Compare commits
47 Commits
Author | SHA1 | Date |
---|---|---|
afornerot | 442718316d | |
afornerot | 4c9b0a1db2 | |
afornerot | 88ffe47f6e | |
afornerot | 0d9caea067 | |
afornerot | 9171ecbf6c | |
afornerot | b155036347 | |
afornerot | 8bc58f6966 | |
afornerot | a2d1841631 | |
afornerot | 0249b6cfae | |
afornerot | 31876489ca | |
afornerot | e2142caa49 | |
afornerot | d9448ccfee | |
afornerot | 0b15ea51bd | |
afornerot | b530a4d8ff | |
afornerot | d2ff60af5c | |
afornerot | e98e1f2698 | |
afornerot | 8f8f53bff3 | |
afornerot | 9dc93daab8 | |
afornerot | 0acb4e1777 | |
afornerot | 0c51a19726 | |
afornerot | 13c9c8bd3d | |
afornerot | 11c6d4635f | |
afornerot | cc200a9862 | |
afornerot | b81226d125 | |
afornerot | 072afb2a1c | |
afornerot | c61312bc3d | |
afornerot | 37968a3728 | |
afornerot | 0989e4762c | |
afornerot | ab2b1e6d3f | |
afornerot | 4f88121362 | |
afornerot | 2df92a3b7f | |
afornerot | 3d949eefce | |
afornerot | 54f9156149 | |
afornerot | 94993f9a10 | |
afornerot | dae554a45d | |
afornerot | 1c572dd516 | |
afornerot | 4c77a4bcd1 | |
afornerot | 88a518ec1c | |
afornerot | 86fcff316f | |
afornerot | 8cfee4699e | |
afornerot | 652d3365a1 | |
afornerot | 8e96aee7ab | |
afornerot | 1666811787 | |
afornerot | 1714bd9a70 | |
afornerot | 70ea9bff97 | |
afornerot | 9205735d1f | |
afornerot | ecb1d43b38 |
5
.env
5
.env
|
@ -1,6 +1,7 @@
|
||||||
# Symfony
|
# Symfony
|
||||||
APP_ENV=PROD
|
APP_ENV=PROD
|
||||||
APP_SECRET=changemeinenvlocal
|
APP_SECRET=changemeinenvlocal
|
||||||
|
APP_PROTOCOL=https
|
||||||
#TRUSTED_PROXIES=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
|
#TRUSTED_PROXIES=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
|
||||||
#TRUSTED_HOSTS='^(localhost|example\.com)$'
|
#TRUSTED_HOSTS='^(localhost|example\.com)$'
|
||||||
|
|
||||||
|
@ -39,9 +40,9 @@ MAILER_NOREPLY=noreply@noreply.fr
|
||||||
|
|
||||||
|
|
||||||
# WEBSOCKET
|
# WEBSOCKET
|
||||||
WSS_USE=0
|
WSS_USE=1
|
||||||
WSS_PORT=5588
|
WSS_PORT=5588
|
||||||
|
WSS_URL=ws://localhost:5588
|
||||||
|
|
||||||
# Proxy
|
# Proxy
|
||||||
PROXY_USE=0
|
PROXY_USE=0
|
||||||
|
|
|
@ -34,3 +34,4 @@ yarn-error.log
|
||||||
/public/uploads/logo/*
|
/public/uploads/logo/*
|
||||||
!/public/uploads/logo/logo.png
|
!/public/uploads/logo/logo.png
|
||||||
/public/uploads/ckeditor
|
/public/uploads/ckeditor
|
||||||
|
/public/uploads/issues
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
update:
|
||||||
|
git pull
|
||||||
|
docker-compose exec ninegitea /app/misc/script/reconfigure.sh
|
|
@ -53,7 +53,11 @@
|
||||||
"preferred-install": {
|
"preferred-install": {
|
||||||
"*": "dist"
|
"*": "dist"
|
||||||
},
|
},
|
||||||
"sort-packages": true
|
"sort-packages": true,
|
||||||
|
"allow-plugins": {
|
||||||
|
"ocramius/package-versions": true,
|
||||||
|
"symfony/flex": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
oneup_uploader:
|
|
||||||
mappings:
|
|
||||||
avatar:
|
|
||||||
frontend: dropzone
|
|
||||||
logo:
|
|
||||||
frontend: dropzone
|
|
||||||
document:
|
|
||||||
frontend: dropzone
|
|
||||||
namer: app.upload.samename
|
|
||||||
storage:
|
|
||||||
directory: "%kernel.project_dir%/uploads/document"
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Read the documentation: https://github.com/1up-lab/OneupUploaderBundle/blob/master/Resources/doc/index.md
|
|
||||||
oneup_uploader:
|
oneup_uploader:
|
||||||
mappings:
|
mappings:
|
||||||
# This is a mapping example, remove it and create your own mappings.
|
avatar:
|
||||||
gallery:
|
frontend: dropzone
|
||||||
frontend: dropzone # or any uploader you use in the frontend
|
logo:
|
||||||
|
frontend: dropzone
|
|
@ -69,7 +69,7 @@ app_sonde:
|
||||||
|
|
||||||
#== Wss ==================================================================================================================
|
#== Wss ==================================================================================================================
|
||||||
app_wss_sample:
|
app_wss_sample:
|
||||||
path: /user/wss/sampble
|
path: /user/wss/sample
|
||||||
defaults: { _controller: App\Controller\WebsocketController:sample }
|
defaults: { _controller: App\Controller\WebsocketController:sample }
|
||||||
|
|
||||||
#== Crop =================================================================================================================
|
#== Crop =================================================================================================================
|
||||||
|
@ -173,6 +173,10 @@ app_report_csv:
|
||||||
path: /user/report/csv/{id}
|
path: /user/report/csv/{id}
|
||||||
defaults: { _controller: App\Controller\ReportController:csv }
|
defaults: { _controller: App\Controller\ReportController:csv }
|
||||||
|
|
||||||
|
app_report_milestone:
|
||||||
|
path: /user/report/milestone/{idscrum}/{mode}/{month}
|
||||||
|
defaults: { _controller: App\Controller\ReportController:milestone }
|
||||||
|
|
||||||
app_report_test:
|
app_report_test:
|
||||||
path: /user/report/test/{id}
|
path: /user/report/test/{id}
|
||||||
defaults: { _controller: App\Controller\ReportController:test }
|
defaults: { _controller: App\Controller\ReportController:test }
|
||||||
|
@ -182,22 +186,10 @@ app_scrum:
|
||||||
path: /user/scrum
|
path: /user/scrum
|
||||||
defaults: { _controller: App\Controller\ScrumController:list }
|
defaults: { _controller: App\Controller\ScrumController:list }
|
||||||
|
|
||||||
app_scrum_view:
|
|
||||||
path: /user/scrum/{id}
|
|
||||||
defaults: { _controller: App\Controller\ScrumController:view }
|
|
||||||
|
|
||||||
app_scrum_submit:
|
app_scrum_submit:
|
||||||
path: /master/scrum/submit
|
path: /master/scrum/submit
|
||||||
defaults: { _controller: App\Controller\ScrumController:submit }
|
defaults: { _controller: App\Controller\ScrumController:submit }
|
||||||
|
|
||||||
app_scrum_stat:
|
|
||||||
path: /user/scrum/stat/{id}
|
|
||||||
defaults: { _controller: App\Controller\ScrumController:stat }
|
|
||||||
|
|
||||||
app_scrum_info:
|
|
||||||
path: /user/scrum/info/{id}
|
|
||||||
defaults: { _controller: App\Controller\ScrumController:info }
|
|
||||||
|
|
||||||
app_scrum_update:
|
app_scrum_update:
|
||||||
path: /master/scrum/update/{id}
|
path: /master/scrum/update/{id}
|
||||||
defaults: { _controller: App\Controller\ScrumController:update }
|
defaults: { _controller: App\Controller\ScrumController:update }
|
||||||
|
@ -206,6 +198,25 @@ app_scrum_delete:
|
||||||
path: /master/scrum/delete/{id}
|
path: /master/scrum/delete/{id}
|
||||||
defaults: { _controller: App\Controller\ScrumController:delete }
|
defaults: { _controller: App\Controller\ScrumController:delete }
|
||||||
|
|
||||||
|
app_scrum_view:
|
||||||
|
path: /user/scrum/{id}
|
||||||
|
defaults: { _controller: App\Controller\ScrumController:view }
|
||||||
|
|
||||||
|
app_scrum_table:
|
||||||
|
path: /user/scrum/table/{id}
|
||||||
|
defaults: { _controller: App\Controller\ScrumController:table }
|
||||||
|
|
||||||
|
app_scrum_stat:
|
||||||
|
path: /user/scrum/stat/{id}
|
||||||
|
defaults: { _controller: App\Controller\ScrumController:stat }
|
||||||
|
|
||||||
|
app_scrum_link:
|
||||||
|
path: /user/scrum/link/{id}
|
||||||
|
defaults: { _controller: App\Controller\ScrumController:link }
|
||||||
|
|
||||||
|
app_scrum_info:
|
||||||
|
path: /user/scrum/info/{id}
|
||||||
|
defaults: { _controller: App\Controller\ScrumController:info }
|
||||||
|
|
||||||
#== Scrumcolumn ========================================================================================================
|
#== Scrumcolumn ========================================================================================================
|
||||||
app_scrumcolumn_submit:
|
app_scrumcolumn_submit:
|
||||||
|
@ -228,7 +239,6 @@ app_scrumcolumn_order:
|
||||||
path: /master/scrumcolumn/order/{scrumid}
|
path: /master/scrumcolumn/order/{scrumid}
|
||||||
defaults: { _controller: App\Controller\ScrumcolumnController:order }
|
defaults: { _controller: App\Controller\ScrumcolumnController:order }
|
||||||
|
|
||||||
|
|
||||||
#== Scrumteam ========================================================================================================
|
#== Scrumteam ========================================================================================================
|
||||||
app_scrumteam_submit:
|
app_scrumteam_submit:
|
||||||
path: /master/scrumteam/submit/{scrumid}
|
path: /master/scrumteam/submit/{scrumid}
|
||||||
|
@ -250,7 +260,6 @@ app_scrumteam_order:
|
||||||
path: /master/scrumteam/order/{scrumid}
|
path: /master/scrumteam/order/{scrumid}
|
||||||
defaults: { _controller: App\Controller\ScrumteamController:order }
|
defaults: { _controller: App\Controller\ScrumteamController:order }
|
||||||
|
|
||||||
|
|
||||||
#== Scrumpriority ========================================================================================================
|
#== Scrumpriority ========================================================================================================
|
||||||
app_scrumpriority_submit:
|
app_scrumpriority_submit:
|
||||||
path: /master/scrumpriority/submit/{scrumid}
|
path: /master/scrumpriority/submit/{scrumid}
|
||||||
|
@ -272,6 +281,26 @@ app_scrumpriority_order:
|
||||||
path: /master/scrumpriority/order/{scrumid}
|
path: /master/scrumpriority/order/{scrumid}
|
||||||
defaults: { _controller: App\Controller\ScrumpriorityController:order }
|
defaults: { _controller: App\Controller\ScrumpriorityController:order }
|
||||||
|
|
||||||
|
#== Scrumsprint ========================================================================================================
|
||||||
|
app_scrumsprint_submit:
|
||||||
|
path: /master/scrumsprint/submit/{scrumid}
|
||||||
|
defaults: { _controller: App\Controller\ScrumsprintController:submit }
|
||||||
|
|
||||||
|
app_scrumsprint_update:
|
||||||
|
path: /master/scrumsprint/update/{id}
|
||||||
|
defaults: { _controller: App\Controller\ScrumsprintController:update }
|
||||||
|
|
||||||
|
app_scrumsprint_delete:
|
||||||
|
path: /master/scrumsprint/delete/{id}
|
||||||
|
defaults: { _controller: App\Controller\ScrumsprintController:delete }
|
||||||
|
|
||||||
|
app_scrumsprint_select:
|
||||||
|
path: /master/scrumsprint/select/{scrumid}
|
||||||
|
defaults: { _controller: App\Controller\ScrumsprintController:select }
|
||||||
|
|
||||||
|
app_scrumsprint_order:
|
||||||
|
path: /master/scrumsprint/order/{scrumid}
|
||||||
|
defaults: { _controller: App\Controller\ScrumsprintController:order }
|
||||||
|
|
||||||
#== Scrumtype ========================================================================================================
|
#== Scrumtype ========================================================================================================
|
||||||
app_scrumtype_submit:
|
app_scrumtype_submit:
|
||||||
|
@ -311,15 +340,35 @@ app_scrumissue_update:
|
||||||
path: /user/scrumissue/update
|
path: /user/scrumissue/update
|
||||||
defaults: { _controller: App\Controller\ScrumissueController:update }
|
defaults: { _controller: App\Controller\ScrumissueController:update }
|
||||||
|
|
||||||
|
app_scrumissue_block:
|
||||||
|
path: /user/scrumissue/block
|
||||||
|
defaults: { _controller: App\Controller\ScrumissueController:block }
|
||||||
|
|
||||||
|
app_scrumissue_unblock:
|
||||||
|
path: /user/scrumissue/unblock
|
||||||
|
defaults: { _controller: App\Controller\ScrumissueController:unblock }
|
||||||
|
|
||||||
|
app_scrumissue_color:
|
||||||
|
path: /user/scrumissue/color
|
||||||
|
defaults: { _controller: App\Controller\ScrumissueController:color }
|
||||||
|
|
||||||
|
app_scrumissue_assigne:
|
||||||
|
path: /user/scrumissue/assigne
|
||||||
|
defaults: { _controller: App\Controller\ScrumissueController:assigne }
|
||||||
|
|
||||||
|
app_scrumissue_notes:
|
||||||
|
path: /user/scrumissue/notes
|
||||||
|
defaults: { _controller: App\Controller\ScrumissueController:notes }
|
||||||
|
|
||||||
app_scrumissue_ctrlchange:
|
app_scrumissue_ctrlchange:
|
||||||
path: /user/scrumissue/ctrlchange
|
path: /user/scrumissue/ctrlchange
|
||||||
defaults: { _controller: App\Controller\ScrumissueController:ctrlchange }
|
defaults: { _controller: App\Controller\ScrumissueController:ctrlchange }
|
||||||
|
|
||||||
#== Issue ========================================================================================================
|
app_scrumissue_view:
|
||||||
app_issue:
|
path: /user/scrumissue/view/{id}
|
||||||
path: /user/issue
|
defaults: { _controller: App\Controller\ScrumissueController:view }
|
||||||
defaults: { _controller: App\Controller\IssueController:list, id: 0 }
|
|
||||||
|
|
||||||
app_issuescrum:
|
#== Poker =============================================================================================================
|
||||||
path: /user/issuescrum/{id}
|
app_poker_get:
|
||||||
defaults: { _controller: App\Controller\IssueController:list }
|
path: /user/poker/{userid}/{issueid}
|
||||||
|
defaults: { _controller: App\Controller\ScrumissueController:getpoker }
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
parameters:
|
parameters:
|
||||||
appEnv: '%env(resolve:APP_ENV)%'
|
appEnv: '%env(resolve:APP_ENV)%'
|
||||||
appSecret: '%env(resolve:APP_SECRET)%'
|
appSecret: '%env(resolve:APP_SECRET)%'
|
||||||
|
appProtocol: '%env(resolve:APP_PROTOCOL)%'
|
||||||
|
|
||||||
appWeburl: '%env(resolve:APP_WEBURL)%'
|
appWeburl: '%env(resolve:APP_WEBURL)%'
|
||||||
appAuth: '%env(resolve:APP_AUTH)%'
|
appAuth: '%env(resolve:APP_AUTH)%'
|
||||||
|
@ -33,7 +34,7 @@ parameters:
|
||||||
|
|
||||||
wssuse: '%env(resolve:WSS_USE)%'
|
wssuse: '%env(resolve:WSS_USE)%'
|
||||||
wssport: '%env(resolve:WSS_PORT)%'
|
wssport: '%env(resolve:WSS_PORT)%'
|
||||||
wssurl: 'wss://%env(resolve:APP_WEBURL)%/wss%env(resolve:APP_ALIAS)%'
|
wssurl: '%env(resolve:WSS_URL)%'
|
||||||
|
|
||||||
proxyUse: '%env(resolve:PROXY_USE)%'
|
proxyUse: '%env(resolve:PROXY_USE)%'
|
||||||
proxyHost: '%env(resolve:PROXY_HOST)%'
|
proxyHost: '%env(resolve:PROXY_HOST)%'
|
||||||
|
@ -104,3 +105,8 @@ services:
|
||||||
public: true
|
public: true
|
||||||
class: App\Service\giteaService
|
class: App\Service\giteaService
|
||||||
arguments: ["@session","%giteaUrl%"]
|
arguments: ["@session","%giteaUrl%"]
|
||||||
|
|
||||||
|
App\Websocket\MessageHandler:
|
||||||
|
public: true
|
||||||
|
arguments:
|
||||||
|
- "@service_container"
|
|
@ -22,8 +22,24 @@ services:
|
||||||
container_name: ninegitea-app
|
container_name: ninegitea-app
|
||||||
image: reg.cadoles.com/envole/ninegitea
|
image: reg.cadoles.com/envole/ninegitea
|
||||||
ports:
|
ports:
|
||||||
- "8000:80"
|
- "8005:80"
|
||||||
|
- "5588:5588"
|
||||||
|
volumes:
|
||||||
|
- ./src:/app/src:delegated
|
||||||
|
- ./templates:/app/templates:delegated
|
||||||
|
- ./config:/app/config:delegated
|
||||||
|
- ./.env:/app/.env:delegated
|
||||||
|
- ./public/uploads:/app/public/uploads:delegated
|
||||||
|
- ./misc:/app/misc:delegated
|
||||||
|
|
||||||
|
adminer:
|
||||||
|
image: adminer
|
||||||
|
container_name: ninegitea-adminer
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 6081:8080
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
mariadb-data:
|
mariadb-data:
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,4 +12,6 @@ composer install --no-interaction
|
||||||
|
|
||||||
bin/console d:s:u --force --complete
|
bin/console d:s:u --force --complete
|
||||||
|
|
||||||
|
bin/console app:Websocket &
|
||||||
|
|
||||||
exec $@
|
exec $@
|
|
@ -11,7 +11,10 @@ class HomeController extends AbstractController
|
||||||
{
|
{
|
||||||
public function home()
|
public function home()
|
||||||
{
|
{
|
||||||
|
if($this->getUser())
|
||||||
return $this->redirectToRoute("app_scrum");
|
return $this->redirectToRoute("app_scrum");
|
||||||
|
else
|
||||||
|
return $this->redirectToRoute("app_login");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function admin()
|
public function admin()
|
||||||
|
|
|
@ -1,212 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Controller;
|
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
|
||||||
use Symfony\Component\Filesystem\Filesystem;
|
|
||||||
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
|
||||||
|
|
||||||
use App\Service\giteaService;
|
|
||||||
|
|
||||||
class IssueController extends AbstractController
|
|
||||||
{
|
|
||||||
private $appKernel;
|
|
||||||
private $data = "issue";
|
|
||||||
private $route = "app_issue";
|
|
||||||
private $render = "Issue/";
|
|
||||||
private $entity = "App:Issue";
|
|
||||||
|
|
||||||
public function __construct(KernelInterface $appKernel,giteaService $giteaservice) {
|
|
||||||
$this->appKernel = $appKernel;
|
|
||||||
$this->giteaservice = $giteaservice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function list($id, Request $request)
|
|
||||||
{
|
|
||||||
$em = $this->getDoctrine()->getManager();
|
|
||||||
$fgcsv = $request->get("fgcsv");
|
|
||||||
|
|
||||||
// Récupérer les repos de gitea
|
|
||||||
if($id==0) $scrums=$em->getRepository("App:Scrum")->findBy([],["name"=>"ASC"]);
|
|
||||||
else $scrums=$em->getRepository("App:Scrum")->findBy(["id"=>$id],["name"=>"ASC"]);
|
|
||||||
|
|
||||||
$giteacategorys=[];
|
|
||||||
$gitearepos=[];
|
|
||||||
$giteamilestones=[];
|
|
||||||
$giteacolumns=[];
|
|
||||||
$giteateams=[];
|
|
||||||
$giteaprioritys=[];
|
|
||||||
$giteatypes=[];
|
|
||||||
$gitealabels=[];
|
|
||||||
$giteaassignees=$em->getRepository("App:User")->findBy([],["username"=>"ASC"]);
|
|
||||||
$viewclosed = $request->getSession()->get("viewclosed");
|
|
||||||
|
|
||||||
foreach($scrums as $key => $scrum) {
|
|
||||||
if(!in_array($scrum->getCategory(),$giteacategorys))
|
|
||||||
array_push($giteacategorys,$scrum->getCategory());
|
|
||||||
|
|
||||||
$gitearepo=$this->giteaservice->getRepo($scrum->getGiteajson()["id"]);
|
|
||||||
if(!$gitearepo) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
|
|
||||||
|
|
||||||
if($gitearepo->updated_at!=$scrum->getGiteajson()["updated_at"]||$gitearepo->open_issues_count!=$scrum->getGiteajson()["open_issues_count"]) {
|
|
||||||
$scrum->setGiteajson(json_decode(json_encode($gitearepo), true));
|
|
||||||
$em->persist($scrum);
|
|
||||||
$em->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
if($gitearepo->open_issues_count>0) {
|
|
||||||
$giteatmp=$this->giteaservice->getMilestones($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],"?state=".($viewclosed=="true"?"all":"open"));
|
|
||||||
foreach($giteatmp as $key => $value) {
|
|
||||||
$giteatmp[$key]->title = $scrum->getGiteajson()["full_name"]. " = ".$giteatmp[$key]->title;
|
|
||||||
}
|
|
||||||
array_push($giteatmp,["id"=>$scrum->getGiteajson()["full_name"],"title"=> $scrum->getGiteajson()["full_name"]. " = Aucun Jalon"]);
|
|
||||||
$giteamilestones=array_merge($giteamilestones,$giteatmp);
|
|
||||||
|
|
||||||
$giteaissues=$this->giteaservice->getIssues($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],"?state=".($viewclosed=="true"?"all":"open"));
|
|
||||||
$json=$scrum->getGiteajson();
|
|
||||||
$json["issues"]=$giteaissues;
|
|
||||||
$json["category"]=$scrum->getCategory();
|
|
||||||
foreach($json["issues"] as $key => $giteaissue) {
|
|
||||||
$issue=$em->getRepository("App:Scrumissue")->findOneBy(["giteaid"=>$giteaissue->id]);
|
|
||||||
if($issue) {
|
|
||||||
$json["issues"][$key]->weight=$issue->getWeight();
|
|
||||||
$json["issues"][$key]->issueid=$issue->getId();
|
|
||||||
$json["issues"][$key]->scrumid=$issue->getScrum()->getId();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$json["issues"][$key]->weight=0;
|
|
||||||
$json["issues"][$key]->issueid=0;
|
|
||||||
$json["issues"][$key]->scrumid=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$tmp=[];
|
|
||||||
foreach($scrum->getScrumcolumns() as $column) {
|
|
||||||
array_push($tmp,$column->getGiteaid());
|
|
||||||
if(!in_array($column->getGiteajson()["name"],$giteacolumns))
|
|
||||||
array_push($giteacolumns,$column->getGiteajson()["name"]);
|
|
||||||
}
|
|
||||||
$json["columns"]=$tmp;
|
|
||||||
array_push($gitearepos,$json);
|
|
||||||
|
|
||||||
foreach($scrum->getScrumteams() as $team) {
|
|
||||||
if(!in_array($team->getGiteajson()["name"],$giteateams))
|
|
||||||
array_push($giteateams,$team->getGiteajson()["name"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($scrum->getScrumprioritys() as $priority) {
|
|
||||||
if(!in_array($priority->getGiteajson()["name"],$giteaprioritys))
|
|
||||||
array_push($giteaprioritys,$priority->getGiteajson()["name"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($scrum->getScrumtypes() as $type) {
|
|
||||||
if(!in_array($type->getGiteajson()["name"],$giteatypes))
|
|
||||||
array_push($giteatypes,$type->getGiteajson()["name"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($giteaissues as $giteaissue) {
|
|
||||||
foreach($giteaissue->labels as $label) {
|
|
||||||
if(!in_array($label->name,$gitealabels))
|
|
||||||
array_push($gitealabels,$label->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$keysort = array_column($giteamilestones, 'title');
|
|
||||||
array_multisort($keysort, SORT_DESC, $giteamilestones);
|
|
||||||
sort($giteacolumns);
|
|
||||||
sort($giteateams);
|
|
||||||
sort($giteaprioritys);
|
|
||||||
sort($giteatypes);
|
|
||||||
sort($gitealabels);
|
|
||||||
sort($giteacategorys);
|
|
||||||
|
|
||||||
// Préférences utilisateur
|
|
||||||
$filtercategorys = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtercategorys",$id);
|
|
||||||
$filterrepos = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterrepos",$id);
|
|
||||||
$filtermilestones = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtermilestones",$id);
|
|
||||||
$filtercolumns = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtercolumns",$id);
|
|
||||||
$filterteams = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterteams",$id);
|
|
||||||
$filterprioritys = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterprioritys",$id);
|
|
||||||
$filtertypes = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtertypes",$id);
|
|
||||||
$filterlabels = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterlabels",$id);
|
|
||||||
$filterassignees = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterassignees",$id);
|
|
||||||
$filterexcludes = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterexcludes",$id);
|
|
||||||
$showfilters = $em->getRepository("App:User")->getUserpreference($this->getUser(),"showfilters",$id);
|
|
||||||
|
|
||||||
if($fgcsv) {
|
|
||||||
$dir = $this->appKernel->getProjectDir() . '/uploads/issues/';
|
|
||||||
$file = "issues-".$id.".csv";
|
|
||||||
$fs = new Filesystem();
|
|
||||||
$fs->mkdir($dir);
|
|
||||||
$csvh = fopen($dir.$file, 'w');
|
|
||||||
$d = ';'; // this is the default but i like to be explicit
|
|
||||||
$e = '"'; // this is the default but i like to be explicit
|
|
||||||
|
|
||||||
$tmp=["Projet","Jalon","Type","Id","Titre","Statut","Label"];
|
|
||||||
fputcsv($csvh, $tmp, $d, $e);
|
|
||||||
|
|
||||||
foreach($gitearepos as $gitearepo) {
|
|
||||||
foreach($gitearepo["issues"] as $giteaissue) {
|
|
||||||
$statut="";
|
|
||||||
$type="";
|
|
||||||
$labels="";
|
|
||||||
foreach($giteaissue->labels as $label) {
|
|
||||||
if(in_array($label->id,$gitearepo["columns"]))
|
|
||||||
$statut=$label->name;
|
|
||||||
elseif(in_array($label->name,$giteatypes))
|
|
||||||
$type=$label->name;
|
|
||||||
else
|
|
||||||
$labels=$labels.($labels!=""?"\n":"").$label->name;
|
|
||||||
}
|
|
||||||
$tmp=[
|
|
||||||
$gitearepo["name"],
|
|
||||||
(isset($giteaissue->milestone->title)?$giteaissue->milestone->title:""),
|
|
||||||
$type,
|
|
||||||
$giteaissue->number,
|
|
||||||
$giteaissue->title,
|
|
||||||
$statut,
|
|
||||||
$labels
|
|
||||||
];
|
|
||||||
fputcsv($csvh, $tmp, $d, $e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose($csvh);
|
|
||||||
|
|
||||||
$response = new BinaryFileResponse($dir.$file);
|
|
||||||
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->render($this->render.'list.html.twig',[
|
|
||||||
"useheader" => true,
|
|
||||||
"usesidebar" => false,
|
|
||||||
"id" => $id,
|
|
||||||
"giteacategorys" => $giteacategorys,
|
|
||||||
"gitearepos" => $gitearepos,
|
|
||||||
"giteamilestones" => $giteamilestones,
|
|
||||||
"giteacolumns" => $giteacolumns,
|
|
||||||
"giteateams" => $giteateams,
|
|
||||||
"giteaprioritys" => $giteaprioritys,
|
|
||||||
"giteatypes" => $giteatypes,
|
|
||||||
"gitealabels" => $gitealabels,
|
|
||||||
"giteaassignees" => $giteaassignees,
|
|
||||||
"filtercategorys" => $filtercategorys,
|
|
||||||
"filterrepos" => $filterrepos,
|
|
||||||
"filtermilestones" => $filtermilestones,
|
|
||||||
"filtercolumns" => $filtercolumns,
|
|
||||||
"filterteams" => $filterteams,
|
|
||||||
"filterprioritys" => $filterprioritys,
|
|
||||||
"filtertypes" => $filtertypes,
|
|
||||||
"filterlabels" => $filterlabels,
|
|
||||||
"filterexcludes" => $filterexcludes,
|
|
||||||
"filterassignees" => $filterassignees,
|
|
||||||
"showfilters" => $showfilters,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -13,6 +13,9 @@ use App\Service\giteaService;
|
||||||
|
|
||||||
class ReportController extends AbstractController
|
class ReportController extends AbstractController
|
||||||
{
|
{
|
||||||
|
private KernelInterface $appKernel;
|
||||||
|
private giteaService $giteaservice;
|
||||||
|
|
||||||
public function __construct(KernelInterface $appKernel, giteaService $giteaservice) {
|
public function __construct(KernelInterface $appKernel, giteaService $giteaservice) {
|
||||||
$this->appKernel = $appKernel;
|
$this->appKernel = $appKernel;
|
||||||
$this->giteaservice = $giteaservice;
|
$this->giteaservice = $giteaservice;
|
||||||
|
@ -114,6 +117,80 @@ class ReportController extends AbstractController
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function milestone($idscrum,$mode,$month,Request $request) {
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$scrum = $em->getRepository("App:Scrum")->find($idscrum);
|
||||||
|
$datestart=new \DateTime($month."01");
|
||||||
|
$dateend=new \DateTime($month."31");
|
||||||
|
|
||||||
|
$repoid = $scrum->getGiteaid();
|
||||||
|
$repoowner = $scrum->getGiteajson()["owner"]["login"];
|
||||||
|
$reponame = $scrum->getGiteajson()["name"];
|
||||||
|
|
||||||
|
//$scrumissues = $em->getRepository("App:Scrumissue")->findBy(["scrum"=>$scrum,"giteastate"=>"open"],["giteamilestonename"=>"ASC","rowid"=>"DESC"]);
|
||||||
|
$scrumissues = $em->getRepository("App:Scrumissue")->findBy(["scrum"=>$scrum],["giteamilestonename"=>"ASC","rowid"=>"DESC"]);
|
||||||
|
|
||||||
|
$reportissues=[];
|
||||||
|
foreach($scrumissues as $scrumissue) {
|
||||||
|
$labels=array_column($scrumissue->getGiteajson()["labels"], 'name');
|
||||||
|
$update=new \DateTime($scrumissue->getGiteajson()["updated_at"]);
|
||||||
|
$close=new \DateTime($scrumissue->getGiteajson()["closed_at"]);
|
||||||
|
//"created_at" => "2024-05-03T15:09:26+02:00"
|
||||||
|
//"updated_at" => "2024-05-03T16:02:00+02:00"
|
||||||
|
//"closed_at" => "2024-05-03T16:01:59+02:00"
|
||||||
|
|
||||||
|
//if(in_array("Type/Scénario",$labels)&&in_array("Statut/Backlog",$labels)) {
|
||||||
|
//if(in_array("Type/Scénario",$labels)) {
|
||||||
|
|
||||||
|
// Dans le cas d'un report Propal on ne prend que les tickets ouvert de type scénario du backlog
|
||||||
|
$ok=false;
|
||||||
|
|
||||||
|
if($mode=="Propal") {
|
||||||
|
if(in_array("Type/Scénario",$labels)&&in_array("Statut/Backlog",$labels)&&$scrumissue->getGiteastate()=="open") {
|
||||||
|
$ok=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dans le cas d'un report PV on prend tout les tickets avec une date de modification ou de cloture dans le mois
|
||||||
|
if($mode=="PV") {
|
||||||
|
$isstatut=false;
|
||||||
|
$isupdate=false;
|
||||||
|
$isclose=false;
|
||||||
|
|
||||||
|
if(in_array("Statut/Livré PREPROD",$labels) || in_array("Statut/A Livrer PROD",$labels) || in_array("Statut/Livré PROD",$labels)) {
|
||||||
|
$isstatut=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!empty($close)&&$close>=$datestart&&$close<=$dateend) $isclose=true;
|
||||||
|
if($update>=$datestart&&$update<=$dateend) $isupdate=true;
|
||||||
|
|
||||||
|
if($isstatut&&($isclose||$isupdate)) $ok=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$ok) continue;
|
||||||
|
|
||||||
|
$tmp= [
|
||||||
|
"id" => $scrumissue->getGiteanumber(),
|
||||||
|
"title" => $scrumissue->getGiteatitle(),
|
||||||
|
"milestone" => ($scrumissue->getGiteamilestonename()??"Aucun"),
|
||||||
|
"statutorder" => $scrumissue->getScrumcolumn()->getRowid(),
|
||||||
|
"statut" => $scrumissue->getScrumcolumn()->getName(),
|
||||||
|
"issueorder" => $scrumissue->getRowid(),
|
||||||
|
];
|
||||||
|
array_push($reportissues,$tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
$statutsort = array_column($reportissues,"statutorder");
|
||||||
|
$issuesort = array_column($reportissues,"statutorder");
|
||||||
|
$milestonesort = array_column($reportissues,"milestone");
|
||||||
|
array_multisort($statutsort, SORT_ASC, $milestonesort, SORT_ASC, $issuesort, SORT_ASC, $reportissues);
|
||||||
|
|
||||||
|
return $this->render('Report/milestone.html.twig', [
|
||||||
|
'useheader' => true,
|
||||||
|
'issues' => $reportissues,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function test($id,Request $request)
|
public function test($id,Request $request)
|
||||||
{
|
{
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
|
@ -4,9 +4,10 @@ namespace App\Controller;
|
||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\Form\FormError;
|
use Symfony\Component\Filesystem\Filesystem;
|
||||||
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
|
||||||
|
|
||||||
use App\Entity\Scrum as Entity;
|
use App\Entity\Scrum as Entity;
|
||||||
use App\Entity\Scrumissue as Scrumissue;
|
use App\Entity\Scrumissue as Scrumissue;
|
||||||
|
@ -20,6 +21,7 @@ class ScrumController extends AbstractController
|
||||||
private $route = "app_scrum";
|
private $route = "app_scrum";
|
||||||
private $render = "Scrum/";
|
private $render = "Scrum/";
|
||||||
private $entity = "App:Scrum";
|
private $entity = "App:Scrum";
|
||||||
|
private $giteaservice;
|
||||||
|
|
||||||
public function __construct(giteaService $giteaservice) { $this->giteaservice = $giteaservice; }
|
public function __construct(giteaService $giteaservice) { $this->giteaservice = $giteaservice; }
|
||||||
|
|
||||||
|
@ -28,6 +30,8 @@ class ScrumController extends AbstractController
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
$scrums = $em->getRepository($this->entity)->findByUser($this->getUser());
|
$scrums = $em->getRepository($this->entity)->findByUser($this->getUser());
|
||||||
|
|
||||||
|
$this->giteaservice->needrefresh();
|
||||||
|
|
||||||
$giteacategorys=[];
|
$giteacategorys=[];
|
||||||
$gitearepos=[];
|
$gitearepos=[];
|
||||||
|
|
||||||
|
@ -175,14 +179,223 @@ class ScrumController extends AbstractController
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
$data=$em->getRepository($this->entity)->find($id);
|
$data=$em->getRepository($this->entity)->find($id);
|
||||||
if(!$data) return $this->redirectToRoute($this->route);
|
if(!$data) return $this->redirectToRoute($this->route);
|
||||||
|
$firstcolumn=$em->getRepository('App:Scrumcolumn')->findOneBy(["scrum"=>$data], ['rowid' => 'ASC']);
|
||||||
|
if(!$firstcolumn) return $this->redirectToRoute($this->route);
|
||||||
|
|
||||||
$forcereload=false;
|
$forcereload=false;
|
||||||
if($request->get("forcereload")) $forcereload=$request->get("forcereload");
|
if($request->get("forcereload")) $forcereload=$request->get("forcereload");
|
||||||
|
|
||||||
|
// Mise à jour des issues par rapport à gitea
|
||||||
$em->getRepository("App:Scrum")->getGitea($data,$giteaassignees,$giteacolumns,$giteamilestones,$giteateams,$giteaprioritys,$giteatypes,$gitealabels,$forcereload);
|
$em->getRepository("App:Scrum")->getGitea($data,$giteaassignees,$giteacolumns,$giteamilestones,$giteateams,$giteaprioritys,$giteatypes,$gitealabels,$forcereload);
|
||||||
|
|
||||||
|
// default color priority
|
||||||
|
$prioritycolor="#70c24a";
|
||||||
|
if(is_array($giteaprioritys)) {
|
||||||
|
|
||||||
|
$priority=$em->getRepository("App:Scrumpriority")->findOneBy(["scrum"=>$data,"giteaid"=>$giteaprioritys[array_key_last($giteaprioritys)]]);
|
||||||
|
if($priority) {
|
||||||
|
$prioritycolor="#".$priority->getGiteajson()["color"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Création du tableau des issues
|
||||||
|
$issues=$data->getScrumissues();
|
||||||
|
$tbissues=[];
|
||||||
|
$tbcols=[];
|
||||||
|
$tbjals=[];
|
||||||
|
$tbsprs=[];
|
||||||
|
$tbestim=[];
|
||||||
|
|
||||||
|
$viewclosed = $this->get('session')->get("viewclosed");
|
||||||
|
foreach($issues as $issue) {
|
||||||
|
// bypass closed
|
||||||
|
if($viewclosed=="false"&&($issue->getGiteastate()=="closed"||($issue->getScrumsprint()&&$issue->getScrumsprint()->getClosed()))) continue;
|
||||||
|
|
||||||
|
// Ids
|
||||||
|
$idcol=($issue->getScrumcolumn()?$issue->getScrumcolumn()->getId():$firstcolumn->getId());
|
||||||
|
$idjal=($issue->getGiteamilestone()?$issue->getGiteamilestone():-100);
|
||||||
|
$idspr=($issue->getScrumsprint()?$issue->getScrumsprint()->getId():-100);
|
||||||
|
|
||||||
|
// Roworders
|
||||||
|
$rowcol=($issue->getScrumcolumn()?$issue->getScrumcolumn()->getRowid():$firstcolumn->getRowid());
|
||||||
|
$rowjal=($issue->getGiteaMilestonename()?$issue->getGiteaMilestonename():-100);
|
||||||
|
$rowspr=($issue->getScrumsprint()?$issue->getScrumsprint()->getRowid():-100);
|
||||||
|
|
||||||
|
// Names
|
||||||
|
$nmcol=($issue->getScrumcolumn()?$issue->getScrumcolumn()->getName():$firstcolumn->getName());
|
||||||
|
$nmjal=($issue->getGiteaMilestonename()?$issue->getGiteaMilestonename():"Aucun");
|
||||||
|
$nmspr=($issue->getScrumsprint()?$issue->getScrumsprint()->getName():"Aucun");
|
||||||
|
|
||||||
|
// Idgiteas
|
||||||
|
$gicol=($issue->getScrumcolumn()?$issue->getScrumcolumn()->getGiteaid():$firstcolumn->getGiteaid());
|
||||||
|
$gijal=($issue->getGiteaMilestone()?$issue->getGiteaMilestone():-100);
|
||||||
|
|
||||||
|
// Liste des colonnes/jalons/sprint avec des issues
|
||||||
|
if(!in_array($idcol,$tbcols)) array_push($tbcols,$idcol);
|
||||||
|
if(!in_array($idcol."|".$idjal,$tbjals)) array_push($tbjals,$idcol."|".$idjal);
|
||||||
|
if(!in_array($idcol."|".$idjal."|".$idspr,$tbsprs)) array_push($tbsprs,$idcol."|".$idjal."|".$idspr);
|
||||||
|
|
||||||
|
// Initialisation du tableau des estimations
|
||||||
|
if(!array_key_exists($idjal,$tbestim)) {
|
||||||
|
$tbestim[$idjal] = [
|
||||||
|
"rowjal" => $rowjal,
|
||||||
|
"idjal" => $idjal,
|
||||||
|
"nmjal" => $nmjal,
|
||||||
|
"gijal" => $gijal,
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"sprints" => []
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!array_key_exists($idspr,$tbestim[$idjal]["sprints"])) {
|
||||||
|
$tbestim[$idjal]["sprints"][$idspr] = [
|
||||||
|
"rowspr" => $rowspr,
|
||||||
|
"idspr" => $idspr,
|
||||||
|
"nmspr" => $nmspr,
|
||||||
|
"nbjrs" => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialisation du tableau des colonnes
|
||||||
|
if(!array_key_exists($idcol,$tbissues)) {
|
||||||
|
$tbissues[$idcol]=[
|
||||||
|
"rowcol" => $rowcol,
|
||||||
|
"idcol" => $idcol,
|
||||||
|
"nmcol" => $nmcol,
|
||||||
|
"gicol" => $gicol,
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"jalons" => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialisation du tableau des jalons de la colonne encours
|
||||||
|
if(!array_key_exists($idjal,$tbissues[$idcol]["jalons"])) {
|
||||||
|
$tbissues[$idcol]["jalons"][$idjal] = [
|
||||||
|
"rowjal" => $rowjal,
|
||||||
|
"idjal" => $idjal,
|
||||||
|
"nmjal" => $nmjal,
|
||||||
|
"gijal" => $gijal,
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"sprints" => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialisation du tableau des sprint de la colonne/jalon encours
|
||||||
|
if(!array_key_exists($idspr,$tbissues[$idcol]["jalons"][$idjal]["sprints"])) {
|
||||||
|
$tbissues[$idcol]["jalons"][$idjal]["sprints"][$idspr] = [
|
||||||
|
"rowspr" => $rowspr,
|
||||||
|
"idspr" => $idspr,
|
||||||
|
"nmspr" => $nmspr,
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"issues" => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// On cumule les estimations
|
||||||
|
$tbissues[$idcol]["nbjrs"]+=$issue->getWeight();
|
||||||
|
$tbissues[$idcol]["jalons"][$idjal]["nbjrs"]+=$issue->getWeight();
|
||||||
|
$tbissues[$idcol]["jalons"][$idjal]["sprints"][$idspr]["nbjrs"]+=$issue->getWeight();
|
||||||
|
$tbestim[$idjal]["nbjrs"]+=$issue->getWeight();
|
||||||
|
$tbestim[$idjal]["sprints"][$idspr]["nbjrs"]+=$issue->getWeight();
|
||||||
|
|
||||||
|
// On sauvegarde l'issue
|
||||||
|
array_push($tbissues[$idcol]["jalons"][$idjal]["sprints"][$idspr]["issues"],$issue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// On ajoute les colonnes sans issues
|
||||||
|
$columns=$data->getScrumcolumns();
|
||||||
|
foreach($columns as $column) {
|
||||||
|
if(!in_array($column->getId(),$tbcols)) {
|
||||||
|
$tbissues[$column->getId()] = [
|
||||||
|
"rowcol" => $column->getRowid(),
|
||||||
|
"idcol" => $column->getId(),
|
||||||
|
"nmcol" => $column->getName(),
|
||||||
|
"gicol" => $column->getGiteaid(),
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"jalons" => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// On ajoute les jalons sans issues
|
||||||
|
foreach($giteamilestones as $milestone) {
|
||||||
|
if(!in_array($column->getId()."|".$milestone->id,$tbjals)) {
|
||||||
|
$tbissues[$column->getId()]["jalons"][$milestone->id] = [
|
||||||
|
"rowjal" => $milestone->title,
|
||||||
|
"idjal" => $milestone->id,
|
||||||
|
"nmjal" => $milestone->title,
|
||||||
|
"gijal" => $milestone->id,
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"sprints" => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// On ajoute le jalon aucun si sans issue
|
||||||
|
if(!in_array($column->getId()."|-100",$tbjals)) {
|
||||||
|
$tbissues[$column->getId()]["jalons"][-100] = [
|
||||||
|
"rowjal" => -100,
|
||||||
|
"idjal" => -100,
|
||||||
|
"nmjal" => "Aucun",
|
||||||
|
"gijal" => null,
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"sprints" => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// On ajoutes les sprints sans issues
|
||||||
|
foreach($tbissues[$column->getId()]["jalons"] as $jalon) {
|
||||||
|
|
||||||
|
$sprints=$em->getRepository("App:Scrumsprint")->findBy(["scrum"=>$data,"giteamilestone"=>$jalon["idjal"]]);
|
||||||
|
foreach($sprints as $sprint) {
|
||||||
|
if($viewclosed=="false"&&$sprint->getClosed()) continue;
|
||||||
|
|
||||||
|
if(!in_array($column->getId()."|".$jalon["idjal"]."|".$sprint->getId(),$tbsprs)) {
|
||||||
|
$tbissues[$column->getId()]["jalons"][$jalon["idjal"]]["sprints"][$sprint->getId()] = [
|
||||||
|
"rowspr" => $sprint->getRowid(),
|
||||||
|
"idspr" => $sprint->getId(),
|
||||||
|
"nmspr" => $sprint->getName(),
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"issues" => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// On ajoute les sprint aucun sans issue
|
||||||
|
if(!in_array($column->getId()."|".$jalon["idjal"]."|-100",$tbsprs)) {
|
||||||
|
$tbissues[$column->getId()]["jalons"][$jalon["idjal"]]["sprints"][-100] = [
|
||||||
|
"rowspr" => -100,
|
||||||
|
"idspr" => -100,
|
||||||
|
"nmspr" => "Aucun",
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"issues" => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tri des issues par colonne/jalon/sprint/issue
|
||||||
|
$rowcol = array_column($tbissues, 'rowcol');
|
||||||
|
array_multisort($rowcol, SORT_ASC, $tbissues);
|
||||||
|
foreach($tbissues as $keycol=>$column) {
|
||||||
|
$rowjal = array_column($tbissues[$keycol]["jalons"], 'rowjal');
|
||||||
|
array_multisort($rowjal, SORT_DESC, $tbissues[$keycol]["jalons"]);
|
||||||
|
foreach($tbissues[$keycol]["jalons"] as $keyjal=>$jalon) {
|
||||||
|
$rowspr = array_column($tbissues[$keycol]["jalons"][$keyjal]["sprints"], 'rowspr');
|
||||||
|
array_multisort($rowspr, SORT_DESC, $tbissues[$keycol]["jalons"][$keyjal]["sprints"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$rowjal = array_column($tbestim, 'rowjal');
|
||||||
|
array_multisort($rowjal, SORT_DESC, $tbestim);
|
||||||
|
foreach($tbestim as $keyjal=>$jalon) {
|
||||||
|
$rowspr = array_column($tbestim[$keyjal]["sprints"], 'rowspr');
|
||||||
|
array_multisort($rowspr, SORT_DESC, $tbestim[$keyjal]["sprints"]);
|
||||||
|
}
|
||||||
|
|
||||||
// Préférences utilisateur
|
// Préférences utilisateur
|
||||||
|
$viewcondensed = $em->getRepository("App:User")->getUserpreference($this->getUser(),"viewcondensed",$id);
|
||||||
$filtermilestones = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtermilestones",$id);
|
$filtermilestones = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtermilestones",$id);
|
||||||
|
$filtersprints = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtersprints",$id);
|
||||||
$filterteams = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterteams",$id);
|
$filterteams = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterteams",$id);
|
||||||
$filterprioritys = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterprioritys",$id);
|
$filterprioritys = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterprioritys",$id);
|
||||||
$filtertypes = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtertypes",$id);
|
$filtertypes = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtertypes",$id);
|
||||||
|
@ -191,6 +404,11 @@ class ScrumController extends AbstractController
|
||||||
$filterexcludes = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterexcludes",$id);
|
$filterexcludes = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterexcludes",$id);
|
||||||
$showfilters = $em->getRepository("App:User")->getUserpreference($this->getUser(),"showfilters",$id);
|
$showfilters = $em->getRepository("App:User")->getUserpreference($this->getUser(),"showfilters",$id);
|
||||||
|
|
||||||
|
// Me demandez pas pourquoi mais j'ai un décallage de 30mn
|
||||||
|
$updatedate=$data->getUpdatedate();
|
||||||
|
$updatedate->setTimezone(new \DateTimeZone("UTC"));
|
||||||
|
$updatedate->add(new \DateInterval("PT30M"));
|
||||||
|
|
||||||
return $this->render($this->render.'view.html.twig', [
|
return $this->render($this->render.'view.html.twig', [
|
||||||
'useheader' => true,
|
'useheader' => true,
|
||||||
'usesidebar' => false,
|
'usesidebar' => false,
|
||||||
|
@ -198,11 +416,15 @@ class ScrumController extends AbstractController
|
||||||
'giteaassignees' => $giteaassignees,
|
'giteaassignees' => $giteaassignees,
|
||||||
'giteacolumns' => $giteacolumns,
|
'giteacolumns' => $giteacolumns,
|
||||||
'giteamilestones' => $giteamilestones,
|
'giteamilestones' => $giteamilestones,
|
||||||
|
'sprints' => $data->getScrumsprintstosee($viewclosed),
|
||||||
'giteateams' => $giteateams,
|
'giteateams' => $giteateams,
|
||||||
'giteaprioritys' => $giteaprioritys,
|
'giteaprioritys' => $giteaprioritys,
|
||||||
|
'prioritycolor' => $prioritycolor,
|
||||||
'giteatypes' => $giteatypes,
|
'giteatypes' => $giteatypes,
|
||||||
'gitealabels' => $gitealabels,
|
'gitealabels' => $gitealabels,
|
||||||
|
'viewcondensed' => $viewcondensed,
|
||||||
'filtermilestones' => $filtermilestones,
|
'filtermilestones' => $filtermilestones,
|
||||||
|
'filtersprints' => $filtersprints,
|
||||||
'filterteams' => $filterteams,
|
'filterteams' => $filterteams,
|
||||||
'filterprioritys' => $filterprioritys,
|
'filterprioritys' => $filterprioritys,
|
||||||
'filtertypes' => $filtertypes,
|
'filtertypes' => $filtertypes,
|
||||||
|
@ -210,141 +432,418 @@ class ScrumController extends AbstractController
|
||||||
'filterassignees' => $filterassignees,
|
'filterassignees' => $filterassignees,
|
||||||
'filterexcludes' => $filterexcludes,
|
'filterexcludes' => $filterexcludes,
|
||||||
'showfilters' => $showfilters,
|
'showfilters' => $showfilters,
|
||||||
|
'tbissues' => $tbissues,
|
||||||
|
'tbestim' => $tbestim,
|
||||||
|
'updatedate' => $updatedate,
|
||||||
$this->data => $data,
|
$this->data => $data,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function table($id, Request $request)
|
||||||
|
{
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$fgcsv = $request->get("fgcsv");
|
||||||
|
$fgpoker = $request->get("fgpoker");
|
||||||
|
|
||||||
|
// Récupérer les repos de gitea
|
||||||
|
$scrum=$em->getRepository("App:Scrum")->findOneBy(["id"=>$id]);
|
||||||
|
|
||||||
|
$gitearepos=[];
|
||||||
|
$giteamilestones=[];
|
||||||
|
$giteacolumns=[];
|
||||||
|
$giteateams=[];
|
||||||
|
$giteaprioritys=[];
|
||||||
|
$giteatypes=[];
|
||||||
|
$gitealabels=[];
|
||||||
|
$giteaassignees=$em->getRepository("App:User")->findBy([],["username"=>"ASC"]);
|
||||||
|
$viewclosed = $request->getSession()->get("viewclosed");
|
||||||
|
|
||||||
|
|
||||||
|
$gitearepo=$this->giteaservice->getRepo($scrum->getGiteajson()["id"]);
|
||||||
|
if($gitearepo->updated_at!=$scrum->getGiteajson()["updated_at"]||$gitearepo->open_issues_count!=$scrum->getGiteajson()["open_issues_count"]) {
|
||||||
|
$scrum->setGiteajson(json_decode(json_encode($gitearepo), true));
|
||||||
|
$em->persist($scrum);
|
||||||
|
$em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
$giteamilestones=$this->giteaservice->getMilestones($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],"?state=".($viewclosed=="true"?"all":"open"));
|
||||||
|
|
||||||
|
$giteaissues=$this->giteaservice->getIssues($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],"?state=".($viewclosed=="true"?"all":"open"));
|
||||||
|
$json=$scrum->getGiteajson();
|
||||||
|
$json["issues"]=$giteaissues;
|
||||||
|
foreach($json["issues"] as $key => $giteaissue) {
|
||||||
|
$issue=$em->getRepository("App:Scrumissue")->findOneBy(["giteaid"=>$giteaissue->id]);
|
||||||
|
if($issue) {
|
||||||
|
$json["issues"][$key]->weight=$issue->getWeight();
|
||||||
|
$json["issues"][$key]->issueid=$issue->getId();
|
||||||
|
$json["issues"][$key]->scrumid=$issue->getScrum()->getId();
|
||||||
|
$json["issues"][$key]->sprintid=($issue->getScrumsprint()?$issue->getScrumsprint()->getId():-100);
|
||||||
|
$json["issues"][$key]->sprintname=($issue->getScrumsprint()?$issue->getScrumsprint()->getName():"Aucun");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$json["issues"][$key]->weight=0;
|
||||||
|
$json["issues"][$key]->issueid=0;
|
||||||
|
$json["issues"][$key]->scrumid=0;
|
||||||
|
$json["issues"][$key]->sprintid=-100;
|
||||||
|
$json["issues"][$key]->sprintname="Aucun";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmp=[];
|
||||||
|
foreach($scrum->getScrumcolumns() as $column) {
|
||||||
|
array_push($tmp,$column->getGiteaid());
|
||||||
|
if(!in_array($column->getGiteajson()["name"],$giteacolumns))
|
||||||
|
array_push($giteacolumns,$column->getGiteajson()["name"]);
|
||||||
|
}
|
||||||
|
$json["columns"]=$tmp;
|
||||||
|
array_push($gitearepos,$json);
|
||||||
|
|
||||||
|
foreach($scrum->getScrumteams() as $team) {
|
||||||
|
if(!in_array($team->getGiteajson()["name"],$giteateams))
|
||||||
|
array_push($giteateams,$team->getGiteajson()["name"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($scrum->getScrumprioritys() as $priority) {
|
||||||
|
if(!in_array($priority->getGiteajson()["name"],$giteaprioritys))
|
||||||
|
array_push($giteaprioritys,$priority->getGiteajson()["name"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($scrum->getScrumtypes() as $type) {
|
||||||
|
if(!in_array($type->getGiteajson()["name"],$giteatypes))
|
||||||
|
array_push($giteatypes,$type->getGiteajson()["name"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($giteaissues as $giteaissue) {
|
||||||
|
foreach($giteaissue->labels as $label) {
|
||||||
|
if(!in_array($label->name,$gitealabels))
|
||||||
|
array_push($gitealabels,$label->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$keysort = array_column($giteamilestones, 'title');
|
||||||
|
array_multisort($keysort, SORT_DESC, $giteamilestones);
|
||||||
|
sort($giteacolumns);
|
||||||
|
sort($giteateams);
|
||||||
|
sort($giteaprioritys);
|
||||||
|
sort($giteatypes);
|
||||||
|
sort($gitealabels);
|
||||||
|
|
||||||
|
// Préférences utilisateur
|
||||||
|
$filtercategorys = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtercategorys",$id);
|
||||||
|
$filterrepos = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterrepos",$id);
|
||||||
|
$filtermilestones = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtermilestones",$id);
|
||||||
|
$filtersprints = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtersprints",$id);
|
||||||
|
$filtercolumns = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtercolumns",$id);
|
||||||
|
$filterteams = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterteams",$id);
|
||||||
|
$filterprioritys = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterprioritys",$id);
|
||||||
|
$filtertypes = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtertypes",$id);
|
||||||
|
$filterlabels = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterlabels",$id);
|
||||||
|
$filterassignees = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterassignees",$id);
|
||||||
|
$filterexcludes = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterexcludes",$id);
|
||||||
|
$showfilters = $em->getRepository("App:User")->getUserpreference($this->getUser(),"showfilters",$id);
|
||||||
|
|
||||||
|
if($fgcsv) {
|
||||||
|
$dir = $this->getParameter('kernel.project_dir') . '/public/uploads/issues/';
|
||||||
|
$file = "issues-".$id.".csv";
|
||||||
|
$fs = new Filesystem();
|
||||||
|
$fs->mkdir($dir);
|
||||||
|
$csvh = fopen($dir.$file, 'w');
|
||||||
|
$d = ';'; // this is the default but i like to be explicit
|
||||||
|
$e = '"'; // this is the default but i like to be explicit
|
||||||
|
|
||||||
|
$tmp=["Projet","Jalon","Sprint","Type","Id","Titre","Statut","Label","Poid"];
|
||||||
|
fputcsv($csvh, $tmp, $d, $e);
|
||||||
|
|
||||||
|
foreach($gitearepos as $gitearepo) {
|
||||||
|
foreach($gitearepo["issues"] as $giteaissue) {
|
||||||
|
$statut="";
|
||||||
|
$issue=$em->getRepository("App:Scrumissue")->findOneBy(["giteaid"=>$giteaissue->id]);
|
||||||
|
|
||||||
|
$type="";
|
||||||
|
$labels="";
|
||||||
|
foreach($giteaissue->labels as $label) {
|
||||||
|
if(in_array($label->id,$gitearepo["columns"]))
|
||||||
|
$statut=$label->name;
|
||||||
|
elseif(in_array($label->name,$giteatypes))
|
||||||
|
$type=$label->name;
|
||||||
|
else
|
||||||
|
$labels=$labels.($labels!=""?"\n":"").$label->name;
|
||||||
|
}
|
||||||
|
$tmp=[
|
||||||
|
$gitearepo["name"],
|
||||||
|
(isset($giteaissue->milestone->title)?$giteaissue->milestone->title:""),
|
||||||
|
($issue->getScrumsprint()?$issue->getScrumsprint()->getName():"Aucun"),
|
||||||
|
$type,
|
||||||
|
$giteaissue->number,
|
||||||
|
$giteaissue->title,
|
||||||
|
$statut,
|
||||||
|
$labels,
|
||||||
|
$issue->getWeight()
|
||||||
|
];
|
||||||
|
fputcsv($csvh, $tmp, $d, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose($csvh);
|
||||||
|
|
||||||
|
$response = new BinaryFileResponse($dir.$file);
|
||||||
|
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT);
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render($this->render.'table.html.twig',[
|
||||||
|
"useheader" => true,
|
||||||
|
"usesidebar" => false,
|
||||||
|
"id" => $id,
|
||||||
|
"gitearepos" => $gitearepos,
|
||||||
|
"giteamilestones" => $giteamilestones,
|
||||||
|
"sprints" => $scrum->getScrumsprints(),
|
||||||
|
"giteacolumns" => $giteacolumns,
|
||||||
|
"giteateams" => $giteateams,
|
||||||
|
"giteaprioritys" => $giteaprioritys,
|
||||||
|
"giteatypes" => $giteatypes,
|
||||||
|
"gitealabels" => $gitealabels,
|
||||||
|
"giteaassignees" => $giteaassignees,
|
||||||
|
"filtercategorys" => $filtercategorys,
|
||||||
|
"filterrepos" => $filterrepos,
|
||||||
|
"filtermilestones" => $filtermilestones,
|
||||||
|
"filtersprints" => $filtersprints,
|
||||||
|
"filtercolumns" => $filtercolumns,
|
||||||
|
"filterteams" => $filterteams,
|
||||||
|
"filterprioritys" => $filterprioritys,
|
||||||
|
"filtertypes" => $filtertypes,
|
||||||
|
"filterlabels" => $filterlabels,
|
||||||
|
"filterexcludes" => $filterexcludes,
|
||||||
|
"filterassignees" => $filterassignees,
|
||||||
|
"showfilters" => $showfilters,
|
||||||
|
"fgpoker" => $fgpoker,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function stat($id,Request $request)
|
public function stat($id,Request $request)
|
||||||
|
{
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$scrum=$em->getRepository($this->entity)->find($id);
|
||||||
|
if(!$scrum) return $this->redirectToRoute($this->route);
|
||||||
|
$em->getRepository("App:Scrum")->getGitea($scrum,$giteaassignees,$giteacolumns,$giteamilestones,$giteateams,$giteaprioritys,$giteatypes,$gitealabels);
|
||||||
|
|
||||||
|
// Préférences utilisateur
|
||||||
|
$filtermilestones = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtermilestones",$id);
|
||||||
|
$filtersprints = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtersprints",$id);
|
||||||
|
$filterbynumber = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterbynumber",$id);
|
||||||
|
$showfilters = $em->getRepository("App:User")->getUserpreference($this->getUser(),"showfilters",$id);
|
||||||
|
|
||||||
|
$tbestim=$this->getEstim($scrum);
|
||||||
|
|
||||||
|
return $this->render($this->render.'stat.html.twig', [
|
||||||
|
'useheader' => true,
|
||||||
|
'usesidebar' => false,
|
||||||
|
'usetitle' => $scrum->getName(),
|
||||||
|
'giteamilestones' => $giteamilestones,
|
||||||
|
'sprints' => $scrum->getScrumsprints(),
|
||||||
|
'filtermilestones' => $filtermilestones,
|
||||||
|
'filtersprints' => $filtersprints,
|
||||||
|
'filterbynumber' => $filterbynumber,
|
||||||
|
'showfilters' => $showfilters,
|
||||||
|
$this->data => $scrum,
|
||||||
|
'tbestim' => $tbestim,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function link($id,Request $request)
|
||||||
{
|
{
|
||||||
// Initialisation de l'enregistrement
|
// Initialisation de l'enregistrement
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
$data=$em->getRepository($this->entity)->find($id);
|
$data=$em->getRepository($this->entity)->find($id);
|
||||||
if(!$data) return $this->redirectToRoute($this->route);
|
if(!$data) return $this->redirectToRoute($this->route);
|
||||||
|
|
||||||
$em->getRepository("App:Scrum")->getGitea($data,$giteaassignees,$giteacolumns,$giteamilestones,$giteateams,$giteaprioritys,$giteatypes,$gitealabels);
|
return $this->render($this->render.'link.html.twig',[
|
||||||
|
"useheader" => true,
|
||||||
// Préférences utilisateur
|
"usesidebar" => false,
|
||||||
$filtermilestones = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtermilestones",$id);
|
"maxwidth" => 1000,
|
||||||
$filterteams = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterteams",$id);
|
"scrum" => $data,
|
||||||
$showfilters = $em->getRepository("App:User")->getUserpreference($this->getUser(),"showfilters",$id);
|
|
||||||
|
|
||||||
$tbstat=[];
|
|
||||||
foreach($data->getScrumIssues() as $issue) {
|
|
||||||
|
|
||||||
$labels=$issue->getGiteajson()["labels"];
|
|
||||||
$haveteams=true;
|
|
||||||
if($filterteams) {
|
|
||||||
$haveteams=false;
|
|
||||||
foreach($filterteams as $filterteam) {
|
|
||||||
foreach($labels as $label) {
|
|
||||||
if($label["id"]==$filterteam) {
|
|
||||||
$haveteams=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if($haveteams) {
|
|
||||||
$idmilestone=($issue->getGiteamilestone()?$issue->getGiteamilestone():-100);
|
|
||||||
$lbmilestone=($issue->getGiteamilestone()?$issue->getGiteamilestonename():"Aucun");
|
|
||||||
if(!array_key_exists($idmilestone,$tbstat)) {
|
|
||||||
$tbstat[$idmilestone]=["id"=>$idmilestone,"name"=>$lbmilestone,"stat"=>[]];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$issue->getScrumcolumn()) $ordercolumns=0;
|
|
||||||
else $ordercolumns=array_search($issue->getScrumcolumn()->getGiteaid(),$giteacolumns);
|
|
||||||
|
|
||||||
//$ordercolumns=$issue->getScrumcolumn()->getId();
|
|
||||||
if(!array_key_exists($ordercolumns,$tbstat[$idmilestone]["stat"])) {
|
|
||||||
$tbstat[$idmilestone]["stat"][$ordercolumns]=[
|
|
||||||
"id"=>$issue->getScrumcolumn()->getId(),
|
|
||||||
"label"=>$issue->getScrumcolumn()->getName(),
|
|
||||||
"total"=>0,
|
|
||||||
"color"=>"#".$issue->getScrumcolumn()->getGiteajson()["color"],
|
|
||||||
"labels"=>[],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($labels as $label) {
|
|
||||||
if($ordercolumns!=$label["id"]) {
|
|
||||||
if(!array_key_exists($label["id"],$tbstat[$idmilestone]["stat"][$ordercolumns]["labels"])) {
|
|
||||||
$tbstat[$idmilestone]["stat"][$ordercolumns]["labels"][$label["id"]] = [
|
|
||||||
"id"=>$label["id"],
|
|
||||||
"label"=>$label["name"],
|
|
||||||
"total"=>0,
|
|
||||||
"color"=>"#".$label["color"],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
$tbstat[$idmilestone]["stat"][$ordercolumns]["labels"][$label["id"]]["total"]+=$issue->getWeight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$tbstat[$idmilestone]["stat"][$ordercolumns]["total"]+=$issue->getWeight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($tbstat as $k1=>$milestone) {
|
|
||||||
$tmp=$tbstat[$k1]["stat"];
|
|
||||||
ksort($tmp);
|
|
||||||
$tbstat[$k1]["stat"]=$tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($tbstat as $k1=>$milestone) {
|
|
||||||
foreach($tbstat[$k1]["stat"] as $k2=>$statut) {
|
|
||||||
$keysort = array_column($tbstat[$k1]["stat"][$k2]["labels"], 'label');
|
|
||||||
array_multisort($keysort, SORT_ASC, $tbstat[$k1]["stat"][$k2]["labels"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return $this->render($this->render.'stat.html.twig', [
|
|
||||||
'useheader' => true,
|
|
||||||
'usesidebar' => false,
|
|
||||||
'usetitle' => $data->getName(),
|
|
||||||
'giteaassignees' => $giteaassignees,
|
|
||||||
'giteacolumns' => $giteacolumns,
|
|
||||||
'giteamilestones' => $giteamilestones,
|
|
||||||
'giteateams' => $giteateams,
|
|
||||||
'giteaprioritys' => $giteaprioritys,
|
|
||||||
'giteatypes' => $giteatypes,
|
|
||||||
'gitealabels' => $gitealabels,
|
|
||||||
'filtermilestones' => $filtermilestones,
|
|
||||||
'filterteams' => $filterteams,
|
|
||||||
'showfilters' => $showfilters,
|
|
||||||
$this->data => $data,
|
|
||||||
'tbstat' => $tbstat,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function info($id,Request $request)
|
public function info($id,Request $request)
|
||||||
{
|
{
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
$viewclosed = $request->getSession()->get("viewclosed");
|
$scrum=$em->getRepository($this->entity)->find($id);
|
||||||
|
if(!$scrum) return $this->redirectToRoute($this->route);
|
||||||
|
//$em->getRepository("App:Scrum")->getGitea($scrum,$giteaassignees,$giteacolumns,$giteamilestones,$giteateams,$giteaprioritys,$giteatypes,$gitealabels);
|
||||||
|
|
||||||
// Rechercher du scrum en cours
|
$tbestim=$this->getEstim($scrum);
|
||||||
$scrum=$em->getRepository("App:Scrum")->find($id);
|
|
||||||
if(!$scrum) return new JsonResponse(['message' => 'No Issue'], 403);
|
|
||||||
|
|
||||||
$giteaissues=$this->giteaservice->getIssues($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],"?state=".($viewclosed=="true"?"all":"open"));
|
|
||||||
|
|
||||||
$weights=[];
|
|
||||||
foreach($giteaissues as $giteaissue) {
|
|
||||||
$scrumissue=$em->getRepository("App:Scrumissue")->findOneBy(["scrum"=>$scrum,"giteaid"=>$giteaissue->id]);
|
|
||||||
if($scrumissue) {
|
|
||||||
if($giteaissue->milestone) $milestoneid=$giteaissue->milestone->id;
|
|
||||||
else $milestoneid=-100;
|
|
||||||
|
|
||||||
if(!array_key_exists($milestoneid,$weights)) $weights[$milestoneid]=0;
|
|
||||||
$weights[$milestoneid]=$weights[$milestoneid]+$scrumissue->getWeight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$output=[];
|
$output=[];
|
||||||
$output["weights"]=$weights;
|
$output["tbestim"]=$tbestim;
|
||||||
|
|
||||||
return new JsonResponse($output);
|
return new JsonResponse($output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getEstim($scrum) {
|
||||||
|
|
||||||
|
|
||||||
|
// Initialisation de l'enregistrement
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$firstcolumn=$em->getRepository('App:Scrumcolumn')->findOneBy(["scrum"=>$scrum], ['rowid' => 'ASC']);
|
||||||
|
if(!$firstcolumn) return $this->redirectToRoute($this->route);
|
||||||
|
|
||||||
|
|
||||||
|
// Création du tableau des issues
|
||||||
|
$issues=$scrum->getScrumissues();
|
||||||
|
$tbissues=[];
|
||||||
|
$tbcols=[];
|
||||||
|
$tbjals=[];
|
||||||
|
$tbsprs=[];
|
||||||
|
$tbestim=[];
|
||||||
|
|
||||||
|
$viewclosed = $this->get('session')->get("viewclosed");
|
||||||
|
if($viewclosed=="false") {
|
||||||
|
$giteamilestones=$this->giteaservice->getMilestones($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],"?state=open");
|
||||||
|
$giteamilestones=array_column($giteamilestones,"id");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($issues as $issue) {
|
||||||
|
// bypass jalon closed
|
||||||
|
if($viewclosed=="false") {
|
||||||
|
|
||||||
|
/*
|
||||||
|
if(array_key_exists("milestone",$issue->getGiteajson()) && !empty($issue->getGiteajson()["milestone"]) && $issue->getGiteajson()["milestone"])
|
||||||
|
dump($issue->getGiteajson()["milestone"]["title"]);
|
||||||
|
*/
|
||||||
|
if(array_key_exists("milestone",$issue->getGiteajson()) && !empty($issue->getGiteajson()["milestone"]) && !in_array($issue->getGiteajson()["milestone"]["id"],$giteamilestones))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//if($viewclosed=="false"&&($issue->getGiteastate()=="closed"||($issue->getScrumsprint()&&$issue->getScrumsprint()->getClosed()))) continue;
|
||||||
|
|
||||||
|
// Ids
|
||||||
|
$idcol=($issue->getScrumcolumn()?$issue->getScrumcolumn()->getId():$firstcolumn->getId());
|
||||||
|
$idjal=($issue->getGiteamilestone()?$issue->getGiteamilestone():-100);
|
||||||
|
$idspr=($issue->getScrumsprint()?$issue->getScrumsprint()->getId():-100);
|
||||||
|
|
||||||
|
// Roworders
|
||||||
|
$rowcol=($issue->getScrumcolumn()?$issue->getScrumcolumn()->getRowid():$firstcolumn->getRowid());
|
||||||
|
$rowjal=($issue->getGiteaMilestonename()?$issue->getGiteaMilestonename():-100);
|
||||||
|
$rowspr=($issue->getScrumsprint()?$issue->getScrumsprint()->getRowid():-100);
|
||||||
|
|
||||||
|
// Names
|
||||||
|
$nmcol=($issue->getScrumcolumn()?$issue->getScrumcolumn()->getName():$firstcolumn->getName());
|
||||||
|
$nmjal=($issue->getGiteaMilestonename()?$issue->getGiteaMilestonename():"Aucun");
|
||||||
|
$nmspr=($issue->getScrumsprint()?$issue->getScrumsprint()->getName():"Aucun");
|
||||||
|
|
||||||
|
// Idgiteas
|
||||||
|
$gicol=($issue->getScrumcolumn()?$issue->getScrumcolumn()->getGiteaid():$firstcolumn->getGiteaid());
|
||||||
|
$gijal=($issue->getGiteaMilestone()?$issue->getGiteaMilestone():-100);
|
||||||
|
|
||||||
|
if(!array_key_exists($idjal,$tbestim)) {
|
||||||
|
$tbestim[$idjal] = [
|
||||||
|
"rowjal" => $rowjal,
|
||||||
|
"idjal" => $idjal,
|
||||||
|
"gijal" => $gijal,
|
||||||
|
"nmjal" => $nmjal,
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"nbiss" => 0,
|
||||||
|
"columns" => [],
|
||||||
|
"sprints" => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!array_key_exists($idspr,$tbestim[$idjal]["sprints"])) {
|
||||||
|
$tbestim[$idjal]["sprints"][$idspr] = [
|
||||||
|
"rowspr" => $rowspr,
|
||||||
|
"idspr" => $idspr,
|
||||||
|
"nmspr" => $nmspr,
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"nbiss" => 0,
|
||||||
|
"columns" => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!array_key_exists("clos",$tbestim[$idjal]["columns"])) {
|
||||||
|
$tbestim[$idjal]["columns"]["clos"] = [
|
||||||
|
"rowcol" => 1000,
|
||||||
|
"idcol" => "clos",
|
||||||
|
"gicol" => "clos",
|
||||||
|
"nmcol" => "Clos",
|
||||||
|
"color" => "000000",
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"nbiss" => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!array_key_exists($idcol,$tbestim[$idjal]["columns"])) {
|
||||||
|
$tbestim[$idjal]["columns"][$idcol] = [
|
||||||
|
"rowcol" => $rowcol,
|
||||||
|
"idcol" => $idcol,
|
||||||
|
"gicol" => $gicol,
|
||||||
|
"nmcol" => $nmcol,
|
||||||
|
"color" => ($issue->getScrumcolumn()?$issue->getScrumcolumn()->getGiteajson()["color"]:$firstcolumn->getGiteajson()["color"]),
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"nbiss" => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!array_key_exists("clos",$tbestim[$idjal]["sprints"][$idspr]["columns"])) {
|
||||||
|
$tbestim[$idjal]["sprints"][$idspr]["columns"]["clos"] = [
|
||||||
|
"rowcol" => 10000,
|
||||||
|
"idcol" => "clos",
|
||||||
|
"gicol" => "clos",
|
||||||
|
"nmcol" => "Clos",
|
||||||
|
"color" => "000000",
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"nbiss" => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!array_key_exists($idcol,$tbestim[$idjal]["sprints"][$idspr]["columns"])) {
|
||||||
|
$tbestim[$idjal]["sprints"][$idspr]["columns"][$idcol] = [
|
||||||
|
"rowcol" => $rowcol,
|
||||||
|
"idcol" => $idcol,
|
||||||
|
"gicol" => $gicol,
|
||||||
|
"nmcol" => $nmcol,
|
||||||
|
"color" => ($issue->getScrumcolumn()?$issue->getScrumcolumn()->getGiteajson()["color"]:$firstcolumn->getGiteajson()["color"]),
|
||||||
|
"nbjrs" => 0,
|
||||||
|
"nbiss" => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// On cumule les estimations
|
||||||
|
if($issue->getGiteastate()=="closed") $idcol="clos";
|
||||||
|
|
||||||
|
$tbestim[$idjal]["nbjrs"]+=$issue->getWeight();
|
||||||
|
$tbestim[$idjal]["columns"][$idcol]["nbjrs"]+=$issue->getWeight();
|
||||||
|
$tbestim[$idjal]["sprints"][$idspr]["nbjrs"]+=$issue->getWeight();
|
||||||
|
$tbestim[$idjal]["sprints"][$idspr]["columns"][$idcol]["nbjrs"]+=$issue->getWeight();
|
||||||
|
|
||||||
|
$tbestim[$idjal]["nbiss"]++;
|
||||||
|
$tbestim[$idjal]["columns"][$idcol]["nbiss"]++;
|
||||||
|
$tbestim[$idjal]["sprints"][$idspr]["nbiss"]++;
|
||||||
|
$tbestim[$idjal]["sprints"][$idspr]["columns"][$idcol]["nbiss"]++;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$this->formatDec($tbestim[$idjal]["nbjrs"]);
|
||||||
|
$this->formatDec($tbestim[$idjal]["columns"][$idcol]["nbjrs"]);
|
||||||
|
$this->formatDec($tbestim[$idjal]["sprints"][$idspr]["nbjrs"]);
|
||||||
|
$this->formatDec($tbestim[$idjal]["sprints"][$idspr]["columns"][$idcol]["nbjrs"]);
|
||||||
|
|
||||||
|
}
|
||||||
|
// dd("stop");
|
||||||
|
|
||||||
|
$keysort = array_column($tbestim, 'nmjal');
|
||||||
|
array_multisort($keysort, SORT_DESC, $tbestim);
|
||||||
|
foreach($tbestim as $keyj => $jalon) {
|
||||||
|
$keysort = array_column($jalon["sprints"],"nmspr");
|
||||||
|
array_multisort($keysort, SORT_DESC, $tbestim[$keyj]["sprints"]);
|
||||||
|
}
|
||||||
|
return $tbestim;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatDec(&$number) {
|
||||||
|
if(strpos(strval($number), '.') !== false) $number=number_format($number,1);
|
||||||
|
else $number=intval($number);
|
||||||
|
}
|
||||||
|
|
||||||
protected function getErrorForm($id,$form,$request,$data,$mode) {
|
protected function getErrorForm($id,$form,$request,$data,$mode) {
|
||||||
if ($form->get('submit')->isClicked()&&$mode=="delete") {
|
if ($form->get('submit')->isClicked()&&$mode=="delete") {
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ class ScrumcolumnController extends AbstractController
|
||||||
|
|
||||||
// Récupérer les repos de gitea
|
// Récupérer les repos de gitea
|
||||||
$gitealabels=$this->giteaservice->getLabels($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
$gitealabels=$this->giteaservice->getLabels($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
||||||
if(!is_array($gitealabels)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
|
if(!is_array($gitealabels)) die("Probleme de connexion avec gitea veuillez vous <a href='/logout'>reconnecter</a>");
|
||||||
|
|
||||||
// Création du formulaire
|
// Création du formulaire
|
||||||
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","gitealabels"=>$gitealabels));
|
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","gitealabels"=>$gitealabels));
|
||||||
|
|
|
@ -12,6 +12,7 @@ use App\Entity\Scrumissue as Entity;
|
||||||
use App\Form\ScrumissueType as Form;
|
use App\Form\ScrumissueType as Form;
|
||||||
|
|
||||||
use App\Service\giteaService;
|
use App\Service\giteaService;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
class ScrumissueController extends AbstractController
|
class ScrumissueController extends AbstractController
|
||||||
{
|
{
|
||||||
|
@ -31,8 +32,10 @@ class ScrumissueController extends AbstractController
|
||||||
$newcolumn=$request->get('newcolumn');
|
$newcolumn=$request->get('newcolumn');
|
||||||
$oldmilestone=$request->get('oldmilestone');
|
$oldmilestone=$request->get('oldmilestone');
|
||||||
$newmilestone=$request->get('newmilestone');
|
$newmilestone=$request->get('newmilestone');
|
||||||
|
$oldsprint=$request->get('oldsprint');
|
||||||
|
$newsprint=$request->get('newsprint');
|
||||||
|
|
||||||
if($oldcolumn!=$newcolumn||$oldmilestone!=$newmilestone) {
|
if($oldcolumn!=$newcolumn||$oldmilestone!=$newmilestone||$oldsprint!=$newsprint) {
|
||||||
// Rechercher l'issue en cours
|
// Rechercher l'issue en cours
|
||||||
$scrumissue=$em->getRepository("App:Scrumissue")->find($id);
|
$scrumissue=$em->getRepository("App:Scrumissue")->find($id);
|
||||||
if(!$scrumissue) return new JsonResponse(['message' => 'No Issue'], 403);
|
if(!$scrumissue) return new JsonResponse(['message' => 'No Issue'], 403);
|
||||||
|
@ -69,15 +72,31 @@ class ScrumissueController extends AbstractController
|
||||||
if(!$return) return new JsonResponse(['message' => 'No API patchIssue'], 403);
|
if(!$return) return new JsonResponse(['message' => 'No API patchIssue'], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mettre à jour le sprint
|
||||||
|
if($oldsprint!=$newsprint) {
|
||||||
|
$scrumissue->setScrumsprint(null);
|
||||||
|
$sprint=$em->getRepository("App:Scrumsprint")->find($newsprint);
|
||||||
|
if($sprint) {
|
||||||
|
$scrumissue->setScrumsprint($sprint);
|
||||||
|
}
|
||||||
|
$em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
// Récupérer l'issue modifiée pour mettre à jour la date de modification gitea
|
// Récupérer l'issue modifiée pour mettre à jour la date de modification gitea
|
||||||
$giteaissue=$this->giteaservice->getIssue($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber());
|
$giteaissue=$this->giteaservice->getIssue($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber());
|
||||||
if(!$giteaissue) return new JsonResponse(['message' => 'No API getIssue'], 403);
|
if(!$giteaissue) return new JsonResponse(['message' => 'No API getIssue'], 403);
|
||||||
$updatedate=new \DateTime($giteaissue->updated_at);
|
$updateissue=new \DateTime(json_decode(json_encode($giteaissue), true)["updated_at"]);
|
||||||
if($updatedate > $scrumissue->getScrum()->getUpdatedate()) {
|
$updateissue->setTimezone(new \DateTimeZone("UTC"));
|
||||||
$scrumissue->getScrum()->setUpdatedate(new \DateTime($giteaissue->updated_at));
|
$em->getRepository("App:Scrum")->majissue($scrumissue,$giteaissue,false);
|
||||||
|
|
||||||
|
$lastupdate=$scrumissue->getScrum()->getUpdatedate();
|
||||||
|
|
||||||
|
|
||||||
|
if($updateissue > $lastupdate) {
|
||||||
|
$scrumissue->getScrum()->setUpdatedate($updateissue);
|
||||||
$em->persist($scrumissue->getScrum());
|
$em->persist($scrumissue->getScrum());
|
||||||
$em->flush();
|
$em->flush();
|
||||||
return new JsonResponse($updatedate->format("Ymd H:i:s"));
|
return new JsonResponse($updateissue->format("Ymd H:i:s"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new JsonResponse(false);
|
return new JsonResponse(false);
|
||||||
|
@ -120,10 +139,77 @@ class ScrumissueController extends AbstractController
|
||||||
|
|
||||||
$output=[];
|
$output=[];
|
||||||
$output["weight"]=$scrumissue->getWeight();
|
$output["weight"]=$scrumissue->getWeight();
|
||||||
|
$output["giteajson"]=$scrumissue->getGiteajson();
|
||||||
|
$output["notes"]=$scrumissue->getNotes();
|
||||||
|
|
||||||
return new JsonResponse($output);
|
return new JsonResponse($output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function view($id, Request $request) {
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$issue=$em->getRepository("App:Scrumissue")->find($id);
|
||||||
|
$scrum = $issue->getScrum();
|
||||||
|
|
||||||
|
$repoid = $scrum->getGiteaid();
|
||||||
|
$repoowner = $scrum->getGiteajson()["owner"]["login"];
|
||||||
|
$reponame = $scrum->getGiteajson()["name"];
|
||||||
|
|
||||||
|
$repo=$this->giteaservice->getRepo($repoid);
|
||||||
|
$giteaissue=$this->giteaservice->getIssue($repoowner,$reponame,$issue->getGiteanumber());
|
||||||
|
$giteaissue->body = $this->giteaservice->markdown("/".$scrum->getGiteajson()["full_name"],"comment",$giteaissue->body);
|
||||||
|
$giteaissue->comments=$this->giteaservice->getIssueComments($repoowner,$reponame,$giteaissue->number);
|
||||||
|
|
||||||
|
|
||||||
|
$giteaissue->statuslife=$issue->getScrumcolumn()->getName();
|
||||||
|
$giteaissue->weight=$issue->getWeight();
|
||||||
|
$giteaissue->nineid=$issue->getId();
|
||||||
|
|
||||||
|
$giteaissue->sprint=($issue->getScrumsprint()?$issue->getScrumsprint()->getName():null);
|
||||||
|
foreach($giteaissue->comments as $keycomment => $comment) {
|
||||||
|
$giteaissue->comments[$keycomment]->body=$this->giteaservice->markdown("/".$scrum->getGiteajson()["full_name"],"comment",$giteaissue->comments[$keycomment]->body);
|
||||||
|
}
|
||||||
|
|
||||||
|
$giteaissue->timelines=$this->giteaservice->getIssueTimelines($repoowner,$reponame,$giteaissue->number);
|
||||||
|
|
||||||
|
$giteaissue->labelhistos=[];
|
||||||
|
$giteaissue->refs=[];
|
||||||
|
foreach($giteaissue->timelines as $key => $timeline) {
|
||||||
|
if($timeline->type == "label"){
|
||||||
|
$tmp=new stdClass();
|
||||||
|
$tmp->label=($timeline->body==1?"Ajout Label":"Suppression Label")." <i>".$timeline->label->name."<i>";
|
||||||
|
$tmp->user=$timeline->user;
|
||||||
|
$tmp->created_at=$timeline->created_at;
|
||||||
|
array_push($giteaissue->labelhistos,$tmp);
|
||||||
|
unset($giteaissue->timelines[$key]);
|
||||||
|
}
|
||||||
|
elseif($timeline->type == "comment_ref" || $timeline->type == "pull_ref" || $timeline->type == "issue_ref"){
|
||||||
|
$tmp=new stdClass();
|
||||||
|
$tmp->label ="<a href='".$timeline->ref_issue->html_url."' target='_blank'>";
|
||||||
|
$tmp->label.=($timeline->type=="pull_ref"?"Request":"Issue")." = ";
|
||||||
|
$tmp->label.="#".$timeline->ref_issue->number." = ".$timeline->ref_issue->title."</a></i>";
|
||||||
|
$tmp->user=$timeline->user;
|
||||||
|
$tmp->created_at=$timeline->created_at;
|
||||||
|
array_push($giteaissue->refs,$tmp);
|
||||||
|
unset($giteaissue->timelines[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Affichage du formulaire
|
||||||
|
return $this->render('Scrum/issue.html.twig', [
|
||||||
|
'useheader' => false,
|
||||||
|
'usesidebar' => false,
|
||||||
|
'maxwidth' => true,
|
||||||
|
'repo' => $repo,
|
||||||
|
'issue' => $giteaissue,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function update(Request $request)
|
public function update(Request $request)
|
||||||
{
|
{
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
@ -154,39 +240,123 @@ class ScrumissueController extends AbstractController
|
||||||
return new JsonResponse($weights);
|
return new JsonResponse($weights);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function block(Request $request)
|
||||||
|
{
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
|
$id=$request->get('id');
|
||||||
|
$issueblocked=$request->get('issueblocked');
|
||||||
|
|
||||||
|
// Rechercher l'issue en cours
|
||||||
|
$scrumissue=$em->getRepository("App:Scrumissue")->find($id);
|
||||||
|
if(!$scrumissue) return new JsonResponse(['message' => 'No Issue'], 403);
|
||||||
|
|
||||||
|
// Bloquer l'issue
|
||||||
|
$response=$this->giteaservice->postIssueblocks($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber(),$issueblocked);
|
||||||
|
|
||||||
|
if(!$response) return new JsonResponse(['message' => 'Error api'], 403);
|
||||||
|
|
||||||
|
return new JsonResponse([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unblock(Request $request)
|
||||||
|
{
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
|
$id=$request->get('id');
|
||||||
|
|
||||||
|
// Rechercher l'issue en cours
|
||||||
|
$scrumissue=$em->getRepository("App:Scrumissue")->find($id);
|
||||||
|
if(!$scrumissue) return new JsonResponse(['message' => 'No Issue'], 403);
|
||||||
|
if(!$scrumissue->getScrumissueblock()) return new JsonResponse(['message' => 'No Issue'], 403);
|
||||||
|
$issueblocked=$scrumissue->getScrumissueblock()->getGiteanumber();
|
||||||
|
|
||||||
|
// Débloquer l'issue
|
||||||
|
$response=$this->giteaservice->deleteIssueblocks($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber(),$issueblocked);
|
||||||
|
if(!$response) return new JsonResponse(['message' => 'Error api'], 403);
|
||||||
|
|
||||||
|
return new JsonResponse([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function assigne(Request $request)
|
||||||
|
{
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
|
$id=$request->get('id');
|
||||||
|
$assignees=$request->get('assignees');
|
||||||
|
|
||||||
|
// Rechercher l'issue en cours
|
||||||
|
$scrumissue=$em->getRepository("App:Scrumissue")->find($id);
|
||||||
|
if(!$scrumissue) return new JsonResponse(['message' => 'No Issue'], 403);
|
||||||
|
|
||||||
|
// Affecter l'issue
|
||||||
|
$response=$this->giteaservice->patchissue($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber(),["assignees"=>($assignees?$assignees:[])]);
|
||||||
|
if(!$response) return new JsonResponse(['message' => 'Error api'], 403);
|
||||||
|
|
||||||
|
return new JsonResponse([]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function notes(Request $request)
|
||||||
|
{
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
|
$id=$request->get('id');
|
||||||
|
$notes=$request->get('notes');
|
||||||
|
|
||||||
|
// Rechercher l'issue en cours
|
||||||
|
$scrumissue=$em->getRepository("App:Scrumissue")->find($id);
|
||||||
|
if(!$scrumissue) return new JsonResponse(['message' => 'No Issue'], 403);
|
||||||
|
$scrumissue->setNotes($notes);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
return new JsonResponse([]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function color(Request $request)
|
||||||
|
{
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
|
$id=$request->get('id');
|
||||||
|
$color=$request->get('color');
|
||||||
|
|
||||||
|
// Rechercher l'issue en cours
|
||||||
|
$scrumissue=$em->getRepository("App:Scrumissue")->find($id);
|
||||||
|
if(!$scrumissue) return new JsonResponse(['message' => 'No Issue'], 403);
|
||||||
|
$scrumissue->setColor($color);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
return new JsonResponse([]);
|
||||||
|
}
|
||||||
|
|
||||||
public function ctrlchange(Request $request)
|
public function ctrlchange(Request $request)
|
||||||
{
|
{
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
$id=$request->get('id');
|
$id=$request->get('id');
|
||||||
$lastupdate=new \DateTime($request->get('lastupdate'));
|
$lastupdate=new \DateTime($request->get('lastupdate'));
|
||||||
|
$lastupdate->setTimezone(new \DateTimeZone("UTC"));
|
||||||
|
$lastupdate->add(new \DateInterval("PT1M"));
|
||||||
|
//var_dump($lastupdate->format(\DateTime::RFC3339_EXTENDED));
|
||||||
|
|
||||||
$scrum=$em->getRepository("App:Scrum")->find($id);
|
$scrum=$em->getRepository("App:Scrum")->find($id);
|
||||||
if(!$scrum) return new JsonResponse(['message' => 'No Scrum'], 403);
|
if(!$scrum) return new JsonResponse(['message' => 'No Scrum'], 403);
|
||||||
|
|
||||||
$giteaissues=$this->giteaservice->getIssues($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
$giteaissues=$this->giteaservice->getIssues($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],"?since=".urlencode($lastupdate->format(\DateTime::RFC3339_EXTENDED)));
|
||||||
if(!is_array($giteaissues)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
|
|
||||||
|
|
||||||
foreach($giteaissues as $giteaissue) {
|
return new Response((!empty($giteaissues)?"1":"0"));
|
||||||
// On ne prend pas les pull request
|
|
||||||
if(!is_null($giteaissue->pull_request))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$scrumissue=$em->getRepository("App:Scrumissue")->findOneBy(["scrum"=>$scrum,"giteaid"=>$giteaissue->id]);
|
|
||||||
|
|
||||||
if(!$scrumissue)
|
|
||||||
return new JsonResponse(true);
|
|
||||||
|
|
||||||
$fgissueupdated=false;
|
|
||||||
$updatedate=new \DateTime(json_decode(json_encode($giteaissue), true)["updated_at"]);
|
|
||||||
if($updatedate>$lastupdate) {
|
|
||||||
$fgissueupdated=true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($fgissueupdated)
|
public function getpoker($userid,$issueid,Request $request) {
|
||||||
return new JsonResponse(true);
|
return new Response(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new JsonResponse(false);
|
public function setpoker($userid,$issueid,Request $request) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ class ScrumpriorityController extends AbstractController
|
||||||
|
|
||||||
// Récupérer les repos de gitea
|
// Récupérer les repos de gitea
|
||||||
$gitealabels=$this->giteaservice->getLabels($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
$gitealabels=$this->giteaservice->getLabels($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
||||||
if(!is_array($gitealabels)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
|
if(!is_array($gitealabels)) die("Probleme de connexion avec gitea veuillez vous <a href='/logout'>reconnecter</a>");
|
||||||
|
|
||||||
// Création du formulaire
|
// Création du formulaire
|
||||||
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","gitealabels"=>$gitealabels));
|
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","gitealabels"=>$gitealabels));
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Form\FormError;
|
||||||
|
|
||||||
|
use App\Entity\Scrumsprint as Entity;
|
||||||
|
use App\Form\ScrumsprintType as Form;
|
||||||
|
|
||||||
|
use App\Service\giteaService;
|
||||||
|
|
||||||
|
class ScrumsprintController extends AbstractController
|
||||||
|
{
|
||||||
|
private $data = "scrumsprint";
|
||||||
|
private $route = "app_scrumsprint";
|
||||||
|
private $render = "Scrumsprint/";
|
||||||
|
private $entity = "App:Scrumsprint";
|
||||||
|
|
||||||
|
public function __construct(giteaService $giteaservice) { $this->giteaservice = $giteaservice; }
|
||||||
|
|
||||||
|
public function submit($scrumid, Request $request)
|
||||||
|
{
|
||||||
|
// Initialisation de l'enregistrement
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$scrum=$em->getRepository("App:Scrum")->find($scrumid);
|
||||||
|
$data = new Entity();
|
||||||
|
$data->setScrum($scrum);
|
||||||
|
|
||||||
|
$last = $em->getRepository('App:Scrumsprint')->findOneBy(["scrum"=>$scrum], ['rowid' => 'DESC']);
|
||||||
|
if(!$last) $data->setRowid(0);
|
||||||
|
else $data->setRowid($last->getRowid()+1);
|
||||||
|
|
||||||
|
// Récupérer les repos de gitea
|
||||||
|
$giteamilestones=$this->giteaservice->getmilestones($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
||||||
|
if(!is_array($giteamilestones)) die("Probleme de connexion avec gitea veuillez vous <a href='/logout'>reconnecter</a>");
|
||||||
|
|
||||||
|
// Création du formulaire
|
||||||
|
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","giteamilestones"=>$giteamilestones));
|
||||||
|
|
||||||
|
// Récupération des data du formulaire
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
// Sur erreur
|
||||||
|
$this->getErrorForm(null,$form,$request,$data,"submit");
|
||||||
|
|
||||||
|
// Sur validation
|
||||||
|
if ($form->get('submit')->isClicked() && $form->isValid()) {
|
||||||
|
$data = $form->getData();
|
||||||
|
$getmilestone=$this->giteaservice->getmilestone($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],$data->getGiteamilestone());
|
||||||
|
$data->setGiteamilestonename($getmilestone->title);
|
||||||
|
|
||||||
|
$em->persist($data);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
// Retour à la liste
|
||||||
|
return $this->render($this->render.'close.html.twig');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Affichage du formulaire
|
||||||
|
return $this->render($this->render.'edit.html.twig', [
|
||||||
|
'useheader' => false,
|
||||||
|
'usesidebar' => false,
|
||||||
|
$this->data => $data,
|
||||||
|
'mode' => 'submit',
|
||||||
|
'form' => $form->createView()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id,Request $request)
|
||||||
|
{
|
||||||
|
// Initialisation de l'enregistrement
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$data=$em->getRepository($this->entity)->find($id);
|
||||||
|
$scrum=$data->getScrum();
|
||||||
|
|
||||||
|
// Récupérer les repos de gitea
|
||||||
|
$giteamilestones=$this->giteaservice->getmilestones($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
||||||
|
|
||||||
|
// Création du formulaire
|
||||||
|
$form = $this->createForm(Form::class,$data,array("mode"=>"update","giteamilestones"=>$giteamilestones));
|
||||||
|
|
||||||
|
// Récupération des data du formulaire
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
// Sur erreur
|
||||||
|
$this->getErrorForm(null,$form,$request,$data,"update");
|
||||||
|
|
||||||
|
// Sur validation
|
||||||
|
if ($form->get('submit')->isClicked() && $form->isValid()) {
|
||||||
|
$data = $form->getData();
|
||||||
|
$getmilestone=$this->giteaservice->getmilestone($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],$data->getGiteamilestone());
|
||||||
|
$data->setGiteamilestonename($getmilestone->title);
|
||||||
|
|
||||||
|
$em->persist($data);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
// Retour à la liste
|
||||||
|
return $this->render($this->render.'close.html.twig');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Affichage du formulaire
|
||||||
|
return $this->render($this->render.'edit.html.twig', [
|
||||||
|
'useheader' => false,
|
||||||
|
'usesidebar' => false,
|
||||||
|
$this->data => $data,
|
||||||
|
'mode' => 'update',
|
||||||
|
'form' => $form->createView()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($id,Request $request)
|
||||||
|
{
|
||||||
|
// Initialisation de l'enregistrement
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$data=$em->getRepository($this->entity)->find($id);
|
||||||
|
|
||||||
|
// Controle avant suppression
|
||||||
|
$error=false;
|
||||||
|
if($id<0) $error=true;
|
||||||
|
|
||||||
|
if($error)
|
||||||
|
return $this->redirectToRoute($this->route."_update",["id"=>$id]);
|
||||||
|
else {
|
||||||
|
$em->remove($data);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
// Retour à la liste
|
||||||
|
return $this->render($this->render.'close.html.twig');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function select($scrumid, Request $request)
|
||||||
|
{
|
||||||
|
// S'assurer que c'est un appel ajax
|
||||||
|
if (!$request->isXmlHttpRequest()) {
|
||||||
|
return new JsonResponse(array('message' => 'Interdit'), 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$scrum=$em->getRepository("App:Scrum")->find($scrumid);
|
||||||
|
|
||||||
|
$scrumsprints = $scrum->getScrumsprints();
|
||||||
|
$output=array();
|
||||||
|
foreach($scrumsprints as $scrumsprint) {
|
||||||
|
$title = "Jalon = ".$scrumsprint->getGiteamilestonename()."<br>";
|
||||||
|
$title.= "Sprint = ".$scrumsprint->getName();
|
||||||
|
array_push($output,array("id"=>$scrumsprint->getId(),"name"=>$title,"closed"=>$scrumsprint->getClosed()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = new Response(json_encode($output));
|
||||||
|
$response->headers->set('Content-Type', 'application/json');
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function order($scrumid, Request $request)
|
||||||
|
{
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$scrumsprintids=explode(",",$request->get('lstordered'));
|
||||||
|
$i=1;
|
||||||
|
foreach($scrumsprintids as $id) {
|
||||||
|
$scrumsprint=$em->getRepository($this->entity)->find($id);
|
||||||
|
if($scrumsprint) {
|
||||||
|
$scrumsprint->setRowid($i);
|
||||||
|
$em->persist($scrumsprint);
|
||||||
|
$em->flush();
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
$response = new Response();
|
||||||
|
$response->headers->set('Content-Type', 'application/json');
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getErrorForm($id,$form,$request,$data,$mode) {
|
||||||
|
if ($form->get('submit')->isClicked()&&$mode=="delete") {
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($form->get('submit')->isClicked() && $mode=="submit") {
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($form->get('submit')->isClicked() && ($mode=="submit" || $mode=="update")) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($form->get('submit')->isClicked() && !$form->isValid()) {
|
||||||
|
$this->get('session')->getFlashBag()->clear();
|
||||||
|
|
||||||
|
$errors = $form->getErrors();
|
||||||
|
foreach( $errors as $error ) {
|
||||||
|
$request->getSession()->getFlashBag()->add("error", $error->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,7 +35,7 @@ class ScrumteamController extends AbstractController
|
||||||
|
|
||||||
// Récupérer les repos de gitea
|
// Récupérer les repos de gitea
|
||||||
$gitealabels=$this->giteaservice->getLabels($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
$gitealabels=$this->giteaservice->getLabels($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
||||||
if(!is_array($gitealabels)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
|
if(!is_array($gitealabels)) die("Probleme de connexion avec gitea veuillez vous <a href='/logout'>reconnecter</a>");
|
||||||
|
|
||||||
// Création du formulaire
|
// Création du formulaire
|
||||||
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","gitealabels"=>$gitealabels));
|
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","gitealabels"=>$gitealabels));
|
||||||
|
|
|
@ -35,7 +35,7 @@ class ScrumtypeController extends AbstractController
|
||||||
|
|
||||||
// Récupérer les repos de gitea
|
// Récupérer les repos de gitea
|
||||||
$gitealabels=$this->giteaservice->getLabels($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
$gitealabels=$this->giteaservice->getLabels($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
||||||
if(!is_array($gitealabels)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
|
if(!is_array($gitealabels)) die("Probleme de connexion avec gitea veuillez vous <a href='/logout'>reconnecter</a>");
|
||||||
|
|
||||||
// Création du formulaire
|
// Création du formulaire
|
||||||
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","gitealabels"=>$gitealabels));
|
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","gitealabels"=>$gitealabels));
|
||||||
|
|
|
@ -135,16 +135,8 @@ class SecurityController extends AbstractController
|
||||||
}
|
}
|
||||||
|
|
||||||
public function loginOAUTH() {
|
public function loginOAUTH() {
|
||||||
/*
|
|
||||||
OAUTH_CLIENTID=
|
|
||||||
OAUTH_CLIENTSECRET=
|
|
||||||
OAUTH_LOGINURL=https://forge.cadoles.com/login/oauth/authorize
|
|
||||||
OAUTH_LOGOUTURL=https://forge.cadoles.com/user/logout
|
|
||||||
OAUTH_TOKENURL=https://forge.cadoles.com/login/oauth/access_token
|
|
||||||
*/
|
|
||||||
// https://[YOUR-GITEA-URL]/login/oauth/authorize?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI& response_type=code&state=STATE
|
|
||||||
|
|
||||||
$callback=$this->generateUrl('app_login_callback', array(), UrlGeneratorInterface::ABSOLUTE_URL);
|
$callback=$this->generateUrl('app_login_callback', array(), UrlGeneratorInterface::ABSOLUTE_URL);
|
||||||
|
$callback=str_replace("http://",$this->getParameter("appProtocol")."://",$callback);
|
||||||
$this->get('session')->set('giteacallback', $callback);
|
$this->get('session')->set('giteacallback', $callback);
|
||||||
$url=$this->getParameter("oauthLoginurl")."?client_id=".$this->getParameter("oauthClientid")."&redirect_uri=".$callback."&response_type=code&state=STATE";
|
$url=$this->getParameter("oauthLoginurl")."?client_id=".$this->getParameter("oauthClientid")."&redirect_uri=".$callback."&response_type=code&state=STATE";
|
||||||
return $this->redirect($url);
|
return $this->redirect($url);
|
||||||
|
@ -208,10 +200,15 @@ class SecurityController extends AbstractController
|
||||||
|
|
||||||
// Redirection
|
// Redirection
|
||||||
$redirect = $this->get('session')->get("_security.main.target_path");
|
$redirect = $this->get('session')->get("_security.main.target_path");
|
||||||
if($redirect)
|
if($redirect) {
|
||||||
|
$redirect=str_replace("http://",$this->getParameter("appProtocol")."://",$redirect);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$redirect=$this->generateUrl('app_home');
|
||||||
|
$redirect=str_replace("http://",$this->getParameter("appProtocol")."://",$redirect);
|
||||||
|
}
|
||||||
return $this->redirect($redirect);
|
return $this->redirect($redirect);
|
||||||
else
|
|
||||||
return $this->redirect($this->generateUrl('app_home'));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,12 @@ class Scrum
|
||||||
*/
|
*/
|
||||||
private $scrumcolumns;
|
private $scrumcolumns;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\OneToMany(targetEntity="Scrumsprint", mappedBy="scrum", cascade={"persist"}, orphanRemoval=true)
|
||||||
|
* @ORM\OrderBy({"rowid" = "ASC"})
|
||||||
|
*/
|
||||||
|
private $scrumsprints;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="Scrumissue", mappedBy="scrum", cascade={"persist"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="Scrumissue", mappedBy="scrum", cascade={"persist"}, orphanRemoval=true)
|
||||||
* @ORM\OrderBy({"giteamilestonename" = "DESC", "rowid" = "ASC"})
|
* @ORM\OrderBy({"giteamilestonename" = "DESC", "rowid" = "ASC"})
|
||||||
|
@ -108,6 +114,18 @@ class Scrum
|
||||||
return $tab;
|
return $tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getScrumsprintstosee($viewclosed) {
|
||||||
|
$sprints=$this->getScrumsprints();
|
||||||
|
if($viewclosed=="false") {
|
||||||
|
foreach($sprints as $sprint) {
|
||||||
|
if($sprint->getClosed()) {
|
||||||
|
$sprints->removeElement($sprint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $sprints;
|
||||||
|
}
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->users = new ArrayCollection();
|
$this->users = new ArrayCollection();
|
||||||
|
@ -117,6 +135,7 @@ class Scrum
|
||||||
$this->scrumteams = new ArrayCollection();
|
$this->scrumteams = new ArrayCollection();
|
||||||
$this->scrumprioritys = new ArrayCollection();
|
$this->scrumprioritys = new ArrayCollection();
|
||||||
$this->scrumtypes = new ArrayCollection();
|
$this->scrumtypes = new ArrayCollection();
|
||||||
|
$this->scrumsprints = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
|
@ -378,4 +397,35 @@ class Scrum
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection|Scrumsprint[]
|
||||||
|
*/
|
||||||
|
public function getScrumsprints(): Collection
|
||||||
|
{
|
||||||
|
return $this->scrumsprints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addScrumsprint(Scrumsprint $scrumsprint): self
|
||||||
|
{
|
||||||
|
if (!$this->scrumsprints->contains($scrumsprint)) {
|
||||||
|
$this->scrumsprints[] = $scrumsprint;
|
||||||
|
$scrumsprint->setScrum($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeScrumsprint(Scrumsprint $scrumsprint): self
|
||||||
|
{
|
||||||
|
if ($this->scrumsprints->contains($scrumsprint)) {
|
||||||
|
$this->scrumsprints->removeElement($scrumsprint);
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($scrumsprint->getScrum() === $this) {
|
||||||
|
$scrumsprint->setScrum(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -49,8 +49,8 @@ class Scrumcolumn
|
||||||
private $scrum;
|
private $scrum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\OneToMany(targetEntity="Scrumissue", mappedBy="scrumcolumn", cascade={"persist"}, orphanRemoval=true)
|
* @ORM\OneToMany(targetEntity="Scrumissue", mappedBy="scrumcolumn", cascade={"persist"}, orphanRemoval=false)
|
||||||
* @ORM\OrderBy({"giteamilestonename" = "DESC", "rowid" = "ASC"})
|
* @ORM\OrderBy({"giteamilestonename" = "DESC", "scrumsprint" = "DESC", "rowid" = "ASC"})
|
||||||
*/
|
*/
|
||||||
private $scrumissues;
|
private $scrumissues;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace App\Entity;
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
|
@ -31,6 +33,16 @@ class Scrumissue
|
||||||
*/
|
*/
|
||||||
private $weight=0;
|
private $weight=0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="string", nullable=true)
|
||||||
|
*/
|
||||||
|
private $color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="text", nullable=true)
|
||||||
|
*/
|
||||||
|
private $notes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="integer")
|
* @ORM\Column(type="integer")
|
||||||
*/
|
*/
|
||||||
|
@ -69,15 +81,46 @@ class Scrumissue
|
||||||
private $giteajson;
|
private $giteajson;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity="Scrum", inversedBy="Scrumissues")
|
* @ORM\ManyToOne(targetEntity="Scrum", inversedBy="scrumissues")
|
||||||
*/
|
*/
|
||||||
private $scrum;
|
private $scrum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToOne(targetEntity="Scrumcolumn", inversedBy="Scrumissues")
|
* @ORM\ManyToOne(targetEntity="Scrumcolumn", inversedBy="scrumissues")
|
||||||
|
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
|
||||||
*/
|
*/
|
||||||
private $scrumcolumn;
|
private $scrumcolumn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity="Scrumsprint", inversedBy="scrumissues")
|
||||||
|
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
|
||||||
|
*/
|
||||||
|
private $scrumsprint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity="Scrumissue", inversedBy="scrumissuedependencies")
|
||||||
|
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
|
||||||
|
*/
|
||||||
|
private $scrumissueblock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\OneToMany(targetEntity="Scrumissue", mappedBy="scrumissueblock", cascade={"persist"}, orphanRemoval=false)
|
||||||
|
* @ORM\OrderBy({"giteanumber" = "ASC"})
|
||||||
|
*/
|
||||||
|
private $scrumissuedependencies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\OneToMany(targetEntity="Userpoker", mappedBy="scrumissue", cascade={"persist"}, orphanRemoval=true)
|
||||||
|
*/
|
||||||
|
private $userpokers;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->userpokers = new ArrayCollection();
|
||||||
|
$this->scrumissuedependcies = new ArrayCollection();
|
||||||
|
$this->scrumissuedependencies = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
|
@ -215,6 +258,113 @@ class Scrumissue
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getScrumsprint(): ?Scrumsprint
|
||||||
|
{
|
||||||
|
return $this->scrumsprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setScrumsprint(?Scrumsprint $scrumsprint): self
|
||||||
|
{
|
||||||
|
$this->scrumsprint = $scrumsprint;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection|Userpoker[]
|
||||||
|
*/
|
||||||
|
public function getUserpokers(): Collection
|
||||||
|
{
|
||||||
|
return $this->userpokers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addUserpoker(Userpoker $userpoker): self
|
||||||
|
{
|
||||||
|
if (!$this->userpokers->contains($userpoker)) {
|
||||||
|
$this->userpokers[] = $userpoker;
|
||||||
|
$userpoker->setScrumissue($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeUserpoker(Userpoker $userpoker): self
|
||||||
|
{
|
||||||
|
if ($this->userpokers->contains($userpoker)) {
|
||||||
|
$this->userpokers->removeElement($userpoker);
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($userpoker->getScrumissue() === $this) {
|
||||||
|
$userpoker->setScrumissue(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getScrumissueblock(): ?self
|
||||||
|
{
|
||||||
|
return $this->scrumissueblock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setScrumissueblock(?self $scrumissueblock): self
|
||||||
|
{
|
||||||
|
$this->scrumissueblock = $scrumissueblock;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection|Scrumissue[]
|
||||||
|
*/
|
||||||
|
public function getScrumissuedependencies(): Collection
|
||||||
|
{
|
||||||
|
return $this->scrumissuedependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addScrumissuedependency(Scrumissue $scrumissuedependency): self
|
||||||
|
{
|
||||||
|
if (!$this->scrumissuedependencies->contains($scrumissuedependency)) {
|
||||||
|
$this->scrumissuedependencies[] = $scrumissuedependency;
|
||||||
|
$scrumissuedependency->setScrumissue($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeScrumissuedependency(Scrumissue $scrumissuedependency): self
|
||||||
|
{
|
||||||
|
if ($this->scrumissuedependencies->contains($scrumissuedependency)) {
|
||||||
|
$this->scrumissuedependencies->removeElement($scrumissuedependency);
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($scrumissuedependency->getScrumissue() === $this) {
|
||||||
|
$scrumissuedependency->setScrumissue(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getColor(): ?string
|
||||||
|
{
|
||||||
|
return $this->color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setColor(?string $color): self
|
||||||
|
{
|
||||||
|
$this->color = $color;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNotes(): ?string
|
||||||
|
{
|
||||||
|
return $this->notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setNotes(?string $notes): self
|
||||||
|
{
|
||||||
|
$this->notes = $notes;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,176 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrumcolumn
|
||||||
|
*
|
||||||
|
* @ORM\Entity()
|
||||||
|
* @ORM\Table(name="scrumsprint")
|
||||||
|
*/
|
||||||
|
class Scrumsprint
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="id", type="integer")
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="name", type="string")
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="integer")
|
||||||
|
*/
|
||||||
|
private $rowid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="boolean")
|
||||||
|
*/
|
||||||
|
private $closed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="integer", nullable=true)
|
||||||
|
*/
|
||||||
|
private $giteamilestone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(type="string", nullable=true)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private $giteamilestonename;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity="Scrum", inversedBy="scrumsprints")
|
||||||
|
*/
|
||||||
|
private $scrum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\OneToMany(targetEntity="Scrumissue", mappedBy="scrumsprint", cascade={"persist"}, orphanRemoval=false)
|
||||||
|
*/
|
||||||
|
private $scrumissues;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->scrumissues = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): ?string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setName(string $name): self
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRowid(): ?int
|
||||||
|
{
|
||||||
|
return $this->rowid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setRowid(int $rowid): self
|
||||||
|
{
|
||||||
|
$this->rowid = $rowid;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGiteamilestone(): ?int
|
||||||
|
{
|
||||||
|
return $this->giteamilestone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setGiteamilestone(?int $giteamilestone): self
|
||||||
|
{
|
||||||
|
$this->giteamilestone = $giteamilestone;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGiteamilestonename(): ?string
|
||||||
|
{
|
||||||
|
return $this->giteamilestonename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setGiteamilestonename(?string $giteamilestonename): self
|
||||||
|
{
|
||||||
|
$this->giteamilestonename = $giteamilestonename;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getScrum(): ?Scrum
|
||||||
|
{
|
||||||
|
return $this->scrum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setScrum(?Scrum $scrum): self
|
||||||
|
{
|
||||||
|
$this->scrum = $scrum;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection|Scrumissue[]
|
||||||
|
*/
|
||||||
|
public function getScrumissues(): Collection
|
||||||
|
{
|
||||||
|
return $this->scrumissues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addScrumissue(Scrumissue $scrumissue): self
|
||||||
|
{
|
||||||
|
if (!$this->scrumissues->contains($scrumissue)) {
|
||||||
|
$this->scrumissues[] = $scrumissue;
|
||||||
|
$scrumissue->setScrumsprint($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeScrumissue(Scrumissue $scrumissue): self
|
||||||
|
{
|
||||||
|
if ($this->scrumissues->contains($scrumissue)) {
|
||||||
|
$this->scrumissues->removeElement($scrumissue);
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($scrumissue->getScrumsprint() === $this) {
|
||||||
|
$scrumissue->setScrumsprint(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClosed(): ?bool
|
||||||
|
{
|
||||||
|
return $this->closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setClosed(bool $closed): self
|
||||||
|
{
|
||||||
|
$this->closed = $closed;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -85,6 +85,11 @@ class User implements UserInterface, \Serializable
|
||||||
*/
|
*/
|
||||||
private $preference;
|
private $preference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\OneToMany(targetEntity="Userpoker", mappedBy="user", cascade={"persist"}, orphanRemoval=true)
|
||||||
|
*/
|
||||||
|
private $userpokers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToMany(targetEntity="Group", inversedBy="users", cascade={"persist"})
|
* @ORM\ManyToMany(targetEntity="Group", inversedBy="users", cascade={"persist"})
|
||||||
* @ORM\JoinTable(name="usergroupe",
|
* @ORM\JoinTable(name="usergroupe",
|
||||||
|
@ -107,6 +112,7 @@ class User implements UserInterface, \Serializable
|
||||||
{
|
{
|
||||||
$this->groups = new ArrayCollection();
|
$this->groups = new ArrayCollection();
|
||||||
$this->scrums = new ArrayCollection();
|
$this->scrums = new ArrayCollection();
|
||||||
|
$this->userpokers = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUsername(): ?string
|
public function getUsername(): ?string
|
||||||
|
@ -172,7 +178,7 @@ class User implements UserInterface, \Serializable
|
||||||
|
|
||||||
public function getDisplayname()
|
public function getDisplayname()
|
||||||
{
|
{
|
||||||
return $this->firstname." ".$this->lastname;
|
return $this->username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setId(int $id): self
|
public function setId(int $id): self
|
||||||
|
@ -336,4 +342,35 @@ class User implements UserInterface, \Serializable
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection|Userpoker[]
|
||||||
|
*/
|
||||||
|
public function getUserpokers(): Collection
|
||||||
|
{
|
||||||
|
return $this->userpokers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addUserpoker(Userpoker $userpoker): self
|
||||||
|
{
|
||||||
|
if (!$this->userpokers->contains($userpoker)) {
|
||||||
|
$this->userpokers[] = $userpoker;
|
||||||
|
$userpoker->setUser($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeUserpoker(Userpoker $userpoker): self
|
||||||
|
{
|
||||||
|
if ($this->userpokers->contains($userpoker)) {
|
||||||
|
$this->userpokers->removeElement($userpoker);
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($userpoker->getUser() === $this) {
|
||||||
|
$userpoker->setUser(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Userpoker
|
||||||
|
*
|
||||||
|
* @ORM\Entity()
|
||||||
|
* @ORM\Table(name="userpoker")
|
||||||
|
*/
|
||||||
|
class Userpoker
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="id", type="integer")
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="name", type="integer")
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private $nb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity="Scrumissue", inversedBy="userpokers")
|
||||||
|
*/
|
||||||
|
private $scrumissue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\ManyToOne(targetEntity="User", inversedBy="userpokers")
|
||||||
|
*/
|
||||||
|
private $user;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNb(): ?int
|
||||||
|
{
|
||||||
|
return $this->nb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setNb(int $nb): self
|
||||||
|
{
|
||||||
|
$this->nb = $nb;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getScrumissue(): ?Scrumissue
|
||||||
|
{
|
||||||
|
return $this->scrumissue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setScrumissue(?Scrumissue $scrumissue): self
|
||||||
|
{
|
||||||
|
$this->scrumissue = $scrumissue;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUser(): ?User
|
||||||
|
{
|
||||||
|
return $this->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUser(?User $user): self
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
namespace App\Form;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Tetranz\Select2EntityBundle\Form\Type\Select2EntityType;
|
||||||
|
|
||||||
|
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||||
|
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Doctrine\ORM\EntityManager;
|
||||||
|
|
||||||
|
class ScrumsprintType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->add('submit',
|
||||||
|
SubmitType::class, [
|
||||||
|
"label" => "Valider",
|
||||||
|
"attr" => ["class" => "btn btn-success no-print"],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$builder->add('name',
|
||||||
|
TextType::class, [
|
||||||
|
"label" =>"Nom",
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$choices=["non"=>0,"oui"=>1];
|
||||||
|
$builder->add('closed',
|
||||||
|
ChoiceType::class, ['choices' => $choices]
|
||||||
|
);
|
||||||
|
|
||||||
|
$choices=[];
|
||||||
|
foreach($options["giteamilestones"] as $milestone) {
|
||||||
|
$choices[$milestone->title]=$milestone->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$builder->add('giteamilestone',
|
||||||
|
ChoiceType::class, [
|
||||||
|
"label" => "Jalon Gitea",
|
||||||
|
"choices" => $choices,
|
||||||
|
"disabled" => ($options["mode"]=="submit"?false:true),
|
||||||
|
"placeholder" => "Selectionnez un label gitea",
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefaults(array(
|
||||||
|
'data_class' => 'App\Entity\Scrumsprint',
|
||||||
|
'mode' => 'string',
|
||||||
|
'giteamilestones' => 'string',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,13 +13,32 @@ class ScrumRepository extends ServiceEntityRepository
|
||||||
{
|
{
|
||||||
private $session;
|
private $session;
|
||||||
private $firstcolumn;
|
private $firstcolumn;
|
||||||
private $datescrumupdate;
|
private $totalTime;
|
||||||
|
private $startTime;
|
||||||
|
private $showTime;
|
||||||
|
|
||||||
public function __construct(ManagerRegistry $registry,giteaService $giteaservice,SessionInterface $session)
|
public function __construct(ManagerRegistry $registry,giteaService $giteaservice,SessionInterface $session)
|
||||||
{
|
{
|
||||||
parent::__construct($registry, Scrum::class);
|
parent::__construct($registry, Scrum::class);
|
||||||
$this->giteaservice = $giteaservice;
|
$this->giteaservice = $giteaservice;
|
||||||
$this->session = $session;
|
$this->session = $session;
|
||||||
|
$this->showTime = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function showtime($istart,$title="") {
|
||||||
|
if($this->showTime) {
|
||||||
|
if($istart) {
|
||||||
|
$this->totalTime = microtime(true);
|
||||||
|
$this->startTime = microtime(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$endTime = microtime(true);
|
||||||
|
$executionTime = $endTime - $this->startTime;
|
||||||
|
$totalTime = $endTime - $this->totalTime;
|
||||||
|
dump($executionTime." / ".$totalTime." = ".$title);
|
||||||
|
$this->startTime = microtime(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findByUser($user) {
|
public function findByUser($user) {
|
||||||
|
@ -36,9 +55,81 @@ class ScrumRepository extends ServiceEntityRepository
|
||||||
return $scrums;
|
return $scrums;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function getGitea($scrum,&$giteaassignees,&$giteacolumns,&$giteamilestones,&$giteateams,&$giteaprioritys,&$giteatypes,&$gitealabels, $forcereload=false) {
|
public function getGitea($scrum,&$giteaassignees,&$giteacolumns,&$giteamilestones,&$giteateams,&$giteaprioritys,&$giteatypes,&$gitealabels, $forcereload=false) {
|
||||||
|
$this->showtime(true);
|
||||||
|
$lastupdate = $scrum->getUpdatedate();
|
||||||
|
if(!$lastupdate) $lastupdate = new \DateTime(("19000101"));
|
||||||
|
$lastupdate->sub(new \DateInterval('PT30M'));
|
||||||
|
|
||||||
$viewclosed = $this->session->get("viewclosed");
|
$viewclosed = $this->session->get("viewclosed");
|
||||||
|
|
||||||
|
// Récupérer les labels de gitea
|
||||||
|
$gitealabels=$this->giteaservice->getLabels($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
||||||
|
if(!is_array($gitealabels)) die("Probleme de connexion avec gitea veuillez vous <a href='/logout'>reconnecter</a>");
|
||||||
|
$giteaidlabels=array_column($gitealabels, 'id');
|
||||||
|
|
||||||
|
// Récupérer les jalons de gitea
|
||||||
|
$giteamilestones=$this->giteaservice->getMilestones($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
||||||
|
if(!is_array($giteamilestones)) die("Probleme de connexion avec gitea veuillez vous <a href='/logout'>reconnecter</a>");
|
||||||
|
$giteaidmilestones=array_column($giteamilestones, 'id');
|
||||||
|
|
||||||
|
// Temps d'execution
|
||||||
|
$this->showtime(false,"Récupération gitealabels & giteamilestones");
|
||||||
|
|
||||||
|
// S'assurer que nos colonnes existes toujours
|
||||||
|
$scrumcolumns=$scrum->getScrumcolumns();
|
||||||
|
foreach($scrumcolumns as $scrumcolumn) {
|
||||||
|
if(!in_array($scrumcolumn->getGiteaid(),$giteaidlabels)) {
|
||||||
|
$this->_em->remove($scrumcolumn);
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// S'assurer que nos teams existes toujours
|
||||||
|
$scrumteams=$scrum->getScrumteams();
|
||||||
|
foreach($scrumteams as $scrumteam) {
|
||||||
|
if(!in_array($scrumteam->getGiteaid(),$giteaidlabels)) {
|
||||||
|
$this->_em->remove($scrumteam);
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// S'assurer que nos prioritys existes toujours
|
||||||
|
$scrumprioritys=$scrum->getScrumprioritys();
|
||||||
|
foreach($scrumprioritys as $scrumpriority) {
|
||||||
|
if(!in_array($scrumpriority->getGiteaid(),$giteaidlabels)) {
|
||||||
|
$this->_em->remove($scrumpriority);
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// S'assurer que nos types existes toujours
|
||||||
|
$scrumtypes=$scrum->getScrumtypes();
|
||||||
|
foreach($scrumtypes as $scrumtype) {
|
||||||
|
if(!in_array($scrumtype->getGiteaid(),$giteaidlabels)) {
|
||||||
|
$this->_em->remove($scrumtype);
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temps d'execution
|
||||||
|
$this->showtime(false,"S'assurer que nos labels colonnes teams prioritys types existes toujours");
|
||||||
|
|
||||||
|
// S'assurer que nos sprint sont toujours lié à un jalon existant
|
||||||
|
$scrumsprints=$scrum->getScrumsprints();
|
||||||
|
foreach($scrumsprints as $scrumsprint) {
|
||||||
|
if(!in_array($scrumsprint->getGiteamilestone(),$giteaidmilestones)) {
|
||||||
|
$this->_em->remove($scrumsprint);
|
||||||
|
$this->_em->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temps d'execution
|
||||||
|
$this->showtime(false,"S'assurer que nos sprint sont toujours lié à un jalon existant");
|
||||||
|
|
||||||
// Récupérer le dernier order
|
// Récupérer le dernier order
|
||||||
$last = $this->_em->getRepository('App:Scrumissue')->findOneBy(["scrum"=>$scrum], ['rowid' => 'DESC']);
|
$last = $this->_em->getRepository('App:Scrumissue')->findOneBy(["scrum"=>$scrum], ['rowid' => 'DESC']);
|
||||||
if(!$last) $lastrowid=-1;
|
if(!$last) $lastrowid=-1;
|
||||||
|
@ -82,54 +173,42 @@ class ScrumRepository extends ServiceEntityRepository
|
||||||
else
|
else
|
||||||
$giteaassignees=[];
|
$giteaassignees=[];
|
||||||
|
|
||||||
$giteacollaborators=$this->giteaservice->getOrgateams($scrum->getGiteajson()["owner"]["login"]);
|
// Temps d'execution
|
||||||
if($giteacollaborators&&is_array($giteacollaborators)) {
|
$this->showtime(false,"Récupérer info ninegitea");
|
||||||
foreach($giteacollaborators as $team) {
|
|
||||||
$giteamembers=$this->giteaservice->getTeammembers($team->id);
|
// Récupérer les intervenants
|
||||||
if($giteamembers&&is_array($giteamembers)) {
|
$giteacollaborators=$this->giteaservice->getAssignees($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
||||||
foreach($giteamembers as $giteamember) {
|
if(!is_array($giteacollaborators)) die("Probleme de connexion avec gitea veuillez vous <a href='/logout'>reconnecter</a>");
|
||||||
if(!in_array($giteamember,$giteaassignees))
|
|
||||||
array_push($giteaassignees,$giteamember);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$giteacollaborators=$this->giteaservice->getCollaborators($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
|
||||||
if(!is_array($giteacollaborators)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
|
|
||||||
foreach($giteacollaborators as $giteacollaborator) {
|
foreach($giteacollaborators as $giteacollaborator) {
|
||||||
if(!in_array($giteacollaborator,$giteaassignees))
|
if(!in_array($giteacollaborator,$giteaassignees))
|
||||||
array_push($giteaassignees,$giteacollaborator);
|
array_push($giteaassignees,$giteacollaborator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temps d'execution
|
||||||
|
$this->showtime(false,"Récupérer les intervenants");
|
||||||
|
|
||||||
// Récupérer les milestones de gitea
|
// Récupérer les milestones de gitea
|
||||||
$giteamilestones=$this->giteaservice->getMilestones($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],"?state=".($viewclosed=="true"?"all":"open"));
|
$giteamilestones=$this->giteaservice->getMilestones($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],"?state=".($viewclosed=="true"?"all":"open"));
|
||||||
if(!is_array($giteamilestones)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
|
if(!is_array($giteamilestones)) die("Probleme de connexion avec gitea veuillez vous <a href='/logout'>reconnecter</a>");
|
||||||
$keysort = array_column($giteamilestones, 'title');
|
$keysort = array_column($giteamilestones, 'title');
|
||||||
array_multisort($keysort, SORT_DESC, $giteamilestones);
|
array_multisort($keysort, SORT_DESC, $giteamilestones);
|
||||||
|
|
||||||
// Récupérer les labels de gitea
|
// Temps d'execution
|
||||||
$gitealabels=$this->giteaservice->getLabels($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
|
$this->showtime(false,"Récupérer les milestones");
|
||||||
|
|
||||||
if(!is_array($gitealabels)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
|
|
||||||
foreach($gitealabels as $key => $gitealabel) {
|
|
||||||
if(in_array($gitealabel->id,$giteacolumns)||in_array($gitealabel->id,$giteateams)||in_array($gitealabel->id,$giteaprioritys)||in_array($gitealabel->id,$giteatypes))
|
|
||||||
unset($gitealabels[$key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Récupérer les issues de gitea
|
// Récupérer les issues de gitea
|
||||||
$giteaissues=$this->giteaservice->getIssues($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],"?state=".($viewclosed=="true"?"all":"open"));
|
$giteaissues=$this->giteaservice->getIssues($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],"?state=all".(!$forcereload?"&since=".urlencode($lastupdate->format(\DateTime::RFC3339_EXTENDED)):""));
|
||||||
if(!is_array($giteaissues)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
|
if(!is_array($giteaissues)) die("Probleme de connexion avec gitea veuillez vous <a href='/logout'>reconnecter</a>");
|
||||||
|
|
||||||
|
// Temps d'execution
|
||||||
|
$this->showtime(false,"Récupérer les issues");
|
||||||
|
|
||||||
// Génération des issues
|
// Génération des issues
|
||||||
$tbgiteaissues=[];
|
$tbgiteaissues=[];
|
||||||
$fgscrumupdate=false;
|
$fgscrumupdate=false;
|
||||||
$this->datescrumupdate=new \DateTime();
|
$updatedates=[];
|
||||||
|
|
||||||
foreach($giteaissues as $giteaissue) {
|
foreach($giteaissues as $giteaissue) {
|
||||||
// On ne prend pas les pull request
|
|
||||||
if(!is_null($giteaissue->pull_request)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scrumissue=$this->_em->getRepository("App:Scrumissue")->findOneBy(["scrum"=>$scrum,"giteaid"=>$giteaissue->id]);
|
$scrumissue=$this->_em->getRepository("App:Scrumissue")->findOneBy(["scrum"=>$scrum,"giteaid"=>$giteaissue->id]);
|
||||||
|
|
||||||
|
@ -139,8 +218,9 @@ class ScrumRepository extends ServiceEntityRepository
|
||||||
$scrumissue->setScrum($scrum);
|
$scrumissue->setScrum($scrum);
|
||||||
$scrumissue->setRowid($lastrowid);
|
$scrumissue->setRowid($lastrowid);
|
||||||
$scrumissue->setGiteaid($giteaissue->id);
|
$scrumissue->setGiteaid($giteaissue->id);
|
||||||
|
$this->majissue($scrumissue,$giteaissue,true);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
$fgissueupdated=false;
|
$fgissueupdated=false;
|
||||||
if($scrumissue->getGiteajson()["updated_at"]!=json_decode(json_encode($giteaissue), true)["updated_at"])
|
if($scrumissue->getGiteajson()["updated_at"]!=json_decode(json_encode($giteaissue), true)["updated_at"])
|
||||||
$fgissueupdated=true;
|
$fgissueupdated=true;
|
||||||
|
@ -156,39 +236,53 @@ class ScrumRepository extends ServiceEntityRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
if($fgissueupdated) {
|
if($fgissueupdated) {
|
||||||
|
$updateissue=new \DateTime(json_decode(json_encode($giteaissue), true)["updated_at"]);
|
||||||
|
$updateissue->setTimezone(new \DateTimeZone("UTC"));
|
||||||
|
array_push($updatedates,$updateissue);
|
||||||
|
|
||||||
|
if($giteaissue->closed_at) {
|
||||||
|
$closeissue=new \DateTime(json_decode(json_encode($giteaissue), true)["closed_at"]);
|
||||||
|
$closeissue->setTimezone(new \DateTimeZone("UTC"));
|
||||||
|
array_push($updatedates,$closeissue);
|
||||||
|
}
|
||||||
|
|
||||||
$fgscrumupdate=true;
|
$fgscrumupdate=true;
|
||||||
$this->majissue($scrumissue,$giteaissue);
|
$this->majissue($scrumissue,$giteaissue,false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
array_push($tbgiteaissues,$giteaissue->number);
|
array_push($tbgiteaissues,$giteaissue->number);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bug faudrait placer à closed l'ensemble des issues vu comme open mais qui ne le sont plus
|
// Temps d'execution
|
||||||
if($viewclosed=="false") {
|
$this->showtime(false,"Traiter les issues");
|
||||||
$scrumissues=$scrum->getScrumissues();
|
|
||||||
foreach($scrumissues as $scrumissue) {
|
|
||||||
if($scrumissue->getGiteastate()=="open"&&!in_array($scrumissue->getGiteanumber(),$tbgiteaissues)) {
|
|
||||||
$giteaissue=$this->giteaservice->getIssue($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"],$scrumissue->getGiteanumber());
|
|
||||||
$fgscrumupdate=true;
|
|
||||||
$this->majissue($scrumissue,$giteaissue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if($fgscrumupdate) {
|
if($fgscrumupdate) {
|
||||||
$scrum->setUpdatedate($this->datescrumupdate);
|
// Convertir les objets DateTime en timestamps
|
||||||
$this->_em->persist($scrum);
|
$timestamps = array_map(function($date) {
|
||||||
|
return $date->getTimestamp();
|
||||||
|
}, $updatedates);
|
||||||
|
|
||||||
|
// Trouver le timestamp le plus récent
|
||||||
|
$mostRecentTimestamp = max($timestamps);
|
||||||
|
|
||||||
|
// Créer une nouvelle instance de DateTime à partir du timestamp le plus récent
|
||||||
|
$mostRecentDate = (new \DateTime())->setTimestamp($mostRecentTimestamp);
|
||||||
|
|
||||||
|
// Mettre à jour la date update du scrum
|
||||||
|
$scrum->setUpdatedate($mostRecentDate);
|
||||||
$this->_em->flush();
|
$this->_em->flush();
|
||||||
|
|
||||||
|
// Temps d'execution
|
||||||
|
$this->showtime(false,"Mettre à jour le scrum");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function majissue($scrumissue,$giteaissue) {
|
public function majissue($scrumissue,$giteaissue,$issubmit) {
|
||||||
if($scrumissue->getGiteajson()["updated_at"]>$this->datescrumupdate)
|
|
||||||
$this->datescrumupdate=$scrumissue->getGiteajson()["updated_at"];
|
|
||||||
|
|
||||||
$scrumissue->setGiteanumber($giteaissue->number);
|
$scrumissue->setGiteanumber($giteaissue->number);
|
||||||
$scrumissue->setGiteastate($giteaissue->state);
|
$scrumissue->setGiteastate($giteaissue->state);
|
||||||
$scrumissue->setGiteatitle($giteaissue->title);
|
$scrumissue->setGiteatitle($giteaissue->title);
|
||||||
|
|
||||||
if($giteaissue->milestone) {
|
if($giteaissue->milestone) {
|
||||||
$scrumissue->setGiteamilestone($giteaissue->milestone->id);
|
$scrumissue->setGiteamilestone($giteaissue->milestone->id);
|
||||||
$scrumissue->setGiteamilestonename($giteaissue->milestone->title);
|
$scrumissue->setGiteamilestonename($giteaissue->milestone->title);
|
||||||
|
@ -199,6 +293,27 @@ class ScrumRepository extends ServiceEntityRepository
|
||||||
}
|
}
|
||||||
$scrumissue->setGiteajson(json_decode(json_encode($giteaissue), true));
|
$scrumissue->setGiteajson(json_decode(json_encode($giteaissue), true));
|
||||||
|
|
||||||
|
// Si le ticket est lié à un sprint on s'assure que ce sprint est bien lié au milestone du ticket
|
||||||
|
if($scrumissue->getScrumsprint()) {
|
||||||
|
if($scrumissue->getScrumsprint()->getGiteamilestone()!=$scrumissue->getGiteamilestone()) {
|
||||||
|
$scrumissue->setScrumsprint(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$issueblock=$this->giteaservice->getissueblocks($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber());
|
||||||
|
if($issueblock&&!empty($issueblock)) {
|
||||||
|
$idblock=$issueblock[0]->number;
|
||||||
|
if(!$scrumissue->getScrumissueblock()||$scrumissue->getScrumissueblock()->getGiteanumber()!=$idblock) {
|
||||||
|
$scrumissueblock=$this->_em->getRepository('App:Scrumissue')->findOneBy(["scrum"=>$scrumissue->getScrum(),"giteanumber"=>$idblock]);
|
||||||
|
$scrumissue->setScrumissueblock($scrumissueblock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif(empty($issueblock)&&$scrumissue->getScrumissueblock()) {
|
||||||
|
$scrumissue->setScrumissueblock(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$this->_em->persist($scrumissue);
|
$this->_em->persist($scrumissue);
|
||||||
$this->_em->flush();
|
$this->_em->flush();
|
||||||
|
|
||||||
|
@ -223,4 +338,18 @@ class ScrumRepository extends ServiceEntityRepository
|
||||||
$this->_em->persist($scrumissue);
|
$this->_em->persist($scrumissue);
|
||||||
$this->_em->flush();
|
$this->_em->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getMaxDate(\DateTime ...$dates): \DateTime {
|
||||||
|
// Initialiser la date maximale avec la première date de la liste
|
||||||
|
$maxDate = $dates[0];
|
||||||
|
|
||||||
|
// Comparer chaque date avec la date maximale actuelle
|
||||||
|
foreach ($dates as $date) {
|
||||||
|
if ($date > $maxDate) {
|
||||||
|
$maxDate = $date;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $maxDate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,14 +33,56 @@ class giteaService
|
||||||
|
|
||||||
|
|
||||||
$response=$this->api("POST",$apiurl,$body);
|
$response=$this->api("POST",$apiurl,$body);
|
||||||
|
|
||||||
if(!$response||$response->code!="200") return false;
|
if(!$response||$response->code!="200") return false;
|
||||||
else {
|
else {
|
||||||
$this->session->set('giteatoken', $response->body->access_token);
|
$this->session->set('giteatoken', $response->body->access_token);
|
||||||
|
$this->session->set('gitearefreshtoken', $response->body->refresh_token);
|
||||||
|
|
||||||
|
$date = new \DateTime();
|
||||||
|
$date->modify('+'.$response->body->expires_in.' seconds');
|
||||||
|
$this->session->set('gitearefreshdate',$date);
|
||||||
|
|
||||||
return $response->body->access_token;
|
return $response->body->access_token;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function refreshtoken() {
|
||||||
|
$apiurl = $this->params->get("oauthTokenurl");
|
||||||
|
$query= [
|
||||||
|
"client_id" => $this->params->get("oauthClientid"),
|
||||||
|
"client_secret" => $this->params->get("oauthClientsecret"),
|
||||||
|
"code" => $this->session->get("giteacode"),
|
||||||
|
"grant_type" => "refresh_token",
|
||||||
|
"refresh_token" => $this->session->get('gitearefreshtoken'),
|
||||||
|
];
|
||||||
|
$body = \Unirest\Request\Body::json($query);
|
||||||
|
|
||||||
|
|
||||||
|
$response=$this->api("POST",$apiurl,$body);
|
||||||
|
if(!$response||$response->code!="200") return false;
|
||||||
|
else {
|
||||||
|
$this->session->set('giteatoken', $response->body->access_token);
|
||||||
|
$this->session->set('gitearefreshtoken', $response->body->refresh_token);
|
||||||
|
|
||||||
|
$date = new \DateTime();
|
||||||
|
$date->modify('+'.$response->body->expires_in.' seconds');
|
||||||
|
$this->session->set('gitearefreshdate',$date);
|
||||||
|
|
||||||
|
return $response->body->access_token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function needrefresh() {
|
||||||
|
$date = new \DateTime();
|
||||||
|
|
||||||
|
// On refresh 15 minutes avant le terme
|
||||||
|
$refreshdate=clone $this->session->get('gitearefreshdate');
|
||||||
|
$refreshdate->modify('-900 seconds');
|
||||||
|
|
||||||
|
if($date>$refreshdate) return $this->refreshtoken();
|
||||||
|
else return $this->session->get('giteatoken');
|
||||||
|
}
|
||||||
|
|
||||||
public function deletetoken($username) {
|
public function deletetoken($username) {
|
||||||
$apiurl=$this->url."/users/".$username."/tokens/".$this->session->get("giteatoken");
|
$apiurl=$this->url."/users/".$username."/tokens/".$this->session->get("giteatoken");
|
||||||
$response=$this->api("DELETE",$apiurl,null,$this->session->get("giteatoken"));
|
$response=$this->api("DELETE",$apiurl,null,$this->session->get("giteatoken"));
|
||||||
|
@ -61,7 +103,7 @@ class giteaService
|
||||||
$response=$this->api("POST",$apiurl,$body,$this->session->get("giteatoken"));
|
$response=$this->api("POST",$apiurl,$body,$this->session->get("giteatoken"));
|
||||||
if(!$response||$response->code!="200") return false;
|
if(!$response||$response->code!="200") return false;
|
||||||
else {
|
else {
|
||||||
$response->body= str_replace($this->giteaUrl,$this->giteaUrl.$context,$response->body);
|
//$response->body= str_replace($this->giteaUrl,$this->giteaUrl.$context,$response->body);
|
||||||
return $response->body;
|
return $response->body;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,6 +223,13 @@ class giteaService
|
||||||
else return $response->body;
|
else return $response->body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getassignees($owner,$name) {
|
||||||
|
$apiurl = $this->url."/repos/$owner/$name/assignees";
|
||||||
|
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
|
||||||
|
if(!$response||$response->code!="200") return false;
|
||||||
|
else return $response->body;
|
||||||
|
}
|
||||||
|
|
||||||
public function getcollaborators($owner,$name) {
|
public function getcollaborators($owner,$name) {
|
||||||
$apiurl = $this->url."/repos/$owner/$name/collaborators";
|
$apiurl = $this->url."/repos/$owner/$name/collaborators";
|
||||||
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
|
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
|
||||||
|
@ -202,9 +251,15 @@ class giteaService
|
||||||
else return $response->body;
|
else return $response->body;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getissues($owner,$name,$state="?state=open") {
|
public function getmilestone($owner,$name,$id) {
|
||||||
$apiurl = $this->url."/repos/$owner/$name/issues".$state;
|
$apiurl = $this->url."/repos/$owner/$name/milestones/".$id;
|
||||||
|
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
|
||||||
|
if(!$response||$response->code!="200") return false;
|
||||||
|
else return $response->body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getissues($owner,$name,$state="?state=open") {
|
||||||
|
$apiurl = $this->url."/repos/$owner/$name/issues".$state.($state==""?"?":"&")."type=issues";
|
||||||
$page=1;
|
$page=1;
|
||||||
$limit=20;
|
$limit=20;
|
||||||
$issues=[];
|
$issues=[];
|
||||||
|
@ -268,7 +323,6 @@ class giteaService
|
||||||
else return $response->body;
|
else return $response->body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getissuetimelines($owner,$name,$index) {
|
public function getissuetimelines($owner,$name,$index) {
|
||||||
$apiurl = $this->url."/repos/$owner/$name/issues/$index/timeline";
|
$apiurl = $this->url."/repos/$owner/$name/issues/$index/timeline";
|
||||||
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
|
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
|
||||||
|
@ -276,13 +330,44 @@ class giteaService
|
||||||
else return $response->body;
|
else return $response->body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getissueblocks($owner,$name,$index) {
|
||||||
|
$apiurl = $this->url."/repos/$owner/$name/issues/$index/blocks";
|
||||||
|
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
|
||||||
|
if(!$response||$response->code!="200") return false;
|
||||||
|
else return $response->body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function postissueblocks($owner,$name,$index,$toblock) {
|
||||||
|
$apiurl = $this->url."/repos/$owner/$name/issues/$index/blocks";
|
||||||
|
$query= ["index" => $toblock,"owner" => $owner, "repo" => $name];
|
||||||
|
$body = \Unirest\Request\Body::json($query);
|
||||||
|
$body=str_replace('"'.$toblock.'"',$toblock,$body);
|
||||||
|
$response=$this->api("POST",$apiurl,$body,$this->session->get("giteatoken"));
|
||||||
|
if(!$response||($response->code!="200"&&$response->code!="201")) return false;
|
||||||
|
else return $response->body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteissueblocks($owner,$name,$index,$toblock) {
|
||||||
|
$apiurl = $this->url."/repos/$owner/$name/issues/$index/blocks";
|
||||||
|
$query= ["index" => $toblock,"owner" => $owner, "repo" => $name];
|
||||||
|
$body = \Unirest\Request\Body::json($query);
|
||||||
|
$body=str_replace('"'.$toblock.'"',$toblock,$body);
|
||||||
|
$response=$this->api("DELETE",$apiurl,$body,$this->session->get("giteatoken"));
|
||||||
|
if(!$response||$response->code!="201") return false;
|
||||||
|
else return $response->body;
|
||||||
|
}
|
||||||
|
|
||||||
private function api($method,$url,$query,$token=null) {
|
private function api($method,$url,$query,$token=null) {
|
||||||
// Entete
|
// Entete
|
||||||
$headers = [
|
$headers = [
|
||||||
'Accept' => 'application/json',
|
'Accept' => 'application/json',
|
||||||
'Content-Type' => 'application/json',
|
'Content-Type' => 'application/json',
|
||||||
];
|
];
|
||||||
if($token) $headers["Authorization"]="token ".$token;
|
|
||||||
|
if($token) {
|
||||||
|
$token=$this->needrefresh();
|
||||||
|
$headers["Authorization"]="token ".$token;
|
||||||
|
}
|
||||||
|
|
||||||
// Paramétrage unirest
|
// Paramétrage unirest
|
||||||
\Unirest\Request::verifyPeer(false);
|
\Unirest\Request::verifyPeer(false);
|
||||||
|
|
|
@ -3,6 +3,7 @@ namespace App\Twig;
|
||||||
|
|
||||||
use Twig\Extension\AbstractExtension;
|
use Twig\Extension\AbstractExtension;
|
||||||
use Twig\TwigFilter;
|
use Twig\TwigFilter;
|
||||||
|
use Twig\TwigFunction;
|
||||||
|
|
||||||
class AppExtension extends AbstractExtension
|
class AppExtension extends AbstractExtension
|
||||||
{
|
{
|
||||||
|
@ -15,6 +16,13 @@ class AppExtension extends AbstractExtension
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFunctions()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new TwigFunction('microtime', [$this, 'getMicrotime']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function urlAvatar($avatar)
|
public function urlAvatar($avatar)
|
||||||
{
|
{
|
||||||
if(stripos($avatar,"http")===0)
|
if(stripos($avatar,"http")===0)
|
||||||
|
@ -23,6 +31,11 @@ class AppExtension extends AbstractExtension
|
||||||
return $this->container->getParameter("appAlias")."uploads/avatar/".$avatar;
|
return $this->container->getParameter("appAlias")."uploads/avatar/".$avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMicrotime($asFloat = true)
|
||||||
|
{
|
||||||
|
return microtime($asFloat);
|
||||||
|
}
|
||||||
|
|
||||||
public function setContainer($container)
|
public function setContainer($container)
|
||||||
{
|
{
|
||||||
$this->container = $container;
|
$this->container = $container;
|
||||||
|
|
|
@ -102,7 +102,7 @@
|
||||||
resizewidth=$('#largeimg').width();
|
resizewidth=$('#largeimg').width();
|
||||||
|
|
||||||
$('#largeimg').CropSelectJs({
|
$('#largeimg').CropSelectJs({
|
||||||
imageSrc: "/{{ appAlias }}/uploads/{{type}}/{{ file }}",
|
imageSrc: "{{ asset("uploads/"~type~"/"~file) }}",
|
||||||
selectionResize: function(data) { resize(data); },
|
selectionResize: function(data) { resize(data); },
|
||||||
selectionMove: function(data) { move(data); },
|
selectionMove: function(data) { move(data); },
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,6 +33,8 @@ function ModalLoad(idmodal,title,path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{% if wssuse %}
|
{% if wssuse %}
|
||||||
|
console.log("pouet");
|
||||||
|
|
||||||
function subscribe(channeltype,channelkey,userkey) {
|
function subscribe(channeltype,channelkey,userkey) {
|
||||||
console.log("== SUBSCRIBE "+channeltype+"-"+channelkey+" with userkey "+userkey);
|
console.log("== SUBSCRIBE "+channeltype+"-"+channelkey+" with userkey "+userkey);
|
||||||
conn.send(JSON.stringify({
|
conn.send(JSON.stringify({
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
--colorfttitlelight-darker: {{ app.session.get('colorfttitlelight-darker')|raw }};
|
--colorfttitlelight-darker: {{ app.session.get('colorfttitlelight-darker')|raw }};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
/* COLOR BODY */
|
/* COLOR BODY */
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
{% for comment in issue.comments %}
|
{% for comment in issue.comments %}
|
||||||
<h3 class='mt-3'>{{comment.user.login}} le {{comment.created_at|date("d/m/Y H:i")}}</h3>
|
<h3 class='mt-3'>{{comment.user.login}} le {{comment.created_at|date("d/m/Y H:i")}}</h3>
|
||||||
<div class='card card-body'>
|
<div class='card card-body'>
|
||||||
{{comment.body|markdown_to_html}}
|
{{comment.body|raw}}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -86,7 +86,7 @@
|
||||||
<div class='card card-body mb-3'>
|
<div class='card card-body mb-3'>
|
||||||
|
|
||||||
{% for timeline in issue.timelines %}
|
{% for timeline in issue.timelines %}
|
||||||
{% if timeline.type!="comment" and timeline.type!="project" and timeline.type!="added_deadline" and timeline.type!="modified_deadline"%}
|
{% if timeline.type!="comment" and timeline.type!="project" and timeline.type!="added_deadline" and timeline.type!="modified_deadline" and timeline.type!="label" %}
|
||||||
<li><b>{{timeline.user.login}} le {{timeline.created_at|date("d/m/Y H:i")}}</b><br>
|
<li><b>{{timeline.user.login}} le {{timeline.created_at|date("d/m/Y H:i")}}</b><br>
|
||||||
|
|
||||||
{% if timeline.type == "change_title" %}
|
{% if timeline.type == "change_title" %}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
{% extends "base.html.twig" %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
{% set statut="" %}
|
||||||
|
{% set milestone="" %}
|
||||||
|
{% for issue in issues %}
|
||||||
|
{% if statut!=issue.statut %}
|
||||||
|
<p> </p>
|
||||||
|
<h2>{{issue.statut}}</h2>
|
||||||
|
{% set statut=issue.statut %}
|
||||||
|
{% set milestone="" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if milestone!=issue.milestone %}
|
||||||
|
<p> </p>
|
||||||
|
<h3>{{issue.milestone}}</h3>
|
||||||
|
{% set milestone=issue.milestone %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<li>{{issue.id}} = {{ issue.title }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="card">
|
<div class="card mb-3">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<i class="fa fa-pencil-alt fa-fw"></i> Informations
|
<i class="fa fa-pencil-alt fa-fw"></i> Informations
|
||||||
</div>
|
</div>
|
||||||
|
@ -57,6 +57,26 @@
|
||||||
{{ form_row(form.users) }}
|
{{ form_row(form.users) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% if mode=="update" %}
|
||||||
|
<div class="card mb-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<i class="fa fa-pencil-alt fa-fw"></i> Sprints
|
||||||
|
<button id="addsprint" type="button" class="btn float-right fa fa-plus"></button>
|
||||||
|
|
||||||
|
<div class="custom-control custom-switch float-right">
|
||||||
|
<input type="checkbox" class="custom-control-input" id="viewsprintclosed">
|
||||||
|
<label class="custom-control-label" for="viewsprintclosed">Afficher les sprint clos</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="scrumsprints" class="card-body">
|
||||||
|
<ol id="scrumsprints" class="list-group list-group-numbered">
|
||||||
|
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if mode=="update" %}
|
{% if mode=="update" %}
|
||||||
|
@ -185,6 +205,23 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="mymodalsprint" class="modal" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title"></h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<iframe frameborder=0 width="100%" height="600px"></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block localjavascript %}
|
{% block localjavascript %}
|
||||||
|
@ -196,6 +233,7 @@
|
||||||
loadscrumteams();
|
loadscrumteams();
|
||||||
loadscrumprioritys();
|
loadscrumprioritys();
|
||||||
loadscrumtypes();
|
loadscrumtypes();
|
||||||
|
loadscrumsprints();
|
||||||
{%endif%}
|
{%endif%}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -376,6 +414,85 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$("#addsprint").click(function() {
|
||||||
|
ModalLoad('mymodalsprint','Ajouter un sprint','{{path('app_scrumsprint_submit',{scrumid:scrum.id})}}');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#scrumsprints').on('click', '.modsprint', function(event) {
|
||||||
|
url="{{path('app_scrumsprint_update',{id:'xxx'})}}";
|
||||||
|
url=url.replace("xxx",$(this).data("id"));
|
||||||
|
ModalLoad('mymodalsprint','Modifier un sprint',url);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#mymodalsprint').on('hidden.bs.modal', function () {
|
||||||
|
loadscrumsprints();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#viewsprintclosed').change(function() {
|
||||||
|
if(this.checked) {
|
||||||
|
$(".sprintclosed").removeClass("hidden");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(".sprintclosed").addClass("hidden");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function loadscrumsprints() {
|
||||||
|
$("#scrumsprints").empty();
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumsprint_select",{scrumid:scrum.id})}}",
|
||||||
|
success: function(datas, dataType)
|
||||||
|
{
|
||||||
|
jQuery.each(datas, function(i, wid) {
|
||||||
|
style='';
|
||||||
|
classname='';
|
||||||
|
if(wid.closed) {
|
||||||
|
style='background-color:#cdcdcd;';
|
||||||
|
classname='sprintclosed';
|
||||||
|
if(!$("#viewsprintclosed").is(':checked')) {
|
||||||
|
classname+=' hidden';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html ='<li data-id="'+wid.id+'" class="list-group-item d-flex justify-content-between '+classname+'" style="'+style+'">';
|
||||||
|
html+='<div>';
|
||||||
|
html+='<div class="mr-3 p-2 d-inline-block"><i class="fas fa-arrows-alt-v fa-2x"></i></div>';
|
||||||
|
html+='<div class="d-inline-block">';
|
||||||
|
html+=wid.name;
|
||||||
|
html+='</div>';
|
||||||
|
html+='</div>';
|
||||||
|
html+='<button type="button" data-id="'+wid.id+'" class="modsprint btn float-right fa fa-file"></button>';
|
||||||
|
html+='</li>';
|
||||||
|
$("#scrumsprints").append(html);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$( "#scrumsprints" ).sortable({
|
||||||
|
axis: "y",
|
||||||
|
handle: ".fa-arrows-alt-v",
|
||||||
|
update: function( event, ui ) {
|
||||||
|
lstordered="";
|
||||||
|
$( "#scrumsprints li" ).each(function( index ) {
|
||||||
|
if(index==0) lstordered=$(this).data("id");
|
||||||
|
else lstordered=lstordered+","+$(this).data("id");
|
||||||
|
});
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumsprint_order",{scrumid:scrum.id})}}",
|
||||||
|
data: {
|
||||||
|
lstordered:lstordered
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$("#addtype").click(function() {
|
$("#addtype").click(function() {
|
||||||
ModalLoad('mymodaltype','Ajouter une colonne','{{path('app_scrumtype_submit',{scrumid:scrum.id})}}');
|
ModalLoad('mymodaltype','Ajouter une colonne','{{path('app_scrumtype_submit',{scrumid:scrum.id})}}');
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,264 @@
|
||||||
|
{% extends "base.html.twig" %}
|
||||||
|
|
||||||
|
{% block localstyle %}
|
||||||
|
.issuecontent {
|
||||||
|
width:75%;
|
||||||
|
}
|
||||||
|
.issuedetail {
|
||||||
|
width:25%;
|
||||||
|
padding-right: 10px;
|
||||||
|
zoom:80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-small {
|
||||||
|
font-size:80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header, .card-body {
|
||||||
|
padding:10px;
|
||||||
|
background-color: var(--colorbgbodylight-darker);
|
||||||
|
}
|
||||||
|
|
||||||
|
.issue-body {
|
||||||
|
zoom: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
color: white;
|
||||||
|
zoom:120%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
<h3 id='issuetitle{{issue.number}}' class='issuetitle'>#{{issue.number}} = {{issue.title}}</h3>
|
||||||
|
|
||||||
|
<div id='issuediv{{issue.number}}' class='d-flex'>
|
||||||
|
<div class='issuecontent' class='d-flex flex-column'>
|
||||||
|
|
||||||
|
<div class="card mb-3">
|
||||||
|
<div class="card-header d-flex">
|
||||||
|
<div class="flex-grow-1">{{issue.user.login}}</div>
|
||||||
|
<div class="text-small"> le {{issue.created_at|date("d/m/Y H:i")}}</div>
|
||||||
|
</div>
|
||||||
|
<div class='card-body issue-body'>
|
||||||
|
{{issue.body|raw}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if issue.comments %}
|
||||||
|
{% for comment in issue.comments %}
|
||||||
|
<div class="card mb-3">
|
||||||
|
<div class="card-header d-flex">
|
||||||
|
<div class="flex-grow-1">{{comment.user.login}}</div>
|
||||||
|
<div class="text-small"> le {{comment.created_at|date("d/m/Y H:i")}}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='card-body issue-body'>
|
||||||
|
{{comment.body|raw}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='pl-3 issuedetail'>
|
||||||
|
<a target="_blank" class="btn btn-success w-100 mb-3" href="{{issue.html_url}}" style="zoom:120%">Modifier dans Gitea</a>
|
||||||
|
|
||||||
|
<div class="card mb-3">
|
||||||
|
<div class="modissu card-header d-flex" style="cursor:pointer">
|
||||||
|
<div class="flex-grow-1"><i class="fas fa-weight-hanging"></i></div>
|
||||||
|
<div>{{ issue.weight }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='card mb-3'>
|
||||||
|
<div class="card-header">Statut</div>
|
||||||
|
<div class="card-body">
|
||||||
|
{% if issue.closed_at %}
|
||||||
|
Clos le {{issue.closed_at|date("d/m/Y H:i")}}
|
||||||
|
{% else %}
|
||||||
|
{{issue.statuslife}}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='card mb-3'>
|
||||||
|
<div class="card-header">Jalon</div>
|
||||||
|
<div class="card-body">
|
||||||
|
{% if issue.milestone %}
|
||||||
|
{{ issue.milestone.title|raw }}
|
||||||
|
{% else %}
|
||||||
|
Backlog
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if issue.sprint %}
|
||||||
|
<div class='card mb-3'>
|
||||||
|
<div class="card-header">Sprint</div>
|
||||||
|
<div class="card-body">
|
||||||
|
{{ issue.sprint }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if issue.refs %}
|
||||||
|
<div class='card mb-3'>
|
||||||
|
<div class="card-header">Références</div>
|
||||||
|
<div class='card-body mb-3'>
|
||||||
|
{% for histo in issue.refs %}
|
||||||
|
<div>
|
||||||
|
{{histo.label|raw}}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if issue.labels %}
|
||||||
|
<div class='card mb-3'>
|
||||||
|
<div class="card-header">Labels</div>
|
||||||
|
<div class='card-body mb-3'>
|
||||||
|
{% for label in issue.labels %}
|
||||||
|
<span class='badge mr-1 mb-1 p-2' style='background-color:#{{label.color}}'>{{label.name}}</span>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for histo in issue.labelhistos %}
|
||||||
|
<div class="mt-1">
|
||||||
|
<b>{{histo.user.login}} le {{histo.created_at|date("d/m/Y H:i")}}</b><br>
|
||||||
|
{{histo.label|raw}}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if issue.timelines %}
|
||||||
|
<div class='card mb-3'>
|
||||||
|
<div class="card-header">Historique</div>
|
||||||
|
<div class="card-body">
|
||||||
|
{% for timeline in issue.timelines %}
|
||||||
|
{% if timeline.type!="label" and timeline.type!="comment" and timeline.type!="project" and timeline.type!="added_deadline" and timeline.type!="modified_deadline"%}
|
||||||
|
<li><b>{{timeline.user.login}} le {{timeline.created_at|date("d/m/Y H:i")}}</b><br>
|
||||||
|
|
||||||
|
{% if timeline.type == "change_title" %}
|
||||||
|
<div class='pl-4'>Modification titre de <i>{{timeline.old_title}}</i> à <i>{{timeline.new_title}}</i></div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "milestone" %}
|
||||||
|
{% if timeline.milestone %}
|
||||||
|
<div class='pl-4'>Affectation au Jalon <i>{{timeline.milestone.title}}</i></div>
|
||||||
|
{% else %}
|
||||||
|
<div class='pl-4'>Suppression du Jalon</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% elseif timeline.type == "comment_ref" or timeline.type == "pull_ref" or timeline.type == "issue_ref" %}
|
||||||
|
<div class='pl-4'>Référencé le ticket <i>#{{timeline.ref_issue.number}} - {{timeline.ref_issue.title}}</i></div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "add_dependency" %}
|
||||||
|
<div class='pl-4'>Ajouté dépendance au ticket <i>#{{timeline.dependent_issue.number}} - {{timeline.dependent_issue.title}}</i></div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "remove_dependency" %}
|
||||||
|
<div class='pl-4'>Supprimé dépendance au ticket <i>#{{timeline.dependent_issue.number}} - {{timeline.dependent_issue.title}}</i></div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "pull_push" %}
|
||||||
|
<div class='pl-4'>Ajout révision</i></div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "assignees" %}
|
||||||
|
<div class='pl-4'>Affecté intervenant <i>{{timeline.assignee.login}}</i></div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "commit_ref" %}
|
||||||
|
<div class='pl-4'>Référencé depuis commit <i>#{{timeline.body|replace({'href="/':'target="_blank" href="'~giteaUrl~'/'})|raw}}</i></div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "merge_pull" %}
|
||||||
|
<div class='pl-4'>Révision fusionnée</div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "delete_branch" %}
|
||||||
|
<div class='pl-4'>Suppression branche {{timeline.old_ref|raw}}</div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "close" %}
|
||||||
|
<div class='pl-4'>Clos <i>Fermeture du ticket</i></div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "review" %}
|
||||||
|
<div class='pl-4'>Revue acceptée</div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "review_request" %}
|
||||||
|
<div class='pl-4'>Demande de révision</div>
|
||||||
|
|
||||||
|
{% elseif timeline.type == "reopen" %}
|
||||||
|
<div class='pl-4'>Réouverture du ticket</div>
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{{ dump(timeline) }}
|
||||||
|
{%endif%}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="mymodalissue" class="modal" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title">Estimation</h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group ">
|
||||||
|
<label class="control-label required" for="issu_weight">
|
||||||
|
Poid
|
||||||
|
</label>
|
||||||
|
<input type="hidden" id="modal-issueid" name="modal-issueid" required="required" class=" form-control" value="">
|
||||||
|
<input type="number" placeholder="0.0" step="0.1" id="modal-issueweight" name="modal-issueweight" required="required" class=" form-control" value="">
|
||||||
|
</div>
|
||||||
|
<button id="issu_update" class="btn btn-success">Enregistrer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block localjavascript %}
|
||||||
|
$(document).on('click','.modissu',function(){
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumissue_info")}}",
|
||||||
|
data: {
|
||||||
|
id:{{issue.nineid}},
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
$("#modal-issueweight").val(data.weight);
|
||||||
|
$("#mymodalissue").modal('show');
|
||||||
|
$("#modal-issueweight").focus();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#issu_update").click(function(){
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumissue_update")}}",
|
||||||
|
data: {
|
||||||
|
id:{{issue.nineid}},
|
||||||
|
weight:$("#modal-issueweight").val(),
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
parent.$(".issue{{issue.nineid}}-weight").html($("#modal-issueweight").val());
|
||||||
|
window.parent.refreshinfo();
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function (request, status, error) {
|
||||||
|
$("#mymodalissue").modal('hide');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<h1>{{scrum.name}}</h1>
|
||||||
|
|
||||||
|
<div class="form-group ">
|
||||||
|
<label class="control-label required" for="scrum_category">
|
||||||
|
Le ticket n°
|
||||||
|
<span class="mandatory">*</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<select id="issue" class="form-control">
|
||||||
|
<option value="" selected></option>
|
||||||
|
{% for issue in scrum.scrumissues %}
|
||||||
|
<option value="{{issue.id}}">#{{issue.giteanumber}} = {{issue.giteatitle}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group ">
|
||||||
|
<label class="control-label required" for="scrum_category">
|
||||||
|
bloque / débloque le ticket n°
|
||||||
|
<span class="mandatory">*</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<select id="block" class="form-control">
|
||||||
|
<option value="" selected></option>
|
||||||
|
{% for issue in scrum.scrumissues %}
|
||||||
|
<option value="{{issue.giteanumber}}">#{{issue.giteanumber}} = {{issue.giteatitle}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button onClick="lock()" class="btn btn-success">Bloque</button>
|
||||||
|
<button onClick="unlock()" class="btn btn-success">Débloque</button>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block localjavascript %}
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#issue").select2();
|
||||||
|
$("#block").select2();
|
||||||
|
});
|
||||||
|
|
||||||
|
function lock() {
|
||||||
|
console.log($("#issue").val());
|
||||||
|
console.log($("#block").val());
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumissue_block")}}",
|
||||||
|
data: {
|
||||||
|
id:$("#issue").val(),
|
||||||
|
issueblocked:$("#block").val(),
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function unlock() {
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumissue_unblock")}}",
|
||||||
|
data: {
|
||||||
|
id:$("#issue").val(),
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
{% endblock %}
|
|
@ -5,10 +5,9 @@
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="d-flex justify-content-start mt-3">
|
<div class="d-flex justify-content-start mt-3">
|
||||||
|
|
||||||
<div class="pr-2">
|
<div class="pr-2">
|
||||||
{% if app.user and is_granted('ROLE_MASTER') %}
|
{% if app.user and is_granted('ROLE_MASTER') %}
|
||||||
<a class="btn btn-success btn-sm mt-2" href={{ path('app_scrum_submit') }}><i class="fa fa-plus mr-2"></i>Ajouter un Scrum</a>
|
<a class="btn btn-success btn-sm d-flex" style="height:69px; justify-content: center; flex-direction: column" href={{ path('app_scrum_submit') }}><i class="fa fa-plus mr-2"></i>Ajouter un Scrum</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -47,7 +46,7 @@
|
||||||
<tr data-category="{{scrum.category}}" data-repo="{{scrum.giteaid}}">
|
<tr data-category="{{scrum.category}}" data-repo="{{scrum.giteaid}}">
|
||||||
<td>
|
<td>
|
||||||
<a href="{{path('app_scrum_view',{id:scrum.id})}}"><i class="fas fa-columns fa-2x mr-1"></i></a>
|
<a href="{{path('app_scrum_view',{id:scrum.id})}}"><i class="fas fa-columns fa-2x mr-1"></i></a>
|
||||||
<a href="{{path('app_issuescrum',{id:scrum.id})}}"><i class="fas fa-ticket-alt fa-2x mr-1"></i></a>
|
<a href="{{path('app_scrum_table',{id:scrum.id})}}"><i class="fas fa-ticket-alt fa-2x mr-1"></i></a>
|
||||||
<a href="{{path('app_scrum_stat',{id:scrum.id})}}"><i class="fas fa-chart-area fa-2x mr-1"></i></a>
|
<a href="{{path('app_scrum_stat',{id:scrum.id})}}"><i class="fas fa-chart-area fa-2x mr-1"></i></a>
|
||||||
|
|
||||||
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_MODO') or is_granted('ROLE_MASTER') %}
|
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_MODO') or is_granted('ROLE_MASTER') %}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
.flot-chart-subcontent {
|
.flot-chart-subcontent {
|
||||||
height: 200px;
|
height: 200px;
|
||||||
width: 40%;
|
width: 350px;
|
||||||
}
|
}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -37,51 +37,78 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div style="width:100%" class="mt-3">
|
<div style="width:100%" class="mt-3">
|
||||||
<label class="control-label" style="color:var(--colorftbodydark)">Filtre EQUIPES</label>
|
<label class="control-label" style="color:var(--colorftbodydark)">Filtre SPRINT</label>
|
||||||
<select id="filterteams" multiple="multiple" class="form-control">
|
<select id="filtersprints" multiple="multiple" class="form-control">
|
||||||
{% for team in scrum.scrumteams %}
|
{% for sprint in sprints %}
|
||||||
<option value="{{team.giteaid}}">{{team.name}}</option>
|
<option value="{{sprint.giteamilestone~"-"~sprint.id}}">{{sprint.giteamilestonename}}-{{sprint.name}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
{% for giteamilestone in giteamilestones %}
|
||||||
|
<option value="{{giteamilestone.id~"--100"}}">{{giteamilestone.title}}-Aucun</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style="width:100%" class="mt-3">
|
||||||
|
<div class="custom-control custom-switch">
|
||||||
|
<input type="checkbox" class="custom-control-input" id="filterbynumber">
|
||||||
|
<label class="custom-control-label" for="filterbynumber" style="color:var(--colorfttitledark);">Vue par {{ (filterbynumber=="true"?"nombre":"poids") }} de tickets</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pl-3" style="width:100%;">
|
<div class="pl-3" style="width:100%;">
|
||||||
<div class="mt-4 mb-3" style="zoom:80%">
|
<div class="mt-4 mb-3" style="zoom:80%">
|
||||||
<button class="btn btn-success" onClick="showFilters()"><i class="fas fa-filter"></i></button>
|
<button class="btn btn-success" onClick="showFilters()"><i class="fas fa-filter"></i></button>
|
||||||
<a class="btn btn-success" href="{{path('app_scrum_view',{id:scrum.id})}}"><i class="fas fa-columns"></i></a>
|
<a class="btn btn-success" href="{{path('app_scrum_view',{id:scrum.id})}}"><i class="fas fa-columns"></i></a>
|
||||||
<a class="btn btn-success" href="{{path('app_issuescrum',{id:scrum.id})}}"><i class="fas fa-ticket-alt"></i></a>
|
<a class="btn btn-success" href="{{path('app_scrum_table',{id:scrum.id})}}"><i class="fas fa-ticket-alt"></i></a>
|
||||||
<span id="textfilters"></span>
|
<span id="textfilters"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1>{{ scrum.name }}</h1>
|
<h1>{{ scrum.name }}</h1>
|
||||||
|
|
||||||
<div class="d-flex flex-column mt-4">
|
<div id="tbestim" class="d-flex flex-column mt-4">
|
||||||
{% for milestone in tbstat %}
|
|
||||||
<div class="flot-chart mr-4" data-milestone="{{ milestone.id }}">
|
|
||||||
<h4>{{milestone.name}}</h4>
|
|
||||||
<div class="mt-4">
|
|
||||||
<div id="floatdonut{{ milestone.id }}" class="flot-chart-content" style="float:left"></div>
|
|
||||||
<div class="mt-3 pb-3" style="width:100%">
|
|
||||||
|
|
||||||
<div class="d-flex justify-content-between mt-4">
|
{% for jalon in tbestim %}
|
||||||
{% for column in milestone.stat %}
|
{% if jalon.nbjrs>0 %}
|
||||||
<div style="width:250px">
|
<div class="card mb-4" data-milestone="{{ jalon.idjal }}">
|
||||||
<div style="background-color:{{column.color}}; padding:3px;margin-bottom:3px;">{{ column.label }} = {{ column.total }}</div>
|
<div class="card-header">{{jalon.nmjal}}</div>
|
||||||
<small>
|
<div class="card-body d-flex justify-content-center">
|
||||||
<div style="line-height:15px; width:100%">
|
<div class="d-flex flex-column">
|
||||||
{% for label in column.labels %}
|
<div class="ustify-content-center" style="display:flex" data-graphmilestone="{{ jalon.idjal }}">
|
||||||
<li >{{label.label}} = {{label.total}}</li>
|
<div id="floatdonut{{ jalon.idjal }}" class="flot-chart-content"></div>
|
||||||
|
<div style="min-width:250px; color: #ffffff; padding: 3px;">
|
||||||
|
{% for column in jalon.columns %}
|
||||||
|
<div style="padding: 3px; background-color:#{{column.color}}">{{column.nmcol}}<span class="float-right">{{(filterbynumber=="true"?column.nbiss:column.nbjrs)}} = {{((filterbynumber=="true"?column.nbiss:column.nbjrs) * 100 / (filterbynumber=="true"?jalon.nbiss:jalon.nbjrs))|number_format}}%</<span></div>
|
||||||
|
{% endfor %}
|
||||||
|
<div style="padding: 3px;color: #000">TOTAL<span class="float-right">{{(filterbynumber=="true"?jalon.nbiss:jalon.nbjrs)}} = 100%</<span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex flex-wrap justify-content-center">
|
||||||
|
{% for sprint in jalon.sprints %}
|
||||||
|
{% if jalon.nbjrs != sprint.nbjrs and sprint.nbjrs>0 %}
|
||||||
|
<div class="card mt-4 mr-4" data-sprint="{{ jalon.idjal~"-"~sprint.idspr }}">
|
||||||
|
<div class="card-header">{{sprint.nmspr}}</div>
|
||||||
|
<div class="card-body d-flex flex-column">
|
||||||
|
<div id="floatdonut{{ jalon.idjal~"-"~sprint.idspr }}" class="flot-chart-subcontent" style="float:left"></div>
|
||||||
|
<div class="mt-3" style="color: #ffffff;">
|
||||||
|
{% for column in sprint.columns %}
|
||||||
|
<div style="padding: 3px; background-color:#{{column.color}}">{{column.nmcol}}<span class="float-right">{{(filterbynumber=="true"?column.nbiss:column.nbjrs)}} = {{((filterbynumber=="true"?column.nbiss:column.nbjrs) * 100 / (filterbynumber=="true"?sprint.nbiss:sprint.nbjrs))|number_format}}%</<span></div>
|
||||||
|
{% endfor %}
|
||||||
|
<div style="padding: 3px;color: #000">TOTAL<span class="float-right">{{(filterbynumber=="true"?sprint.nbiss:sprint.nbjrs)}} = 100%</<span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</small>
|
|
||||||
</div>
|
|
||||||
{%endfor%}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,6 +117,25 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block localjavascript %}
|
{% block localjavascript %}
|
||||||
|
// View par nombre de tickets
|
||||||
|
{% if filterbynumber %}
|
||||||
|
$("#filterbynumber").prop( "checked", {{ filterbynumber }} )
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
$('#filterbynumber').change(function() {
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{ path('app_user_preference') }}",
|
||||||
|
data: {
|
||||||
|
key:'filterbynumber',
|
||||||
|
id:{{scrum.id}},
|
||||||
|
value: this.checked
|
||||||
|
}
|
||||||
|
}).done(function( data ) {
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function showFilters() {
|
function showFilters() {
|
||||||
if($("#filters").hasClass("d-flex")) {
|
if($("#filters").hasClass("d-flex")) {
|
||||||
toshow=0;
|
toshow=0;
|
||||||
|
@ -116,13 +162,28 @@
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// Apply Filter
|
// Apply Filter
|
||||||
function showhide() {
|
function showhide() {
|
||||||
|
// Afficher masquer les jalons
|
||||||
if($("#filtermilestones").val().length !== 0) {
|
if($("#filtermilestones").val().length !== 0) {
|
||||||
$("[data-milestone]").hide();
|
$("[data-milestone]").hide();
|
||||||
$.each($("#filtermilestones").val(), function( index, value ) {
|
$.each($("#filtermilestones").val(), function( index, value ) {
|
||||||
$("[data-milestone="+value+"]").show();
|
$("[data-milestone="+value+"]").show();
|
||||||
|
$("[data-graphmilestone="+value+"]").show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else $("[data-milestone]").show();
|
else {
|
||||||
|
$("[data-milestone]").show();
|
||||||
|
$("[data-graphmilestone]").show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Afficher masquer les sprints
|
||||||
|
if($("#filtersprints").val().length !== 0) {
|
||||||
|
$("[data-sprint]").hide();
|
||||||
|
$("[data-graphmilestone]").hide();
|
||||||
|
$.each($("#filtersprints").val(), function( index, value ) {
|
||||||
|
$("[data-sprint="+value+"]").show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if($("#filtermilestones").val().length === 0)$("[data-sprint]").show();
|
||||||
|
|
||||||
textfilters="";
|
textfilters="";
|
||||||
if($("#filtermilestones").val().length!==0) {
|
if($("#filtermilestones").val().length!==0) {
|
||||||
|
@ -134,10 +195,10 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if($("#filterteams").val().length!==0) {
|
if($("#filtersprints").val().length!==0) {
|
||||||
data = $("#filterteams").select2('data');
|
data = $("#filtersprints").select2('data');
|
||||||
textfilters=textfilters+" <b>EQUIPES</b> =";
|
textfilters=textfilters+" <b>SPRINT</b> =";
|
||||||
$.each($("#filterteams").val(), function( index, value ) {
|
$.each($("#filtersprints").val(), function( index, value ) {
|
||||||
if(index>0)textfilters=textfilters+" &";
|
if(index>0)textfilters=textfilters+" &";
|
||||||
textfilters=textfilters+" "+data[index].text;
|
textfilters=textfilters+" "+data[index].text;
|
||||||
});
|
});
|
||||||
|
@ -175,46 +236,47 @@
|
||||||
filtermilestones();
|
filtermilestones();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Filter Teams
|
// Filter Sprints
|
||||||
function filterteams() {
|
function filtersprints() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: "{{ path('app_user_preference') }}",
|
url: "{{ path('app_user_preference') }}",
|
||||||
data: {
|
data: {
|
||||||
key:'filterteams',
|
key:'filtersprints',
|
||||||
id:{{scrum.id}},
|
id:{{scrum.id}},
|
||||||
value: $("#filterteams").val()
|
value: $("#filtersprints").val()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
location.reload();
|
showhide();
|
||||||
}
|
}
|
||||||
$('#filterteams').select2();
|
|
||||||
{% if filterteams %}
|
$('#filtersprints').select2();
|
||||||
{% for team in filterteams %}
|
{% if filtersprints %}
|
||||||
$("#filterteams").val($("#filterteams").val().concat("{{team}}"));
|
{% for sprint in filtersprints %}
|
||||||
|
$("#filtersprints").val($("#filtersprints").val().concat("{{sprint}}"));
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
$('#filterteams').trigger('change');
|
$('#filtersprints').trigger('change');
|
||||||
{% endif %}
|
{% endif %}
|
||||||
$('#filterteams').on("select2:select", function(e) {
|
$('#filtersprints').on("select2:select", function(e) {
|
||||||
filterteams();
|
filtersprints();
|
||||||
});
|
});
|
||||||
$('#filterteams').on("select2:unselect", function(e) {
|
$('#filtersprints').on("select2:unselect", function(e) {
|
||||||
filterteams();
|
filtersprints();
|
||||||
});
|
});
|
||||||
|
|
||||||
{% for milestone in tbstat %}
|
{% for jalon in tbestim %}
|
||||||
var data = [
|
var data = [
|
||||||
{% for data in milestone.stat %}
|
{% for column in jalon.columns %}
|
||||||
{
|
{
|
||||||
label: "{{ data.label}}",
|
label: "{{ column.nmcol}}",
|
||||||
data: {{ data.total }},
|
data: {{ column.nbiss }},
|
||||||
color: "{{ data.color }}",
|
color: "#{{ column.color }}",
|
||||||
},
|
},
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
];
|
];
|
||||||
|
|
||||||
var plotObj = $.plot($("#floatdonut{{ milestone.id }}"), data, {
|
var plotObj = $.plot($("#floatdonut{{ jalon.idjal }}"), data, {
|
||||||
series: {
|
series: {
|
||||||
pie: {
|
pie: {
|
||||||
show: true,
|
show: true,
|
||||||
|
@ -238,29 +300,39 @@
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
{% for data in milestone.stat %}
|
console.log("BY number = {{ (filterbynumber=="true" ? 'filtre par nbticket':'filtre par poids') }}");
|
||||||
{% for data in milestone.stat %}
|
{% for sprint in jalon.sprints %}
|
||||||
|
console.log("Sprint = {{sprint.nmspr}}");
|
||||||
|
|
||||||
|
{% for column in sprint.columns %}
|
||||||
|
console.log({{ (filterbynumber=="true" ? column.nbiss:column.nbjrs) }});
|
||||||
|
{% endfor %}
|
||||||
var data = [
|
var data = [
|
||||||
{% for label in data.labels %}
|
{% for column in sprint.columns %}
|
||||||
{
|
{
|
||||||
label: "{{ label.label}}",
|
label: "{{ column.nmcol}}",
|
||||||
data: {{ label.total }},
|
data: {{ (filterbynumber=="true" ? column.nbiss:column.nbjrs) }},
|
||||||
color: "{{ label.color }}",
|
color: "#{{ column.color }}",
|
||||||
},
|
},
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
];
|
];
|
||||||
var plotObj = $.plot($("#floatsubdonut{{ milestone.id }}-{{ data.id }}"), data, {
|
|
||||||
|
var plotObj = $.plot($("#floatdonut{{ jalon.idjal~"-"~sprint.idspr }}"), data, {
|
||||||
series: {
|
series: {
|
||||||
pie: {
|
pie: {
|
||||||
show: true,
|
show: true,
|
||||||
|
radius: 1,
|
||||||
label: {
|
label: {
|
||||||
show: false,
|
show: true,
|
||||||
radius: 3/4,
|
radius: 1,
|
||||||
threshold: 0.1,
|
threshold: 0.1,
|
||||||
background: {
|
background: {
|
||||||
opacity: 0.5,
|
opacity: 0.5,
|
||||||
color: '#cdcdcd',
|
color: '#cdcdcd',
|
||||||
},
|
},
|
||||||
|
formatter: function(label, series) {
|
||||||
|
return '<span style="color:#000; padding:3px;">' + label + '</span>';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -270,7 +342,6 @@
|
||||||
});
|
});
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if not showfilters %}
|
{% if not showfilters %}
|
||||||
$("#filters").addClass("d-none");
|
$("#filters").addClass("d-none");
|
||||||
|
|
|
@ -32,31 +32,15 @@
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div id="filters" class="d-flex flex-column pl-2 pr-2 " style="width:350px; background-color:var(--colorbgbodydark);min-height:1500px;">
|
<div id="filters" class="d-flex flex-column pl-2 pr-2 " style="width:350px; background-color:var(--colorbgbodydark);min-height:1500px;">
|
||||||
|
{% if fgpoker %}
|
||||||
|
<div id="online" class="mt-2"></div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div style="width:100%" class="mt-3">
|
<div style="width:100%" class="mt-3">
|
||||||
<label class="control-label" style="color:var(--colorftbodydark)">Filtre TICKET</label>
|
<label class="control-label" style="color:var(--colorftbodydark)">Filtre TICKET</label>
|
||||||
<input type="number" id="filterticket" class=" form-control">
|
<input type="number" id="filterticket" class=" form-control">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if id == 0 %}
|
|
||||||
<div style="width:100%" class="mt-3">
|
|
||||||
<label class="control-label" style="color:var(--colorftbodydark)">Filtre CATEGORIES</label>
|
|
||||||
<select id="filtercategorys" multiple="multiple" class="form-control">
|
|
||||||
{% for giteacategory in giteacategorys %}
|
|
||||||
<option value="{{giteacategory}}">{{giteacategory}}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="width:100%" class="mt-3">
|
|
||||||
<label class="control-label" style="color:var(--colorftbodydark)">Filtre PROJETS</label>
|
|
||||||
<select id="filterrepos" multiple="multiple" class="form-control">
|
|
||||||
{% for gitearepo in gitearepos %}
|
|
||||||
<option value="{{gitearepo.id}}">{{gitearepo.full_name}}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div style="width:100%" class="mt-3">
|
<div style="width:100%" class="mt-3">
|
||||||
<label class="control-label" style="color:var(--colorftbodydark)">Filtre JALONS</label>
|
<label class="control-label" style="color:var(--colorftbodydark)">Filtre JALONS</label>
|
||||||
<select id="filtermilestones" multiple="multiple" class="form-control">
|
<select id="filtermilestones" multiple="multiple" class="form-control">
|
||||||
|
@ -66,6 +50,18 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style="width:100%" class="mt-3">
|
||||||
|
<label class="control-label" style="color:var(--colorftbodydark)">Filtre SPRINT</label>
|
||||||
|
<select id="filtersprints" multiple="multiple" class="form-control">
|
||||||
|
{% for sprint in sprints %}
|
||||||
|
<option value="{{sprint.giteamilestone~"-"~sprint.id}}">{{sprint.giteamilestonename}}-{{sprint.name}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
{% for giteamilestone in giteamilestones %}
|
||||||
|
<option value="{{giteamilestone.id~"--100"}}">{{giteamilestone.title}}-Aucun</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style="width:100%" class="mt-3">
|
<div style="width:100%" class="mt-3">
|
||||||
<label class="control-label" style="color:var(--colorftbodydark)">Filtre STATUTS</label>
|
<label class="control-label" style="color:var(--colorftbodydark)">Filtre STATUTS</label>
|
||||||
<select id="filtercolumns" multiple="multiple" class="form-control">
|
<select id="filtercolumns" multiple="multiple" class="form-control">
|
||||||
|
@ -143,7 +139,7 @@
|
||||||
<a class="btn btn-success" href="{{path('app_scrum_stat',{id:id})}}"><i class="fas fa-chart-area"></i></a>
|
<a class="btn btn-success" href="{{path('app_scrum_stat',{id:id})}}"><i class="fas fa-chart-area"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span id="textfilters"></span>
|
<span id="textfilters"></span>
|
||||||
<a class="btn btn-success float-right" href="{{path('app_issuescrum',{id:id,'fgcsv':true})}}">Export CSV</a>
|
<a class="btn btn-success float-right" href="{{path('app_scrum_table',{id:id,'fgcsv':true})}}">Export CSV</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -153,15 +149,21 @@
|
||||||
<th class="no-sort"></th>
|
<th class="no-sort"></th>
|
||||||
{%if id==0 %}<th style="width:100px">Projet</th>{%endif%}
|
{%if id==0 %}<th style="width:100px">Projet</th>{%endif%}
|
||||||
<th style="width:200px">Jalon</th>
|
<th style="width:200px">Jalon</th>
|
||||||
|
<th style="width:200px">Sprint</th>
|
||||||
<th style="width:200px">Type</th>
|
<th style="width:200px">Type</th>
|
||||||
<th style="width:70px"class="no-string">N°</th>
|
<th style="width:70px"class="no-string">N°</th>
|
||||||
<th style="width:1000px">Titre</th>
|
<th style="width:1000px">Titre</th>
|
||||||
|
{% if (not wssuse or not fgpoker) %}
|
||||||
<th style="width:200px">Equipe</th>
|
<th style="width:200px">Equipe</th>
|
||||||
<th style="width:250px">Priorité</th>
|
<th style="width:250px">Priorité</th>
|
||||||
<th style="width:70px">Poid</th>
|
|
||||||
<th style="width:135px">Affecté à</th>
|
<th style="width:135px">Affecté à</th>
|
||||||
<th style="width:135px">Statut</th>
|
|
||||||
<th style="width:300px">Etiquettes</th>
|
<th style="width:300px">Etiquettes</th>
|
||||||
|
{% else %}
|
||||||
|
<th style="width:300px">Poker</th>
|
||||||
|
{% endif %}
|
||||||
|
<th style="width:135px">Statut</th>
|
||||||
|
<th style="width:70px">Poid</th>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
|
@ -182,19 +184,15 @@
|
||||||
{% if tosee %}
|
{% if tosee %}
|
||||||
{% set dataticket = giteaissue.number %}
|
{% set dataticket = giteaissue.number %}
|
||||||
{% set datarepo = gitearepo.id %}
|
{% set datarepo = gitearepo.id %}
|
||||||
|
{% set datamilestone = (giteaissue.milestone?giteaissue.milestone.id:-100) %}
|
||||||
{% if giteaissue.milestone %}
|
{% set datasprint = datamilestone~"-"~giteaissue.sprintid %}
|
||||||
{% set datamilestone = giteaissue.milestone.id %}
|
|
||||||
{%else%}
|
|
||||||
{% set datamilestone = gitearepo.full_name %}
|
|
||||||
{%endif%}
|
|
||||||
|
|
||||||
{% set statut = "Backlog" %}
|
{% set statut = "Backlog" %}
|
||||||
{% set teams = "" %}
|
{% set teams = "" %}
|
||||||
{% set types = "" %}
|
{% set types = "" %}
|
||||||
{% set datateams = "" %}
|
{% set datateams = "" %}
|
||||||
{% set datatypes = "" %}
|
{% set datatypes = "" %}
|
||||||
{% set prioritys = '<span class="btn-link tag mr-1" style="background-color:#70c24a"><i class="fas fa-tag"></i>'~giteaprioritys|last~'</span>' %}
|
{% set prioritys = (not giteaprioritys?'':'<span class="btn-link tag mr-1" style="background-color:#70c24a"><i class="fas fa-tag"></i>'~giteaprioritys|last~'</span>') %}
|
||||||
{% set dataprioritys = ','~giteaprioritys|last %}
|
{% set dataprioritys = ','~giteaprioritys|last %}
|
||||||
{% set labels = "" %}
|
{% set labels = "" %}
|
||||||
{% set datalabels = "" %}
|
{% set datalabels = "" %}
|
||||||
|
@ -221,12 +219,13 @@
|
||||||
{% set dataassignees=dataassignees~','~assignee.username %}
|
{% set dataassignees=dataassignees~','~assignee.username %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
<tr data-category="{{gitearepo.category}}" data-repo="{{datarepo}}" data-milestone="{{datamilestone}}" data-ticket="{{dataticket}}" data-column="{{statut}}" data-teams="{{datateams}}" data-prioritys="{{dataprioritys}}" data-types="{{datatypes}}" data-labels="{{datalabels}}" data-assignees="{{dataassignees}}">
|
<tr data-id="{{giteaissue.issueid}}" data-milestone="{{datamilestone}}" data-sprint="{{datasprint}}" data-ticket="{{dataticket}}" data-column="{{statut}}" data-teams="{{datateams}}" data-prioritys="{{dataprioritys}}" data-types="{{datatypes}}" data-labels="{{datalabels}}" data-assignees="{{dataassignees}}">
|
||||||
<td>
|
<td>
|
||||||
<a target="_blank" class="btn btn-link fa fa-file" href="{{giteaissue.html_url}}"></a>
|
<a target="_blank" class="btn btn-link fa fa-file" href="{{giteaissue.html_url}}"></a>
|
||||||
</td>
|
</td>
|
||||||
{%if id==0 %}<td>{{ gitearepo.full_name }}</td>{%endif%}
|
{%if id==0 %}<td>{{ gitearepo.full_name }}</td>{%endif%}
|
||||||
<td>{% if giteaissue.milestone %}{{ giteaissue.milestone.title }} {%endif%}</td>
|
<td>{% if giteaissue.milestone %}{{ giteaissue.milestone.title }} {%endif%}</td>
|
||||||
|
<td>{% if giteaissue.sprintid %}{{ giteaissue.sprintname }} {%endif%}</td>
|
||||||
<td>{{ types|raw }}</td>
|
<td>{{ types|raw }}</td>
|
||||||
<td>{{ giteaissue.number }}</td>
|
<td>{{ giteaissue.number }}</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -235,15 +234,11 @@
|
||||||
{{ giteaissue.title }}
|
{{ giteaissue.title }}
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
{% if (not wssuse or not fgpoker) %}
|
||||||
<td>{{ teams|raw }}</td>
|
<td>{{ teams|raw }}</td>
|
||||||
<td>{{ prioritys|raw }}</td>
|
<td>{{ prioritys|raw }}</td>
|
||||||
|
|
||||||
<td>
|
|
||||||
<div id="modissu{{ giteaissue.issueid }}" data-issue="{{ giteaissue.issueid }}" data-giteaid="{{giteaissue.number}}" data-giteatitle="{{ giteaissue.title }}" type="button" class="modissu btn btn-link">
|
|
||||||
<i class="fas fa-weight-hanging"></i> = <span id="issue{{giteaissue.issueid}}-weight">{{ giteaissue.weight }}</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{% set dataorder="" %}
|
{% set dataorder="" %}
|
||||||
{% for assignee in giteaissue.assignees %}
|
{% for assignee in giteaissue.assignees %}
|
||||||
{% set dataorder=dataorder~assignee.username %}
|
{% set dataorder=dataorder~assignee.username %}
|
||||||
|
@ -254,8 +249,19 @@
|
||||||
<img src="{{assignee.avatar_url}}" class="assignee" title="{{assignee.username}}">
|
<img src="{{assignee.avatar_url}}" class="assignee" title="{{assignee.username}}">
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ statut }}</td>
|
|
||||||
<td>{{ labels|raw }}</td>
|
<td>{{ labels|raw }}</td>
|
||||||
|
{% else %}
|
||||||
|
<td>
|
||||||
|
<div class="pokertd d-flex"></div>
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<td>{{ statut }}</td>
|
||||||
|
<td>
|
||||||
|
<div id="modissu{{ giteaissue.issueid }}" data-issue="{{ giteaissue.issueid }}" data-giteaid="{{giteaissue.number}}" data-giteatitle="{{ giteaissue.title }}" type="button" class="modissu btn btn-link">
|
||||||
|
<i class="fas fa-weight-hanging"></i> = <span id="issue{{giteaissue.issueid}}-weight">{{ giteaissue.weight }}</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -320,9 +326,8 @@
|
||||||
function showhide() {
|
function showhide() {
|
||||||
textfilters="";
|
textfilters="";
|
||||||
ticketfilter=$("#filterticket").val();
|
ticketfilter=$("#filterticket").val();
|
||||||
categoryfilters=$("#filtercategorys").val();
|
|
||||||
repofilters=$("#filterrepos").val();
|
|
||||||
milestonefilters=$("#filtermilestones").val();
|
milestonefilters=$("#filtermilestones").val();
|
||||||
|
sprintfilters=$("#filtersprints").val();
|
||||||
columnfilters=$("#filtercolumns").val();
|
columnfilters=$("#filtercolumns").val();
|
||||||
teamfilters=$("#filterteams").val();
|
teamfilters=$("#filterteams").val();
|
||||||
priorityfilters=$("#filterprioritys").val();
|
priorityfilters=$("#filterprioritys").val();
|
||||||
|
@ -340,6 +345,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
ticket= $(el).data('ticket');
|
ticket= $(el).data('ticket');
|
||||||
milestone = $(el).data('milestone');
|
milestone = $(el).data('milestone');
|
||||||
|
sprint = $(el).data('sprint');
|
||||||
column = $(el).data('column');
|
column = $(el).data('column');
|
||||||
teams = $(el).data('teams').split(',');
|
teams = $(el).data('teams').split(',');
|
||||||
prioritys = $(el).data('prioritys').split(',');
|
prioritys = $(el).data('prioritys').split(',');
|
||||||
|
@ -373,6 +379,11 @@
|
||||||
toreturn=false;
|
toreturn=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(sprintfilters.length!==0 && jQuery.inArray(sprint.toString(), sprintfilters )<0) {
|
||||||
|
toreturn=false;
|
||||||
|
}
|
||||||
|
|
||||||
if(columnfilters.length!==0 && jQuery.inArray(column.toString(), columnfilters )<0) {
|
if(columnfilters.length!==0 && jQuery.inArray(column.toString(), columnfilters )<0) {
|
||||||
toreturn=false;
|
toreturn=false;
|
||||||
}
|
}
|
||||||
|
@ -439,26 +450,6 @@
|
||||||
textfilters=textfilters+" <b>TICKET</b> ="+ticketfilter;
|
textfilters=textfilters+" <b>TICKET</b> ="+ticketfilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
{% if id == 0 %}
|
|
||||||
if(categoryfilters.length!==0) {
|
|
||||||
data = $("#filtercategorys").select2('data');
|
|
||||||
textfilters=textfilters+" <b>CATEGORIES</b> =";
|
|
||||||
$.each(categoryfilters, function( index, value ) {
|
|
||||||
if(index>0)textfilters=textfilters+" &";
|
|
||||||
textfilters=textfilters+" "+data[index].text;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if(repofilters.length!==0) {
|
|
||||||
data = $("#filterrepos").select2('data');
|
|
||||||
textfilters=textfilters+" <b>PROJETS</b> =";
|
|
||||||
$.each(repofilters, function( index, value ) {
|
|
||||||
if(index>0)textfilters=textfilters+" &";
|
|
||||||
textfilters=textfilters+" "+data[index].text;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
if(milestonefilters.length!==0) {
|
if(milestonefilters.length!==0) {
|
||||||
data = $("#filtermilestones").select2('data');
|
data = $("#filtermilestones").select2('data');
|
||||||
textfilters=textfilters+" <b>JALONS</b> =";
|
textfilters=textfilters+" <b>JALONS</b> =";
|
||||||
|
@ -468,6 +459,15 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(sprintfilters.length!==0) {
|
||||||
|
data = $("#filtersprints").select2('data');
|
||||||
|
textfilters=textfilters+" <b>SPRINTS</b> =";
|
||||||
|
$.each(sprintfilters, function( index, value ) {
|
||||||
|
if(index>0)textfilters=textfilters+" &";
|
||||||
|
textfilters=textfilters+" "+data[index].text;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if(columnfilters.length!==0) {
|
if(columnfilters.length!==0) {
|
||||||
data = $("#filtercolumns").select2('data');
|
data = $("#filtercolumns").select2('data');
|
||||||
textfilters=textfilters+" <b>STATUS</b> =";
|
textfilters=textfilters+" <b>STATUS</b> =";
|
||||||
|
@ -537,36 +537,6 @@
|
||||||
table.draw();
|
table.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
{% if id == 0 %}
|
|
||||||
function filtercategorys() {
|
|
||||||
$.ajax({
|
|
||||||
method: "POST",
|
|
||||||
url: "{{ path('app_user_preference') }}",
|
|
||||||
data: {
|
|
||||||
key:'filtercategorys',
|
|
||||||
id:{{id}},
|
|
||||||
value: $("#filtercategorys").val()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
showhide();
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterrepos() {
|
|
||||||
$.ajax({
|
|
||||||
method: "POST",
|
|
||||||
url: "{{ path('app_user_preference') }}",
|
|
||||||
data: {
|
|
||||||
key:'filterrepos',
|
|
||||||
id:{{id}},
|
|
||||||
value: $("#filterrepos").val()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
showhide();
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
function filtermilestones() {
|
function filtermilestones() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -581,6 +551,20 @@
|
||||||
showhide();
|
showhide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filtersprints() {
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{ path('app_user_preference') }}",
|
||||||
|
data: {
|
||||||
|
key:'filtersprints',
|
||||||
|
id:{{id}},
|
||||||
|
value: $("#filtersprints").val()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showhide();
|
||||||
|
}
|
||||||
|
|
||||||
function filtercolumns() {
|
function filtercolumns() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -732,36 +716,6 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
{% if id== 0 %}
|
|
||||||
$('#filtercategorys').select2();
|
|
||||||
{% if filtercategorys %}
|
|
||||||
{% for category in filtercategorys %}
|
|
||||||
$("#filtercategorys").val($("#filtercategorys").val().concat("{{category}}"));
|
|
||||||
{%endfor%}
|
|
||||||
$('#filtercategorys').trigger('change');
|
|
||||||
{% endif %}
|
|
||||||
$('#filtercategorys').on("select2:select", function(e) {
|
|
||||||
filtercategorys();
|
|
||||||
});
|
|
||||||
$('#filtercategorys').on("select2:unselect", function(e) {
|
|
||||||
filtercategorys();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#filterrepos').select2();
|
|
||||||
{% if filterrepos %}
|
|
||||||
{% for repo in filterrepos %}
|
|
||||||
$("#filterrepos").val($("#filterrepos").val().concat("{{repo}}"));
|
|
||||||
{%endfor%}
|
|
||||||
$('#filterrepos').trigger('change');
|
|
||||||
{% endif %}
|
|
||||||
$('#filterrepos').on("select2:select", function(e) {
|
|
||||||
filterrepos();
|
|
||||||
});
|
|
||||||
$('#filterrepos').on("select2:unselect", function(e) {
|
|
||||||
filterrepos();
|
|
||||||
});
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
$("#filterticket").on("keyup", function() {
|
$("#filterticket").on("keyup", function() {
|
||||||
showhide();
|
showhide();
|
||||||
});
|
});
|
||||||
|
@ -780,6 +734,20 @@
|
||||||
filtermilestones();
|
filtermilestones();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#filtersprints').select2();
|
||||||
|
{% if filtersprints %}
|
||||||
|
{% for sprint in filtersprints %}
|
||||||
|
$("#filtersprints").val($("#filtersprints").val().concat("{{sprint}}"));
|
||||||
|
{%endfor%}
|
||||||
|
$('#filtersprints').trigger('change');
|
||||||
|
{% endif %}
|
||||||
|
$('#filtersprints').on("select2:select", function(e) {
|
||||||
|
filtersprints();
|
||||||
|
});
|
||||||
|
$('#filtersprints').on("select2:unselect", function(e) {
|
||||||
|
filtersprints();
|
||||||
|
});
|
||||||
|
|
||||||
$('#filtercolumns').select2();
|
$('#filtercolumns').select2();
|
||||||
{% if filtercolumns %}
|
{% if filtercolumns %}
|
||||||
{% for column in filtercolumns %}
|
{% for column in filtercolumns %}
|
||||||
|
@ -894,4 +862,89 @@
|
||||||
|
|
||||||
$("#mycontent").show();
|
$("#mycontent").show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
{% if wssuse and fgpoker %}
|
||||||
|
var conn;
|
||||||
|
|
||||||
|
function connect() {
|
||||||
|
conn = new WebSocket("{{wssurl}}");
|
||||||
|
|
||||||
|
conn.onopen = function(e) {
|
||||||
|
console.log("== CONNECT");
|
||||||
|
{% set userkey = "" %}
|
||||||
|
{% if app.user %}
|
||||||
|
{% set userkey = app.user.apikey %}
|
||||||
|
{%endif%}
|
||||||
|
|
||||||
|
subscribe("home",{{id}},"{{userkey}}");
|
||||||
|
sendMessage({command: "alive"});
|
||||||
|
};
|
||||||
|
|
||||||
|
conn.onmessage = function(e) {
|
||||||
|
ret=JSON.parse(e.data);
|
||||||
|
console.log("MESSAGE REU ="+ret.command);
|
||||||
|
|
||||||
|
switch(ret.command) {
|
||||||
|
case "alive" :
|
||||||
|
if(!$('#online'+ret.from.id).length) {
|
||||||
|
img='<img id="online'+ret.from.id+'" src="'+ret.from.avatar+'" class="avatar ml-2 mr-2" title="'+ret.from.displayname+'">';
|
||||||
|
$("#online").append(img);
|
||||||
|
|
||||||
|
$("tr").each(function(){
|
||||||
|
line=$(this);
|
||||||
|
issueid=$(this).data("id");
|
||||||
|
url="{{path("app_poker_get",{userid:"xxx",issueid:"yyy"})}}";
|
||||||
|
url=url.replace("xxx",ret.from.id);
|
||||||
|
url=url.replace("yyy",issueid);
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: url,
|
||||||
|
async: false,
|
||||||
|
success: function(data) {
|
||||||
|
html ='<div class="d-flex flex-column align-items-center" data-user="'+ret.from.id+'">';
|
||||||
|
html+='<img src="'+ret.from.avatar+'" class="avatar mb-1" style="zoom:80%;" title="'+ret.from.displayname+'">';
|
||||||
|
html+='<input class="pokervalue" id="poker-'+ret.from.id+'-'+issueid+'" data-user="'+ret.from.id+'" data-issue="'+issueid+'" type="number" style="width:60px" value="'+data+'"></input>';
|
||||||
|
html+='</div>';
|
||||||
|
line.find(".pokertd").append(html);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret.from.id!={{app.user.id}}) {
|
||||||
|
console.log("meto");
|
||||||
|
sendMessage({command: "meto"});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "adead" :
|
||||||
|
$('#online'+ret.from.id).remove();
|
||||||
|
$('[data-user='+ret.from.id+']').remove();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "meto" :
|
||||||
|
if(!$('#online'+ret.from.id).length) {
|
||||||
|
html='<img id="online'+ret.from.id+'" src="'+ret.from.avatar+'" class="avatar ml-2 mr-2" title="'+ret.from.displayname+'">';
|
||||||
|
$("#online").append(html);
|
||||||
|
$(".pokertd").append(html);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
conn.onclose = function(e) {
|
||||||
|
console.log("== DISCONNECT");
|
||||||
|
$('#online img').remove();
|
||||||
|
console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason);
|
||||||
|
setTimeout(function() { connect(); }, 1000);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
connect();
|
||||||
|
|
||||||
|
$("body").on("input", ".pokervalue", function () {
|
||||||
|
console.log($(this).val());
|
||||||
|
});
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -22,19 +22,24 @@
|
||||||
|
|
||||||
.tag {
|
.tag {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 8px 8px;
|
padding: 4px 8px;
|
||||||
margin-bottom: 5px;
|
//margin-bottom: 2px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 35px;
|
min-width: 35px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #ffffff !important;
|
color: #ffffff !important;
|
||||||
zoom: 80%;
|
zoom: 70%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag i {
|
.tag i {
|
||||||
margin-right:5px;
|
margin-right:5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tooltip-inner {
|
||||||
|
text-align: left !important; /* Aligne le texte à gauche */
|
||||||
|
white-space: pre-line; /* Conserve les retours à la ligne */
|
||||||
|
}
|
||||||
|
|
||||||
.assignee {
|
.assignee {
|
||||||
width:30px;
|
width:30px;
|
||||||
margin: 5px 5px 0px 0px;
|
margin: 5px 5px 0px 0px;
|
||||||
|
@ -43,9 +48,19 @@
|
||||||
.state-closed {
|
.state-closed {
|
||||||
background-color: #cdcdcd !important;
|
background-color: #cdcdcd !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-small { font-size:80%}
|
||||||
|
.text-verysmall { font-size:70%}
|
||||||
|
|
||||||
|
.submenu a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--colorfttitlelight);
|
||||||
|
}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
{% set start = microtime(true) %}
|
||||||
|
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div id="filters" class="d-flex flex-column pl-2 pr-2 " style="width:350px; background-color:var(--colorbgbodydark);min-height:1500px;">
|
<div id="filters" class="d-flex flex-column pl-2 pr-2 " style="width:350px; background-color:var(--colorbgbodydark);min-height:1500px;">
|
||||||
<div style="width:100%" class="mt-3">
|
<div style="width:100%" class="mt-3">
|
||||||
|
@ -58,6 +73,18 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style="width:100%" class="mt-3">
|
||||||
|
<label class="control-label" style="color:var(--colorftbodydark)">Filtre SPRINT</label>
|
||||||
|
<select id="filtersprints" multiple="multiple" class="form-control">
|
||||||
|
{% for sprint in sprints %}
|
||||||
|
<option value="{{sprint.giteamilestone~"-"~sprint.id}}">{{sprint.giteamilestonename}}-{{sprint.name}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
{% for giteamilestone in giteamilestones %}
|
||||||
|
<option value="{{giteamilestone.id~"--100"}}">{{giteamilestone.title}}-Aucun</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style="width:100%" class="mt-3">
|
<div style="width:100%" class="mt-3">
|
||||||
<label class="control-label" style="color:var(--colorftbodydark)">Filtre TYPES</label>
|
<label class="control-label" style="color:var(--colorftbodydark)">Filtre TYPES</label>
|
||||||
<select id="filtertypes" multiple="multiple" class="form-control">
|
<select id="filtertypes" multiple="multiple" class="form-control">
|
||||||
|
@ -113,12 +140,14 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style="width:100%" class="mt-3">
|
||||||
|
<div class="custom-control custom-switch">
|
||||||
|
<input type="checkbox" class="custom-control-input" id="viewcondensed">
|
||||||
|
<label class="custom-control-label" for="viewcondensed" style="color:var(--colorfttitledark);">Vue condensée</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style="color:var(--colorftbodydark);zoom:75%;" class="mt-5">
|
<div id="tbestim" class="mt-5">
|
||||||
{% for giteamilestone in giteamilestones %}
|
|
||||||
{{giteamilestone.title}} = <span id="total{{giteamilestone.id}}" class="totalweight">0</span><br>
|
|
||||||
{% endfor %}
|
|
||||||
Aucun = <span id="total-100" class="totalweight">0</span><br>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -130,20 +159,36 @@
|
||||||
|
|
||||||
<div class="mt-4" style="zoom:80%">
|
<div class="mt-4" style="zoom:80%">
|
||||||
<button class="btn btn-success" onClick="showFilters()"><i class="fas fa-filter"></i></button>
|
<button class="btn btn-success" onClick="showFilters()"><i class="fas fa-filter"></i></button>
|
||||||
<a class="btn btn-success" href="{{path('app_issuescrum',{id:scrum.id})}}"><i class="fas fa-ticket-alt"></i></a>
|
<a class="btn btn-success" href="{{path('app_scrum_table',{id:scrum.id})}}"><i class="fas fa-ticket-alt"></i></a>
|
||||||
<a class="btn btn-success" href="{{path('app_scrum_stat',{id:scrum.id})}}"><i class="fas fa-chart-area"></i></a>
|
<a class="btn btn-success" href="{{path('app_scrum_stat',{id:scrum.id})}}"><i class="fas fa-chart-area"></i></a>
|
||||||
<a href="{{giteaUrl}}/{{scrum.giteajson.owner.login}}/{{scrum.giteajson.name}}/issues/new" class="btn btn-success" target="_blank">Nouveau Ticket</a>
|
<a href="{{giteaUrl}}/{{scrum.giteajson.owner.login}}/{{scrum.giteajson.name}}/issues/new" class="btn btn-success" target="_blank">Nouveau Ticket</a>
|
||||||
<span id="textfilters"></span>
|
<span id="textfilters"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% for column in scrum.scrumcolumns %}
|
{% for column in tbissues %}
|
||||||
{% set idmiletone="-100" %}
|
<div class="d-inline-block mt-3 align-top mb-5 p-2" data-column="{{column.gicol}}" style="width: 18rem;">
|
||||||
{% set tbidmiletone=[] %}
|
<h2 style="text-transform: uppercase; text-align:center; font-size:26px">{{ column.nmcol }}</h2>
|
||||||
{% set haveissues=false %}
|
|
||||||
<div class="card d-inline-block mt-3 align-top mb-5" data-column="{{column.giteaid}}" style="width: 18rem;">
|
|
||||||
<div class="card-header">{{ column.name }}</div>
|
|
||||||
<div class="card-body p-1">
|
<div class="card-body p-1">
|
||||||
{% for issue in column.scrumissues %}
|
{% for jalon in column.jalons %}
|
||||||
|
{% for sprint in jalon.sprints %}
|
||||||
|
<div class="card mb-3" data-column="{{column.gicol}}" data-milestone="{{jalon.gijal}}" data-sprint="{{sprint.idspr}}" data-millestonesprint="{{jalon.gijal~"-"~sprint.idspr}}">
|
||||||
|
<div class="card-header p-1 d-flex" style="font-size:16px; cursor:pointer;" onClick="$(this).next('.card-body').toggle()">
|
||||||
|
<div>
|
||||||
|
JALON = {{jalon.nmjal}}
|
||||||
|
{% if sprint.idspr!=-100 %}
|
||||||
|
<br>
|
||||||
|
SPRINT = {{sprint.nmspr}}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ml-auto" data-weight="{{column.gicol~"-"~jalon.gijal~"-"~sprint.idspr}}">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body p-1">
|
||||||
|
<ul class="scrumcolumn list-group" style="min-height:50px" data-column="{{column.gicol}}" data-milestone="{{jalon.gijal}}" data-sprint="{{sprint.idspr}}" data-millestonesprint="{{jalon.gijal~"-"~sprint.idspr}}">
|
||||||
|
{% for issue in sprint.issues %}
|
||||||
{% set tosee=false %}
|
{% set tosee=false %}
|
||||||
{% if app.session.get('viewclosed')=="true" and issue.giteastate=="closed" %}
|
{% if app.session.get('viewclosed')=="true" and issue.giteastate=="closed" %}
|
||||||
{% set tosee=true %}
|
{% set tosee=true %}
|
||||||
|
@ -153,29 +198,12 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if tosee %}
|
{% if tosee %}
|
||||||
{% set haveissues=true %}
|
|
||||||
{% if idmiletone!=issue.giteamilestone %}
|
|
||||||
{% if idmiletone!=-100 %}</ul>{% endif %}
|
|
||||||
|
|
||||||
{% if issue.giteamilestone is empty %}
|
|
||||||
{% set tbidmiletone = tbidmiletone|merge([-100]) %}
|
|
||||||
{% set idmilestone = -100 %}
|
|
||||||
{% set namemilestone = "Aucun" %}
|
|
||||||
{% else %}
|
|
||||||
{% set tbidmiletone = tbidmiletone|merge([issue.giteamilestone]) %}
|
|
||||||
{% set idmilestone = issue.giteamilestone %}
|
|
||||||
{% set namemilestone = issue.giteajson.milestone.title %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h3 data-milestone="{{idmilestone}}">JALON = {{namemilestone}}</h3>
|
|
||||||
<ul class="scrumcolumn list-group" style="min-height:50px" data-column="{{column.giteaid}}" data-milestone="{{idmilestone}}">
|
|
||||||
{% set idmiletone=issue.giteamilestone %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% set datalabels="" %}
|
{% set datalabels="" %}
|
||||||
{% set datateams="" %}
|
{% set datateams="" %}
|
||||||
{% set datatypes="" %}
|
{% set datatypes="" %}
|
||||||
{% set dataprioritys="datapriority"~giteaprioritys|last %}
|
{% set dataprioritys="datapriority"~giteaprioritys|last %}
|
||||||
|
{% set issuprioritycolor=prioritycolor %}
|
||||||
|
|
||||||
{% for label in issue.giteajson.labels %}
|
{% for label in issue.giteajson.labels %}
|
||||||
{% if label.id not in giteacolumns and label.id in giteateams %}
|
{% if label.id not in giteacolumns and label.id in giteateams %}
|
||||||
{% set datateams=datateams~"datateam"~label.id~" " %}
|
{% set datateams=datateams~"datateam"~label.id~" " %}
|
||||||
|
@ -187,11 +215,10 @@
|
||||||
|
|
||||||
{% if label.id not in giteacolumns and label.id in giteaprioritys %}
|
{% if label.id not in giteacolumns and label.id in giteaprioritys %}
|
||||||
{% set dataprioritys="datapriority"~label.id~" " %}
|
{% set dataprioritys="datapriority"~label.id~" " %}
|
||||||
|
{% set issuprioritycolor="#"~label.color %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if label.id not in giteacolumns and label.id not in giteateams and label.id not in giteatypes and label.id not in giteaprioritys %}
|
|
||||||
{% set datalabels=datalabels~"datalabel"~label.id~" " %}
|
{% set datalabels=datalabels~"datalabel"~label.id~" " %}
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% set dataassignees="" %}
|
{% set dataassignees="" %}
|
||||||
|
@ -199,51 +226,154 @@
|
||||||
{% set dataassignees=dataassignees~"dataassignee"~assignee.id~" " %}
|
{% set dataassignees=dataassignees~"dataassignee"~assignee.id~" " %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
<div id="issu{{ issue.id }}" data-id="{{ issue.id }}" data-issue="{{ issue.id }}" data-column="{{column.giteaid}}" data-milestone="{{idmilestone}}" class="card mb-1 issue issue-{{issue.id}} {{datateams}} {{datatypes}} {{dataprioritys}} {{datalabels}} {{dataassignees}} state-{{issue.giteastate}}">
|
{% set backcolor="" %}
|
||||||
<div class="card-footer p-1" style="line-height:10px; border-top:none;">
|
{% if not issue.color is empty %}
|
||||||
<div class="float-left btn btn-link p-0 m-0 fas fa-arrows-alt" style="cursor:move"></div>
|
{% set backcolor="background-color:"~issue.color~";" %}
|
||||||
<a target="_blank" class="modcolumn btn btn-link float-right fa fa-file p-0 m-0" href="{{issue.giteajson.html_url}}"></a>
|
{% elseif issue.scrumissueblock and not issue.scrumissueblock.color is empty %}
|
||||||
|
{% set backcolor="background-color:"~issue.scrumissueblock.color~";" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% set notes=(not issue.notes is empty?issue.notes|striptags|replace({'\n': '<br>', '\r': '<br>'})|raw:"") %}
|
||||||
|
|
||||||
|
<div id="issu{{ issue.id }}" data-id="{{ issue.id }}" data-issue="{{ issue.id }}" data-column="{{column.gicol}}" data-milestone="{{jalon.gijal}}" data-sprint="{{sprint.idspr}}" class="card mb-1 issue issue-{{issue.id}} {{datateams}} {{datatypes}} {{dataprioritys}} {{datalabels}} {{dataassignees}} state-{{issue.giteastate}}" style="border-left: 10px solid {{issuprioritycolor}}" {{ (not notes is empty?'title='~notes:'') }}>
|
||||||
|
<div class="card-footer p-1 d-flex" style="line-height:16px; border-top:none; {{ backcolor }}" >
|
||||||
|
<div class="flex-grow-1 d-flex align-items-center" style="max-width:224px";>
|
||||||
|
<div class="pr-2 issu-id" style="cursor:move">
|
||||||
|
#{{issue.giteanumber}}
|
||||||
|
</div>
|
||||||
|
<div class="text-small" style="cursor:pointer; word-break: break-word;" onClick="$('#issu-detail{{ issue.id }}').toggle()">
|
||||||
|
{% if not issue.scrumissueblock is empty %}
|
||||||
|
<div class="text-verysmall" style="margin-bottom:-5px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis; width: 160px;">
|
||||||
|
#{{issue.scrumissueblock.giteanumber}} = {{issue.scrumissueblock.giteatitle}}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div style="line-height:13px;">{{ issue.giteatitle }}</div>
|
||||||
|
|
||||||
|
{% for depend in issue.scrumissuedependencies %}
|
||||||
|
{% if loop.first %}
|
||||||
|
<div class="text-verysmall" style="margin-top: 5px;line-height:11px; width:160px;">
|
||||||
|
{% endif %}
|
||||||
|
{% set style="" %}
|
||||||
|
{% if depend.giteastate=="closed" %}
|
||||||
|
{% set style="text-decoration: line-through;" %}
|
||||||
|
{% endif %}
|
||||||
|
<div style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;{{style}}">#{{depend.giteanumber}} = {{depend.giteatitle}}</div>
|
||||||
|
{% if loop.last %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body p-1" style="line-height:10px;">
|
<div id="viewissu{{ issue.id }}" class="viewissu mb-2" onMouseenter="issuhover(this,{{ issue.id }})" data-issue="{{ issue.id }}" data-giteaid="{{issue.giteanumber}}" data-giteatitle="{{ issue.giteatitle }}" type="button" style="line-height:9px; text-align:center;">
|
||||||
<div>
|
<i class="btn btn-link fas fa-eye p-0 m-0 fa-fw"></i>
|
||||||
<small>
|
<br><span class="text-verysmall issue{{issue.id}}-weight">{{ issue.weight }}</span>
|
||||||
{{issue.giteanumber}} - {{ issue.giteatitle }}<br><br>
|
</div>
|
||||||
<small>Crée le {{issue.giteajson.created_at|date("d/m/y")}}</small><small style ="float:right">Modifié le {{issue.giteajson.updated_at|date("d/m/y")}}</small>
|
</div>
|
||||||
{% if issue.giteastate=="closed" %}
|
|
||||||
<br><small>Clos le {{issue.giteajson.closed_at|date("d/m/y")}}</small>
|
<div id="submenu{{issue.id}}" class="submenu" onmouseleave="issuout(this)" style="
|
||||||
|
position: absolute;
|
||||||
|
left: 214px;
|
||||||
|
top: -1px;
|
||||||
|
width:300px;
|
||||||
|
z-index:1200;
|
||||||
|
display:none;
|
||||||
|
background-color:#f7f7f7;
|
||||||
|
flex-direction: column;
|
||||||
|
border: 1px solid #cdcdcd;
|
||||||
|
border-radius: .25rem;
|
||||||
|
">
|
||||||
|
|
||||||
|
<div id="viewissu{{ issue.id }}" class="viewissu mb-2" data-issue="{{ issue.id }}" data-giteaid="{{issue.giteanumber}}" data-giteatitle="{{ issue.giteatitle }}">
|
||||||
|
<i class="btn fas fa-eye p-0 m-0 fa-fw pl-1 pl-1"></i>
|
||||||
|
<span style="cursor:pointer;">
|
||||||
|
Aperçu Ticket
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a target="_blank" href="{{issue.giteajson.html_url}}" style="cursor:pointer" class="modcolumn mb-2">
|
||||||
|
<i class="btn fa fa-file fa-fw p-0 m-0 pl-1 pl-1"></i>
|
||||||
|
<span>Modifier dans Gitea</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div id="modissu{{ issue.id }}" class="modissu mb-2" data-issue="{{ issue.id }}" data-giteaid="{{issue.giteanumber}}" data-giteatitle="{{ issue.giteatitle }}">
|
||||||
|
<i class="btn fas fa-weight-hanging p-0 m-0 fa-fw pl-1 pl-1"></i>
|
||||||
|
<span style="cursor:pointer;">
|
||||||
|
Modifier le Poids = <span class="issue{{issue.id}}-weight">{{ issue.weight }}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if issue.scrumissueblock is empty %}
|
||||||
|
<div id="lockissu{{ issue.id }}" class="lockissu mb-2" data-issue="{{ issue.id }}" data-giteaid="{{issue.giteanumber}}" data-giteatitle="{{ issue.giteatitle }}">
|
||||||
|
<i class="btn fas fa-lock p-0 m-0 fa-fw pl-1 pl-1"></i>
|
||||||
|
<span style="cursor:pointer;">
|
||||||
|
Ajouter ce ticket comme bloquant à
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div id="unlockissu{{ issue.id }}" class="unlockissu mb-2" data-issue="{{ issue.id }}" data-giteaid="{{issue.giteanumber}}" data-giteatitle="{{ issue.giteatitle }}">
|
||||||
|
<i class="btn fas fa-lock p-0 m-0 fa-fw pl-1 pl-1"></i>
|
||||||
|
<span style="cursor:pointer;">
|
||||||
|
N'est plus bloquant pour #{{ issue.scrumissueblock.giteanumber}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<br><br>
|
|
||||||
|
|
||||||
|
<div id="assigneissu{{ issue.id }}" class="assigneissu mb-2" data-issue="{{ issue.id }}" data-giteaid="{{issue.giteanumber}}" data-giteatitle="{{ issue.giteatitle }}">
|
||||||
|
<i class="btn fas fa-users p-0 m-0 fa-fw pl-1 pl-1"></i>
|
||||||
|
<span style="cursor:pointer;">
|
||||||
|
Affecté à
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="notesissu{{ issue.id }}" class="notesissu mb-2" data-issue="{{ issue.id }}" data-giteaid="{{issue.giteanumber}}" data-giteatitle="{{ issue.giteatitle }}">
|
||||||
|
<i class="btn fas fa-clipboard p-0 m-0 fa-fw pl-1 pl-1"></i>
|
||||||
|
<span style="cursor:pointer;">
|
||||||
|
Notes
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<input type="text" id="colorissu{{ issue.id }}" data-issue="{{ issue.id }}" class="pick-a-color form-control form-control spectrum sp-colorize" value="{{issue.color}}" autocomplete="off">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="issu-detail{{ issue.id }}" class="card-body p-1 issu-detail">
|
||||||
|
<div>
|
||||||
{% for label in issue.giteajson.labels %}
|
{% for label in issue.giteajson.labels %}
|
||||||
{% if label.id not in giteacolumns and label.id in giteaprioritys %}
|
{% if label.id not in giteacolumns and label.id in giteaprioritys %}
|
||||||
<span class="btn-link tag" style="background-color:#{{label.color}}">
|
<span class="btn-link tag" style="background-color:#{{label.color}}">
|
||||||
<i class="fas fa-tag"></i>
|
<i class="fas fa-clock"></i>
|
||||||
{{ label.name }}
|
{{ label.name }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<br>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
{% for label in issue.giteajson.labels %}
|
{% for label in issue.giteajson.labels %}
|
||||||
{% if label.id not in giteacolumns and label.id in giteatypes %}
|
{% if label.id not in giteacolumns and label.id in giteatypes %}
|
||||||
<span class="btn-link tag" style="background-color:#{{label.color}}">
|
<span class="btn-link tag" style="background-color:#{{label.color}}">
|
||||||
<i class="fas fa-tag"></i>
|
<i class="fas fa-quote-right"></i>
|
||||||
{{ label.name }}
|
{{ label.name }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<br>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
{% for label in issue.giteajson.labels %}
|
{% for label in issue.giteajson.labels %}
|
||||||
{% if label.id not in giteacolumns and label.id in giteateams %}
|
{% if label.id not in giteacolumns and label.id in giteateams %}
|
||||||
<span class="btn-link tag" style="background-color:#{{label.color}}">
|
<span class="btn-link tag" style="background-color:#{{label.color}}">
|
||||||
<i class="fas fa-tag"></i>
|
<i class="fas fa-users"></i>
|
||||||
{{ label.name }}
|
{{ label.name }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<br>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
{% for label in issue.giteajson.labels %}
|
{% for label in issue.giteajson.labels %}
|
||||||
{% if label.id not in giteacolumns and label.id not in giteateams and label.id not in giteaprioritys and label.id not in giteatypes %}
|
{% if label.id not in giteacolumns and label.id not in giteateams and label.id not in giteaprioritys and label.id not in giteatypes %}
|
||||||
<span class="btn-link tag" style="background-color:#{{label.color}}">
|
<span class="btn-link tag" style="background-color:#{{label.color}}">
|
||||||
|
@ -252,6 +382,7 @@
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{% for assignee in issue.giteajson.assignees %}
|
{% for assignee in issue.giteajson.assignees %}
|
||||||
|
@ -259,31 +390,32 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="modissu{{ issue.id }}" data-issue="{{ issue.id }}" data-giteaid="{{issue.giteanumber}}" data-giteatitle="{{ issue.giteatitle }}" type="button" class="modissu btn btn-link float-right">
|
<div id="modissu{{ issue.id }}" class="modissu btn btn-link d-flex justify-content-end align-items-center" data-issue="{{ issue.id }}" data-giteaid="{{issue.giteanumber}}" data-giteatitle="{{ issue.giteatitle }}" type="button">
|
||||||
<i class="fas fa-weight-hanging"></i> = <span id="issue{{issue.id}}-weight">{{ issue.weight }}</span>
|
<i class="fas fa-weight-hanging"></i> = <span class="issue{{issue.id}}-weight">{{ issue.weight }}</span>
|
||||||
</div>
|
</div>
|
||||||
</small>
|
|
||||||
|
<div class="d-flex text-small">
|
||||||
|
<div class="text-small">Crée le {{issue.giteajson.created_at|date("d/m/y")}}</div>
|
||||||
|
<div class="text-small text-right ml-auto">Modifié le {{issue.giteajson.updated_at|date("d/m/y")}}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-small">
|
||||||
|
<div class="text-small">Par {{issue.giteajson.user.login}}</div>
|
||||||
|
{% if issue.giteastate=="closed" %}
|
||||||
|
<div class="text-small text-right ml-auto">
|
||||||
|
Clos le {{issue.giteajson.closed_at|date("d/m/y")}}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% if haveissues %}
|
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
</div>
|
||||||
|
</div>
|
||||||
{% for giteamilestone in giteamilestones %}
|
{% endfor %}
|
||||||
{% if giteamilestone.id not in tbidmiletone %}
|
{% endfor %}
|
||||||
<h3 data-milestone="{{giteamilestone.id}}"> JALON = {{giteamilestone.title}}</h3>
|
|
||||||
<ul class="scrumcolumn list-group" style="min-height:50px" data-column="{{ column.giteaid }}" data-milestone="{{giteamilestone.id}}"></ul>
|
|
||||||
{% endif %}
|
|
||||||
{%endfor%}
|
|
||||||
|
|
||||||
{% if -100 not in tbidmiletone %}
|
|
||||||
<h3 data-milestone="-100"> JALON = Aucun</h3>
|
|
||||||
<ul class="scrumcolumn list-group" style="min-height:50px" data-column="{{ column.giteaid }}" data-milestone="-100"></ul>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -313,12 +445,89 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="mymodalblock" class="modal" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title"></h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-group ">
|
||||||
|
<label class="control-label required" for="issu_weight">
|
||||||
|
Le ticket en cours bloque le ticket suivant
|
||||||
|
</label>
|
||||||
|
<input type="hidden" id="modal-issueid" name="modal-issueid" required="required" class=" form-control" value="">
|
||||||
|
<input type="integer" id="modal-issueblocked" name="modal-issueweight" required="required" class=" form-control" value="">
|
||||||
|
</div>
|
||||||
|
<button id="issu_blockupdate" class="btn btn-success">Enregistrer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="mymodalassignees" class="modal" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title"></h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<input type="hidden" id="modal-issueid" name="modal-issueid" required="required" class=" form-control" value="">
|
||||||
|
|
||||||
|
<div style="width:100%">
|
||||||
|
<label class="control-label required" for="issu_weight">
|
||||||
|
Affecté à
|
||||||
|
</label>
|
||||||
|
<select id="modal-assignees" multiple="multiple" class="form-control mb-3">
|
||||||
|
{% for giteaassignee in giteaassignees %}
|
||||||
|
<option value="{{giteaassignee.login}}">{{giteaassignee.login}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button id="issu_assigne" class="btn btn-success mt-3">Enregistrer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="mymodalnotes" class="modal" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title"></h4>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<input type="hidden" id="modal-issueid" name="modal-issueid" required="required" class=" form-control" value="">
|
||||||
|
|
||||||
|
<div style="width:100%">
|
||||||
|
<textarea id="modal-notes" style="width:100%; height:300px;">
|
||||||
|
</textarea>
|
||||||
|
</div>
|
||||||
|
<button id="issu_notes" class="btn btn-success mt-3">Enregistrer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% set end = microtime(true) %}
|
||||||
|
{% set duration = end - start %}
|
||||||
|
<p>render time: {{ duration }} seconds</p>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block localjavascript %}
|
{% block localjavascript %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function showFilters() {
|
function showFilters() {
|
||||||
if($("#filters").hasClass("d-flex")) {
|
if($("#filters").hasClass("d-flex")) {
|
||||||
toshow=0;
|
toshow=0;
|
||||||
|
@ -343,16 +552,43 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
$(".issue").tooltip({
|
||||||
|
content: function() {
|
||||||
|
return $(this).data('tooltip'); // Utilise le contenu de l'attribut data-tooltip
|
||||||
|
},
|
||||||
|
items: '[data-tooltip]', // Spécifie les éléments qui déclenchent le tooltip
|
||||||
|
html: true // Autorise le HTML dans le tooltip (si nécessaire pour certains tooltips personnalisés)
|
||||||
|
});
|
||||||
|
|
||||||
// Apply Filter
|
// Apply Filter
|
||||||
function showhide() {
|
function showhide() {
|
||||||
if($("#filtermilestones").val().length !== 0) {
|
// Vue condensée
|
||||||
|
if($("#viewcondensed").is(':checked')) {
|
||||||
|
$(".issu-detail").hide();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(".issu-detail").show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Afficher masquer les jalons
|
||||||
|
if($("#filtermilestones").val().length !== 0 && $("#filtersprints").val().length === 0) {
|
||||||
$("[data-milestone]").hide();
|
$("[data-milestone]").hide();
|
||||||
$.each($("#filtermilestones").val(), function( index, value ) {
|
$.each($("#filtermilestones").val(), function( index, value ) {
|
||||||
|
console.log(value);
|
||||||
$("[data-milestone="+value+"]").show();
|
$("[data-milestone="+value+"]").show();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else $("[data-milestone]").show();
|
else $("[data-milestone]").show();
|
||||||
|
|
||||||
|
// Afficher masquer les sprints
|
||||||
|
if($("#filtersprints").val().length !== 0) {
|
||||||
|
$("[data-millestonesprint]").hide();
|
||||||
|
$.each($("#filtersprints").val(), function( index, value ) {
|
||||||
|
$("[data-millestonesprint="+value+"]").show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if($("#filtermilestones").val().length === 0)$("[data-millestonesprint]").show();
|
||||||
|
|
||||||
$(".issue").show();
|
$(".issue").show();
|
||||||
|
|
||||||
$( ".issue" ).each(function( index ) {
|
$( ".issue" ).each(function( index ) {
|
||||||
|
@ -419,6 +655,15 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($("#filtersprints").val().length!==0) {
|
||||||
|
data = $("#filtersprints").select2('data');
|
||||||
|
textfilters=textfilters+" <b>SPRINT</b> =";
|
||||||
|
$.each($("#filtersprints").val(), function( index, value ) {
|
||||||
|
if(index>0)textfilters=textfilters+" &";
|
||||||
|
textfilters=textfilters+" "+data[index].text;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if($("#filterteams").val().length!==0) {
|
if($("#filterteams").val().length!==0) {
|
||||||
data = $("#filterteams").select2('data');
|
data = $("#filterteams").select2('data');
|
||||||
textfilters=textfilters+" <b>EQUIPES</b> =";
|
textfilters=textfilters+" <b>EQUIPES</b> =";
|
||||||
|
@ -473,23 +718,61 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$("#textfilters").html(textfilters);
|
$("#textfilters").html(textfilters);
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshinfo() {
|
|
||||||
|
$(document).on('click','.viewissu',function(){
|
||||||
|
$(".submenu").hide();
|
||||||
|
url="{{path('app_scrumissue_view',{id:"xxx"})}}";
|
||||||
|
url=url.replace("xxx",$(this).data("issue"));
|
||||||
|
|
||||||
|
ModalLoad('mymodallarge','Aperçu Ticket',url);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click','.lockissu',function(){
|
||||||
|
$(".modal-title").html("#"+$(this).data("giteaid")+" - "+$(this).data("giteatitle"));
|
||||||
|
$("#modal-issueid").val($(this).data("issue"));
|
||||||
|
$("#modal-issueblocked").val("");
|
||||||
|
$("#mymodalblock").modal('show');
|
||||||
|
$("#modal-issueblocked").focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#issu_blockupdate").click(function(){
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: "{{path("app_scrum_info",{id:scrum.id})}}",
|
url: "{{path("app_scrumissue_block")}}",
|
||||||
|
data: {
|
||||||
|
id:$("#modal-issueid").val(),
|
||||||
|
issueblocked:$("#modal-issueblocked").val(),
|
||||||
|
},
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
$(".totalweight").html("0");
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function (request, status, error) {
|
||||||
|
$("#issueblocked").modal('hide');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
Object.entries(data.weights).forEach(entry => {
|
$(document).on('click','.unlockissu',function(){
|
||||||
const [key, value] = entry;
|
if (window.confirm("Souhaitez-vous enlever le blocage ?")) {
|
||||||
$("#total"+key).html(value);
|
$.ajax({
|
||||||
});
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumissue_unblock")}}",
|
||||||
|
data: {
|
||||||
|
id:$(this).data("issue"),
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function (request, status, error) {
|
||||||
|
alert("pb sur le déblocage");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$(document).on('click','.modissu',function(){
|
$(document).on('click','.modissu',function(){
|
||||||
$(".modal-title").html("#"+$(this).data("giteaid")+" - "+$(this).data("giteatitle"));
|
$(".modal-title").html("#"+$(this).data("giteaid")+" - "+$(this).data("giteatitle"));
|
||||||
|
@ -518,7 +801,7 @@
|
||||||
weight:$("#modal-issueweight").val(),
|
weight:$("#modal-issueweight").val(),
|
||||||
},
|
},
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
$("#issue"+$("#modal-issueid").val()+"-weight").html($("#modal-issueweight").val());
|
$(".issue"+$("#modal-issueid").val()+"-weight").html($("#modal-issueweight").val());
|
||||||
refreshinfo();
|
refreshinfo();
|
||||||
$("#mymodalissue").modal('hide');
|
$("#mymodalissue").modal('hide');
|
||||||
},
|
},
|
||||||
|
@ -528,6 +811,108 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(".pick-a-color").on("change", function() {
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumissue_color")}}",
|
||||||
|
data: {
|
||||||
|
id:$(this).data("issue"),
|
||||||
|
color:$(this).val(),
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function (request, status, error) {
|
||||||
|
alert("pb sur le set color");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click','.assigneissu',function(){
|
||||||
|
$(".modal-title").html("#"+$(this).data("giteaid")+" - "+$(this).data("giteatitle"));
|
||||||
|
$("#modal-issueid").val($(this).data("issue"));
|
||||||
|
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumissue_info")}}",
|
||||||
|
data: {
|
||||||
|
id:$("#modal-issueid").val(),
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
var tbassignees=[];
|
||||||
|
if(data.giteajson.assignees) {
|
||||||
|
for (let assignee of data.giteajson.assignees) {
|
||||||
|
tbassignees.push(assignee.login);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#modal-assignees').select2();
|
||||||
|
$('#modal-assignees').val(tbassignees);
|
||||||
|
$('#modal-assignees').trigger('change');
|
||||||
|
|
||||||
|
$("#mymodalassignees").modal('show');
|
||||||
|
$(".submenu").hide();
|
||||||
|
$("#modal-assignees").focus();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#issu_assigne").click(function(){
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumissue_assigne")}}",
|
||||||
|
data: {
|
||||||
|
id:$("#modal-issueid").val(),
|
||||||
|
assignees: $("#modal-assignees").val(),
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function (request, status, error) {
|
||||||
|
alert("pb sur l'affectation au ticket");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click','.notesissu',function(){
|
||||||
|
$(".modal-title").html("#"+$(this).data("giteaid")+" - "+$(this).data("giteatitle"));
|
||||||
|
$("#modal-issueid").val($(this).data("issue"));
|
||||||
|
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumissue_info")}}",
|
||||||
|
data: {
|
||||||
|
id:$("#modal-issueid").val(),
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
$('#modal-notes').val(data.notes);
|
||||||
|
|
||||||
|
$("#mymodalnotes").modal('show');
|
||||||
|
$(".submenu").hide();
|
||||||
|
$("#modal-notes").focus();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#issu_notes").click(function(){
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrumissue_notes")}}",
|
||||||
|
data: {
|
||||||
|
id:$("#modal-issueid").val(),
|
||||||
|
notes: $("#modal-notes").val(),
|
||||||
|
},
|
||||||
|
success: function(data) {
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function (request, status, error) {
|
||||||
|
alert("pb sur enregistrement du ticket");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Filter Milestones
|
// Filter Milestones
|
||||||
function filtermilestones() {
|
function filtermilestones() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -557,6 +942,35 @@
|
||||||
filtermilestones();
|
filtermilestones();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Filter Sprint
|
||||||
|
function filtersprints() {
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{ path('app_user_preference') }}",
|
||||||
|
data: {
|
||||||
|
key:'filtersprints',
|
||||||
|
id:{{scrum.id}},
|
||||||
|
value: $("#filtersprints").val()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showhide();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#filtersprints').select2({sorter: data => data.sort((a, b) => a.text.localeCompare(b.text)),});
|
||||||
|
{% if filtersprints %}
|
||||||
|
{% for sprint in filtersprints %}
|
||||||
|
$("#filtersprints").val($("#filtersprints").val().concat("{{sprint}}"));
|
||||||
|
{%endfor%}
|
||||||
|
$('#filtersprints').trigger('change');
|
||||||
|
{% endif %}
|
||||||
|
$('#filtersprints').on("select2:select", function(e) {
|
||||||
|
filtersprints();
|
||||||
|
});
|
||||||
|
$('#filtersprints').on("select2:unselect", function(e) {
|
||||||
|
filtersprints();
|
||||||
|
});
|
||||||
|
|
||||||
// Filter Teams
|
// Filter Teams
|
||||||
function filterteams() {
|
function filterteams() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -728,6 +1142,26 @@
|
||||||
filterexcludes();
|
filterexcludes();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// View condensed
|
||||||
|
{% if viewcondensed %}
|
||||||
|
$("#viewcondensed").prop( "checked", {{ viewcondensed }} )
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
$('#viewcondensed').change(function() {
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{ path('app_user_preference') }}",
|
||||||
|
data: {
|
||||||
|
key:'viewcondensed',
|
||||||
|
id:{{scrum.id}},
|
||||||
|
value: this.checked
|
||||||
|
}
|
||||||
|
}).done(function( data ) {
|
||||||
|
showhide();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Resume filtre
|
// Resume filtre
|
||||||
{% if not showfilters %}
|
{% if not showfilters %}
|
||||||
$("#filters").addClass("d-none");
|
$("#filters").addClass("d-none");
|
||||||
|
@ -739,23 +1173,28 @@
|
||||||
refreshinfo();
|
refreshinfo();
|
||||||
$("#mycontent").show();
|
$("#mycontent").show();
|
||||||
|
|
||||||
lastupdate="{{scrum.updatedate|date("Ymd H:i:s")}}";
|
lastupdate="{{updatedate|date("Ymd H:i")}}";
|
||||||
|
console.log(lastupdate);
|
||||||
|
|
||||||
|
|
||||||
// Sort columns
|
|
||||||
$( ".scrumcolumn" ).sortable({
|
$( ".scrumcolumn" ).sortable({
|
||||||
handle: ".fa-arrows-alt",
|
handle: ".issu-id",
|
||||||
connectWith: ".scrumcolumn",
|
connectWith: ".scrumcolumn",
|
||||||
cursor: "move",
|
cursor: "move",
|
||||||
update: function( event, ui ) {
|
start: function( event, ui ) {
|
||||||
|
$(".submenu").hide();
|
||||||
|
},
|
||||||
|
stop: function( event, ui ) {
|
||||||
id=$(ui.item).data("issue");
|
id=$(ui.item).data("issue");
|
||||||
oldcolumn=$(ui.item).data("column");
|
oldcolumn=$(ui.item).data("column");
|
||||||
oldmilestone=$(ui.item).data("milestone");
|
oldmilestone=$(ui.item).data("milestone");
|
||||||
|
oldsprint=$(ui.item).data("sprint");
|
||||||
newcolumn=$(ui.item).parent().data("column");
|
newcolumn=$(ui.item).parent().data("column");
|
||||||
newmilestone=$(ui.item).parent().data("milestone");
|
newmilestone=$(ui.item).parent().data("milestone");
|
||||||
console.log("ID = "+id+" = Column : "+oldcolumn+">>"+newcolumn+" = Milestone : "+oldmilestone+">>"+newmilestone );
|
newsprint=$(ui.item).parent().data("sprint");
|
||||||
|
console.log("ID = "+id+" = Column : "+oldcolumn+">>"+newcolumn+" = Milestone : "+oldmilestone+">>"+newmilestone+" = Sprint : "+oldsprint+">>"+newsprint );
|
||||||
if(oldcolumn!=newcolumn||oldmilestone!=newmilestone) {
|
|
||||||
|
|
||||||
|
if(oldcolumn!=newcolumn||oldmilestone!=newmilestone||oldsprint!=newsprint) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: "{{path("app_scrumissue_change")}}",
|
url: "{{path("app_scrumissue_change")}}",
|
||||||
|
@ -763,13 +1202,17 @@
|
||||||
id:id,
|
id:id,
|
||||||
oldcolumn:oldcolumn,
|
oldcolumn:oldcolumn,
|
||||||
oldmilestone:oldmilestone,
|
oldmilestone:oldmilestone,
|
||||||
|
oldsprint:oldsprint,
|
||||||
newcolumn:newcolumn,
|
newcolumn:newcolumn,
|
||||||
newmilestone:newmilestone,
|
newmilestone:newmilestone,
|
||||||
|
newsprint:newsprint
|
||||||
},
|
},
|
||||||
success: function(data) {
|
success: function(data) {
|
||||||
$(ui.item).data("column",newcolumn);
|
$(ui.item).data("column",newcolumn);
|
||||||
$(ui.item).data("milestone",newmilestone);
|
$(ui.item).data("milestone",newmilestone);
|
||||||
|
$(ui.item).data("sprint",newsprint);
|
||||||
if(data) lastupdate=data;
|
if(data) lastupdate=data;
|
||||||
|
console.log(lastupdate);
|
||||||
|
|
||||||
refreshinfo();
|
refreshinfo();
|
||||||
},
|
},
|
||||||
|
@ -798,9 +1241,7 @@
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var intervalId = window.setInterval(function(){
|
var intervalId = window.setInterval(function(){
|
||||||
console.log(lastupdate);
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: "{{path("app_scrumissue_ctrlchange")}}",
|
url: "{{path("app_scrumissue_ctrlchange")}}",
|
||||||
|
@ -809,12 +1250,65 @@
|
||||||
lastupdate:lastupdate
|
lastupdate:lastupdate
|
||||||
},
|
},
|
||||||
success: function(fgupdated) {
|
success: function(fgupdated) {
|
||||||
if(fgupdated) {
|
if(fgupdated=="1") {
|
||||||
$("#haveupdate").show();
|
$("#haveupdate").show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 60000);
|
}, 300000);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function refreshinfo() {
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "{{path("app_scrum_info",{id:scrum.id})}}",
|
||||||
|
success: function(data) {
|
||||||
|
html="";
|
||||||
|
$("[data-weight]").html("");
|
||||||
|
|
||||||
|
Object.entries(data.tbestim).forEach(entry => {
|
||||||
|
const [keyj, jalon] = entry;
|
||||||
|
|
||||||
|
html+='<table style="color:var(--colorftbodydark);zoom:75%; width:100%; border:1px solid var(--colorbgbodylight)">';
|
||||||
|
html+='<tr>';
|
||||||
|
html+='<td class="pl-1">'+jalon.nmjal+'</td>';
|
||||||
|
html+='<td class="pr-1" style="width:30px;text-align:right;">'+jalon.nbjrs+'</span></td>';
|
||||||
|
html+='</tr>';
|
||||||
|
|
||||||
|
nofirst=false;
|
||||||
|
Object.entries(jalon.sprints).forEach(entry => {
|
||||||
|
const [keys, sprint] = entry;
|
||||||
|
if(nofirst || sprint.idspr!=-100) {
|
||||||
|
html+='<tr>';
|
||||||
|
html+='<td class="pl-1">'+sprint.nmspr+'</td>';
|
||||||
|
html+='<td class="pr-1" style="width:30px;text-align:right;">'+sprint.nbjrs+'</span></td>';
|
||||||
|
html+='</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.entries(sprint.columns).forEach(entry => {
|
||||||
|
const [keys, column] = entry;
|
||||||
|
$("[data-weight="+column.gicol+"-"+jalon.gijal+"-"+sprint.idspr+"]").html(column.nbjrs);
|
||||||
|
|
||||||
|
});
|
||||||
|
nofirst=true;
|
||||||
|
});
|
||||||
|
|
||||||
|
html+='</table>';
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#tbestim").html(html);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function issuhover(btn,idissu) {
|
||||||
|
$(".submenu").hide();
|
||||||
|
$("#submenu"+idissu).css("display","flex");
|
||||||
|
}
|
||||||
|
|
||||||
|
function issuout(menu) {
|
||||||
|
$(menu).css("display","none");
|
||||||
|
}
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block localjavascript %}
|
||||||
|
$(document).ready(function() {
|
||||||
|
window.parent.$("#mymodalsprint").modal('hide');
|
||||||
|
});
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,52 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
{{ form_start(form) }}
|
||||||
|
{{ form_widget(form.submit) }}
|
||||||
|
<a class="btn btn-secondary" onClick="closeModal();">Annuler</a>
|
||||||
|
|
||||||
|
{% if mode=="update" %}
|
||||||
|
<a href="{{ path('app_scrumsprint_delete',{'id':scrumsprint.id}) }}"
|
||||||
|
class="btn btn-danger float-right"
|
||||||
|
data-method="delete"
|
||||||
|
data-confirm="Êtes-vous sûr de vouloir supprimer cet entregistrement ?">
|
||||||
|
Supprimer
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
{% if app.session.flashbag.has('error') %}
|
||||||
|
<div class='alert alert-danger' style='margin: 5px 0px'>
|
||||||
|
<strong>Erreur</strong><br>
|
||||||
|
{% for flashMessage in app.session.flashbag.get('error') %}
|
||||||
|
{{ flashMessage }}<br>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if app.session.flashbag.has('notice') %}
|
||||||
|
<div class='alert alert-info' style='margin: 5px 0px'>
|
||||||
|
<strong>Information</strong><br>
|
||||||
|
{% for flashMessage in app.session.flashbag.get('notice') %}
|
||||||
|
{{ flashMessage }}<br>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ form_row(form.name) }}
|
||||||
|
{{ form_row(form.giteamilestone) }}
|
||||||
|
{{ form_row(form.closed) }}
|
||||||
|
{{ form_end(form) }}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block localjavascript %}
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#scrumsprint_name").focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
window.parent.$("#mymodalsprint").modal('hide');
|
||||||
|
}
|
||||||
|
{% endblock %}
|
|
@ -1,10 +1,15 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
{{wssurl}}
|
||||||
<div id="chat" class="text-center mt-5">
|
<div id="chat" class="text-center mt-5">
|
||||||
<div class="mb-2">online</div>
|
<div class="mb-2">online</div>
|
||||||
<div id="online" style="mt-2"></div>
|
<div id="online" style="mt-2"></div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block localjavascript %}
|
||||||
{% if wssuse %}
|
{% if wssuse %}
|
||||||
<script>
|
|
||||||
var conn;
|
var conn;
|
||||||
|
|
||||||
function connect() {
|
function connect() {
|
||||||
|
@ -20,13 +25,14 @@
|
||||||
subscribe("home",1,"{{userkey}}");
|
subscribe("home",1,"{{userkey}}");
|
||||||
sendMessage({command: "alive"});
|
sendMessage({command: "alive"});
|
||||||
};
|
};
|
||||||
|
|
||||||
conn.onmessage = function(e) {
|
conn.onmessage = function(e) {
|
||||||
ret=JSON.parse(e.data);
|
ret=JSON.parse(e.data);
|
||||||
console.log(ret.log);
|
|
||||||
|
|
||||||
switch(ret.command) {
|
switch(ret.command) {
|
||||||
case "alive" :
|
case "alive" :
|
||||||
if(!$('#online'+ret.from.id).length) {
|
if(!$('#online'+ret.from.id).length) {
|
||||||
|
console.log(ret);
|
||||||
html='<img id="online'+ret.from.id+'" src="'+ret.from.avatar+'" class="avatar ml-2 mr-2" title="'+ret.from.displayname+'">';
|
html='<img id="online'+ret.from.id+'" src="'+ret.from.avatar+'" class="avatar ml-2 mr-2" title="'+ret.from.displayname+'">';
|
||||||
$("#online").append(html);
|
$("#online").append(html);
|
||||||
}
|
}
|
||||||
|
@ -57,5 +63,5 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
connect();
|
connect();
|
||||||
</script>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endblock %}
|
|
@ -66,8 +66,6 @@
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="navbarNav">
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li class="nav-item"><a href="{{path("app_scrum")}}">Scrums</a></li>
|
|
||||||
<a href="{{path("app_issue")}}">Issues</a>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -154,6 +152,10 @@
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
{{ include('Include/javascript.js.twig') }}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
{% if app.session.get('viewclosed') %}
|
{% if app.session.get('viewclosed') %}
|
||||||
|
|
Loading…
Reference in New Issue