This commit is contained in:
afornerot 2022-01-22 11:18:42 +01:00
parent dd5c13027f
commit 3fe78d7e7c
15 changed files with 1058 additions and 238 deletions

View File

@ -13,6 +13,7 @@ twig:
appCron: '%appCron%'
wssuse: '%wssuse%'
wssurl: '%wssurl%'
giteaUrl: '%giteaUrl%'

View File

@ -207,7 +207,7 @@ app_scrumcolumn_order:
path: /master/scrumcolumn/order/{scrumid}
defaults: { _controller: App\Controller\ScrumcolumnController:order }
#== Scrumoissue ========================================================================================================
#== Scrumissue ========================================================================================================
app_scrumissue_change:
path: /user/scrumissue/change
defaults: { _controller: App\Controller\ScrumissueController:change }
@ -215,3 +215,16 @@ app_scrumissue_change:
app_scrumissue_order:
path: /user/scrumissue/order
defaults: { _controller: App\Controller\ScrumissueController:order }
app_scrumissue_ctrlchange:
path: /user/scrumissue/ctrlchange
defaults: { _controller: App\Controller\ScrumissueController:ctrlchange }
#== Issue ========================================================================================================
app_issue:
path: /user/issue
defaults: { _controller: App\Controller\IssueController:list, id: 0 }
app_issuescrum:
path: /user/issuescrum/{id}
defaults: { _controller: App\Controller\IssueController:list }

View File

@ -0,0 +1,116 @@
<?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\Issue as Entity;
use App\Entity\Issueissue as Issueissue;
use App\Form\IssueType as Form;
use App\Service\giteaService;
class IssueController extends AbstractController
{
private $data = "issue";
private $route = "app_issue";
private $render = "Issue/";
private $entity = "App:Issue";
public function __construct(giteaService $giteaservice) { $this->giteaservice = $giteaservice; }
public function list($id, Request $request)
{
$em = $this->getDoctrine()->getManager();
// 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=[];
$gitealabels=[];
$giteaassignees=$em->getRepository("App:User")->findBy([],["username"=>"ASC"]);
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"]);
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"]);
$json=$scrum->getGiteajson();
$json["issues"]=$giteaissues;
$json["category"]=$scrum->getCategory();
$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($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($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);
$filterlabels = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterlabels",$id);
$filterassignees = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterassignees",$id);
return $this->render($this->render.'list.html.twig',[
"useheader" => true,
"usesidebar" => false,
"id" => $id,
"giteacategorys" => $giteacategorys,
"gitearepos" => $gitearepos,
"giteamilestones" => $giteamilestones,
"giteacolumns" => $giteacolumns,
"gitealabels" => $gitealabels,
"giteaassignees" => $giteaassignees,
"filtercategorys" => $filtercategorys,
"filterrepos" => $filterrepos,
"filtermilestones" => $filtermilestones,
"filtercolumns" => $filtercolumns,
"filterlabels" => $filterlabels,
"filterassignees" => $filterassignees,
]);
}
}

View File

@ -13,31 +13,6 @@ use App\Form\ScrumType as Form;
use App\Service\giteaService;
class ExecutionTime
{
private $startTime;
private $endTime;
public function start(){
$this->startTime = getrusage();
}
public function end(){
$this->endTime = getrusage();
}
private function runTime($ru, $rus, $index) {
return ($ru["ru_$index.tv_sec"]*1000 + intval($ru["ru_$index.tv_usec"]/1000))
- ($rus["ru_$index.tv_sec"]*1000 + intval($rus["ru_$index.tv_usec"]/1000));
}
public function __toString(){
return "This process used " . $this->runTime($this->endTime, $this->startTime, "utime") .
" ms for its computations\nIt spent " . $this->runTime($this->endTime, $this->startTime, "stime") .
" ms in system calls\n";
}
}
class ScrumController extends AbstractController
{
private $data = "scrum";
@ -50,18 +25,40 @@ class ScrumController extends AbstractController
public function list(Request $request)
{
$em = $this->getDoctrine()->getManager();
$datas = $em->getRepository($this->entity)->findAll();
/*
foreach($datas as $data) {
dump($data->getGiteajson()["name"]);
dump($this->giteaservice->getRepoNotifications($data->getGiteajson()["owner"]["login"],$data->getGiteajson()["name"]));
$scrums = $em->getRepository($this->entity)->findBy([],["name"=>"ASC"]);
$giteacategorys=[];
$gitearepos=[];
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();
}
array_push($gitearepos,$gitearepo);
}
*/
sort($giteacategorys);
$filtercategorys = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtercategorys",0);
$filterrepos = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterrepos",0);
return $this->render($this->render.'list.html.twig',[
$this->data."s" => $datas,
"useheader" => true,
"usesidebar" => false,
$this->data."s" => $scrums,
"giteacategorys" => $giteacategorys,
"gitearepos" => $gitearepos,
"filtercategorys" => $filtercategorys,
"filterrepos" => $filterrepos,
"useheader" => true,
"usesidebar" => false,
]);
}
@ -174,144 +171,18 @@ class ScrumController extends AbstractController
public function view($id,Request $request)
{
$executionTime = new ExecutionTime();
$executionTime->start();
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$data=$em->getRepository($this->entity)->find($id);
if(!$data) return $this->redirectToRoute($this->route);
// Récupérer le dernier order
$last = $em->getRepository('App:Scrumissue')->findOneBy(["scrum"=>$data], ['rowid' => 'DESC']);
if(!$last) $lastrowid=-1;
else $lastrowid=$last->getRowid();
// Récupérer la premier column scrum
$firstcolumn=$em->getRepository('App:Scrumcolumn')->findOneBy(["scrum"=>$data], ['rowid' => 'ASC']);
if(!$firstcolumn) return $this->redirectToRoute($this->route."_update",["id"=>$data->getId()]);
// Récupérer la premier column scrum
$columns=$em->getRepository('App:Scrumcolumn')->findBy(["scrum"=>$data], ['rowid' => 'ASC']);
$giteacolumns=[];
foreach($columns as $column) {
array_push($giteacolumns,$column->getGiteaid());
}
// Récupérer la orga de gitea
if(!empty($data->getGiteajson()["owner"]["email"]))
$giteaassignees=[$data->getGiteajson()["owner"]];
else
$giteaassignees=[];
$giteateams=$this->giteaservice->getOrgateams($data->getGiteajson()["owner"]["login"]);
if($giteateams&&is_array($giteateams)) {
foreach($giteateams as $team) {
$giteamembers=$this->giteaservice->getTeammembers($team->id);
if($giteamembers&&is_array($giteamembers)) {
foreach($giteamembers as $giteamember) {
if(!in_array($giteamember,$giteaassignees))
array_push($giteaassignees,$giteamember);
}
}
}
}
$giteacollaborators=$this->giteaservice->getCollaborators($data->getGiteajson()["owner"]["login"],$data->getGiteajson()["name"]);
if(!is_array($giteacollaborators)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
foreach($giteacollaborators as $giteacollaborator) {
if(!in_array($giteacollaborator,$giteaassignees))
array_push($giteaassignees,$giteacollaborator);
}
// Récupérer les milestones de gitea
$giteamilestones=$this->giteaservice->getMilestones($data->getGiteajson()["owner"]["login"],$data->getGiteajson()["name"]);
if(!is_array($giteamilestones)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
$keysort = array_column($giteamilestones, 'title');
array_multisort($keysort, SORT_DESC, $giteamilestones);
// Récupérer les labels de gitea
$gitealabels=$this->giteaservice->getLabels($data->getGiteajson()["owner"]["login"],$data->getGiteajson()["name"]);
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))
unset($gitealabels[$key]);
}
// Récupérer les issues de gitea
$giteaissues=$this->giteaservice->getIssues($data->getGiteajson()["owner"]["login"],$data->getGiteajson()["name"]);
if(!is_array($giteaissues)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
// Génération des issues
$tbgiteaissues=[];
foreach($giteaissues as $giteaissue) {
// On ne prend pas les pull request
if(!is_null($giteaissue->pull_request)) {
continue;
}
$scrumissue=$em->getRepository("App:Scrumissue")->findOneBy(["scrum"=>$data,"giteaid"=>$giteaissue->id]);
if(!$scrumissue) {
$lastrowid++;
$scrumissue=new Scrumissue();
$scrumissue->setScrum($data);
$scrumissue->setRowid($lastrowid);
$scrumissue->setGiteaid($giteaissue->id);
}
if($scrumissue->getGiteajson()["updated_at"]!=json_decode(json_encode($giteaissue), true)["updated_at"]) {
$scrumissue->setGiteanumber($giteaissue->number);
$scrumissue->setGiteastate($giteaissue->state);
$scrumissue->setGiteatitle($giteaissue->title);
if($giteaissue->milestone) {
$scrumissue->setGiteamilestone($giteaissue->milestone->id);
$scrumissue->setGiteamilestonename($giteaissue->milestone->title);
}
else {
$scrumissue->setGiteamilestone(null);
$scrumissue->setGiteamilestonename(null);
}
$scrumissue->setGiteajson(json_decode(json_encode($giteaissue), true));
$em->persist($scrumissue);
$em->flush();
$havecolumn=false;
foreach($giteaissue->labels as $gitealabel) {
$scrumcolumn=$em->getRepository('App:Scrumcolumn')->findOneBy(["giteaid"=>$gitealabel->id]);
if($scrumcolumn) {
$havecolumn=true;
$scrumissue->setScrumcolumn($scrumcolumn);
break;
}
}
if(!$havecolumn) $scrumissue->setScrumcolumn($firstcolumn);
// Sauvegarde de l'issue
$em->persist($scrumissue);
$em->flush();
}
array_push($tbgiteaissues,$giteaissue->number);
}
$scrumissues=$data->getScrumissues();
foreach($scrumissues as $scrumissue) {
if(!in_array($scrumissue->getGiteanumber(),$tbgiteaissues)) {
$em->remove($scrumissue);
$em->flush();
}
}
$em->getRepository("App:Scrum")->getGitea($data,$giteaassignees,$giteacolumns,$giteamilestones,$gitealabels);
// Préférences utilisateur
$filtermilestones = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtermilestones",$id);
$filterlabels = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterlabels",$id);
$filterassignees = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterassignees",$id);
$executionTime->end();
//dump($executionTime->__toString());
return $this->render($this->render.'view.html.twig', [
'useheader' => true,
'usesidebar' => false,
@ -335,12 +206,6 @@ class ScrumController extends AbstractController
}
if ($form->get('submit')->isClicked() && ($mode=="submit" || $mode=="update")) {
// On s'assure que le label ne contient pas des caractères speciaux
$string = preg_replace('~[^ éèêôöàïî\'@a-zA-Z0-9._-]~', '', $data->getName());
if($string!=$data->getName())
{
$form->addError(new FormError('Caractères interdit dans ce label'));
}
}
if ($form->get('submit')->isClicked() && !$form->isValid()) {

View File

@ -35,6 +35,7 @@ class ScrumcolumnController extends AbstractController
// Récupérer les repos 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='/ninegitea/logout'>reconnecter</a>");
// Création du formulaire
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","gitealabels"=>$gitealabels));

View File

@ -32,39 +32,55 @@ class ScrumissueController extends AbstractController
$oldmilestone=$request->get('oldmilestone');
$newmilestone=$request->get('newmilestone');
// Rechercher l'issue en cours
$scrumissue=$em->getRepository("App:Scrumissue")->find($id);
if(!$scrumissue) return new JsonResponse(['message' => 'No Issue'], 403);
if($oldcolumn!=$newcolumn||$oldmilestone!=$newmilestone) {
// Rechercher l'issue en cours
$scrumissue=$em->getRepository("App:Scrumissue")->find($id);
if(!$scrumissue) return new JsonResponse(['message' => 'No Issue'], 403);
// Récupérer la liste des labels de l'issue
$gitealabels=$this->giteaservice->getIssuelabels($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber());
if(!is_array($gitealabels)) return new JsonResponse(['message' => 'No API getIssuelabels'], 403);
// Récupérer la liste des labels de l'issue
$gitealabels=$this->giteaservice->getIssuelabels($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber());
if(!is_array($gitealabels)) return new JsonResponse(['message' => 'No API getIssuelabels'], 403);
// Remplacer l'ancien column par la nouvelle
$newgitelabels=[];
$haveold=false;
foreach($gitealabels as $gitealabel) {
if($gitealabel->id!=$oldcolumn) array_push($newgitelabels,$gitealabel->id);
else $haveold=true;
// Remplacer l'ancien column par la nouvelle
if($oldcolumn!=$newcolumn) {
$newgitelabels=[];
$haveold=false;
foreach($gitealabels as $gitealabel) {
if($gitealabel->id!=$oldcolumn) array_push($newgitelabels,$gitealabel->id);
else $haveold=true;
}
if(!in_array($newcolumn,$newgitelabels)) array_push($newgitelabels,intval($newcolumn));
// Supprimer l'ancien label
if($haveold) {
$return=$this->giteaservice->deleteIssuelabel($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber(),$oldcolumn);
if(!$return) return new JsonResponse(['message' => 'No API deleteIssuelabel'], 403);
}
// Mettre à jour les labels
$return=$this->giteaservice->putIssuelabels($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber(),$newgitelabels);
if(!$return) return new JsonResponse(['message' => 'No API putIssuelabels'], 403);
}
// Mettre à jour le milestone
if($oldmilestone!=$newmilestone) {
$patchs=["milestone"=>intval($newmilestone)];
$return=$this->giteaservice->patchIssue($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber(),$patchs);
if(!$return) return new JsonResponse(['message' => 'No API patchIssue'], 403);
}
// 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());
if(!$giteaissue) return new JsonResponse(['message' => 'No API getIssue'], 403);
$updatedate=new \DateTime($giteaissue->updated_at);
if($updatedate > $scrumissue->getScrum()->getUpdatedate()) {
$scrumissue->getScrum()->setUpdatedate(new \DateTime($giteaissue->updated_at));
$em->persist($scrumissue->getScrum());
$em->flush();
return new JsonResponse($updatedate->format("Ymd H:i:s"));
}
}
if(!in_array($newcolumn,$newgitelabels)) array_push($newgitelabels,intval($newcolumn));
// Supprimer l'ancien label
if($haveold) {
$return=$this->giteaservice->deleteIssuelabel($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber(),$oldcolumn);
if(!$return) return new JsonResponse(['message' => 'No API deleteIssuelabel'], 403);
}
// Mettre à jour les labels
$return=$this->giteaservice->putIssuelabels($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber(),$newgitelabels);
if(!$return) return new JsonResponse(['message' => 'No API putIssuelabels'], 403);
// Mettre à jour le milestone
$patchs=["milestone"=>intval($newmilestone)];
$return=$this->giteaservice->patchIssue($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber(),$patchs);
if(!$return) return new JsonResponse(['message' => 'No API patchIssue'], 403);
return new JsonResponse();
return new JsonResponse(false);
}
public function order(Request $request)
@ -92,4 +108,40 @@ class ScrumissueController extends AbstractController
return new JsonResponse();
}
public function ctrlchange(Request $request)
{
$em = $this->getDoctrine()->getManager();
$id=$request->get('id');
$lastupdate=new \DateTime($request->get('lastupdate'));
$scrum=$em->getRepository("App:Scrum")->find($id);
if(!$scrum) return new JsonResponse(['message' => 'No Scrum'], 403);
$giteaissues=$this->giteaservice->getIssues($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
if(!is_array($giteaissues)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
foreach($giteaissues as $giteaissue) {
// 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)
return new JsonResponse(true);
}
return new JsonResponse(false);
}
}

View File

@ -29,6 +29,18 @@ class Scrum
*/
private $name;
/**
* @ORM\Column(name="category", type="string", nullable=true)
*
*/
private $category;
/**
* @ORM\Column(name="updatedate", type="datetime", nullable=true)
*
*/
private $updatedate;
/**
* @ORM\Column(type="integer")
*/
@ -70,9 +82,9 @@ class Scrum
if($id!=$issue->getGiteamilestone()) {
$id=$issue->getGiteamilestone();
$label=($issue->getGiteamilestonename()?$issue->getGiteamilestonename():"Aucun");
$tab[$id]=[$label,0];
$tab[$id]=["Jalon",$label,0];
}
$tab[$id][1]=$tab[$id][1]+1;
$tab[$id][2]=$tab[$id][2]+1;
}
return $tab;
@ -228,4 +240,28 @@ class Scrum
return $this;
}
public function getUpdatedate(): ?\DateTimeInterface
{
return $this->updatedate;
}
public function setUpdatedate(?\DateTimeInterface $updatedate): self
{
$this->updatedate = $updatedate;
return $this;
}
public function getCategory(): ?string
{
return $this->category;
}
public function setCategory(?string $category): self
{
$this->category = $category;
return $this;
}
}

View File

@ -26,6 +26,12 @@ class ScrumType extends AbstractType
]
);
$builder->add('category',
TextType::class, [
"label" =>"Categorie",
]
);
$builder->add('name',
TextType::class, [
"label" =>"Nom",

View File

@ -5,11 +5,158 @@ namespace App\Repository;
use App\Entity\Scrum;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
use App\Service\giteaService;
use App\Entity\Scrumissue as Scrumissue;
class ScrumRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
public function __construct(ManagerRegistry $registry,giteaService $giteaservice)
{
parent::__construct($registry, Scrum::class);
$this->giteaservice = $giteaservice;
}
public function getGitea($scrum,&$giteaassignees,&$giteacolumns,&$giteamilestones,&$gitealabels) {
// Récupérer le dernier order
$last = $this->_em->getRepository('App:Scrumissue')->findOneBy(["scrum"=>$scrum], ['rowid' => 'DESC']);
if(!$last) $lastrowid=-1;
else $lastrowid=$last->getRowid();
// Récupérer la premier column scrum
$firstcolumn=$this->_em->getRepository('App:Scrumcolumn')->findOneBy(["scrum"=>$scrum], ['rowid' => 'ASC']);
if(!$firstcolumn) return $this->redirectToRoute($this->route."_update",["id"=>$scrum->getId()]);
// Récupérer la premier column scrum
$columns=$this->_em->getRepository('App:Scrumcolumn')->findBy(["scrum"=>$scrum], ['rowid' => 'ASC']);
$giteacolumns=[];
foreach($columns as $column) {
array_push($giteacolumns,$column->getGiteaid());
}
// Récupérer la orga de gitea
if(!empty($scrum->getGiteajson()["owner"]["email"]))
$giteaassignees=[$scrum->getGiteajson()["owner"]];
else
$giteaassignees=[];
$giteateams=$this->giteaservice->getOrgateams($scrum->getGiteajson()["owner"]["login"]);
if($giteateams&&is_array($giteateams)) {
foreach($giteateams as $team) {
$giteamembers=$this->giteaservice->getTeammembers($team->id);
if($giteamembers&&is_array($giteamembers)) {
foreach($giteamembers as $giteamember) {
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) {
if(!in_array($giteacollaborator,$giteaassignees))
array_push($giteaassignees,$giteacollaborator);
}
// Récupérer les milestones 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='/ninegitea/logout'>reconnecter</a>");
$keysort = array_column($giteamilestones, 'title');
array_multisort($keysort, SORT_DESC, $giteamilestones);
// 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='/ninegitea/logout'>reconnecter</a>");
foreach($gitealabels as $key => $gitealabel) {
if(in_array($gitealabel->id,$giteacolumns))
unset($gitealabels[$key]);
}
// Récupérer les issues de gitea
$giteaissues=$this->giteaservice->getIssues($scrum->getGiteajson()["owner"]["login"],$scrum->getGiteajson()["name"]);
if(!is_array($giteaissues)) die("Probleme de connexion avec gitea veuillez vous <a href='/ninegitea/logout'>reconnecter</a>");
// Génération des issues
$tbgiteaissues=[];
$fgscrumupdate=false;
$datescrumupdate=new \DateTime();
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]);
if(!$scrumissue) {
$lastrowid++;
$scrumissue=new Scrumissue();
$scrumissue->setScrum($scrum);
$scrumissue->setRowid($lastrowid);
$scrumissue->setGiteaid($giteaissue->id);
}
$fgissueupdated=false;
if($scrumissue->getGiteajson()["updated_at"]!=json_decode(json_encode($giteaissue), true)["updated_at"])
$fgissueupdated=true;
if($giteaissue->milestone&&$scrumissue->getGiteamilestonename()!=$giteaissue->milestone->title)
$fgissueupdated=true;
if(!$giteaissue->milestone&&!is_null($scrumissue->getGiteamilestone()))
$fgissueupdated=true;
//$fgissueupdated=true;
if($fgissueupdated) {
$fgscrumupdate=true;
if($scrumissue->getGiteajson()["updated_at"]>$datescrumupdate)
$datescrumupdate=$scrumissue->getGiteajson()["updated_at"];
$scrumissue->setGiteanumber($giteaissue->number);
$scrumissue->setGiteastate($giteaissue->state);
$scrumissue->setGiteatitle($giteaissue->title);
if($giteaissue->milestone) {
$scrumissue->setGiteamilestone($giteaissue->milestone->id);
$scrumissue->setGiteamilestonename($giteaissue->milestone->title);
}
else {
$scrumissue->setGiteamilestone(null);
$scrumissue->setGiteamilestonename(null);
}
$scrumissue->setGiteajson(json_decode(json_encode($giteaissue), true));
$this->_em->persist($scrumissue);
$this->_em->flush();
$havecolumn=false;
foreach($giteaissue->labels as $gitealabel) {
$scrumcolumn=$this->_em->getRepository('App:Scrumcolumn')->findOneBy(["giteaid"=>$gitealabel->id]);
if($scrumcolumn) {
$havecolumn=true;
$scrumissue->setScrumcolumn($scrumcolumn);
break;
}
}
if(!$havecolumn) $scrumissue->setScrumcolumn($firstcolumn);
// Sauvegarde de l'issue
$this->_em->persist($scrumissue);
$this->_em->flush();
}
array_push($tbgiteaissues,$giteaissue->number);
}
$scrumissues=$scrum->getScrumissues();
foreach($scrumissues as $scrumissue) {
if(!in_array($scrumissue->getGiteanumber(),$tbgiteaissues)) {
$this->_em->remove($scrumissue);
$this->_em->flush();
}
}
if($fgscrumupdate) {
$scrum->setUpdatedate($datescrumupdate);
$this->_em->persist($scrum);
$this->_em->flush();
}
}
}

View File

@ -176,6 +176,13 @@ class giteaService
}
public function getissue($owner,$name,$index) {
$apiurl = $this->url."/repos/$owner/$name/issues/$index";
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
if(!$response||$response->code!="200") return false;
else return $response->body;
}
public function getissuelabels($owner,$name,$index) {
$apiurl = $this->url."/repos/$owner/$name/issues/$index/labels";
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));

View File

@ -0,0 +1,421 @@
{% extends "base.html.twig" %}
{% block localstyle %}
.tag {
border-radius: 5px;
padding: 8px 8px;
margin-bottom: 5px;
display: inline-block;
min-width: 35px;
text-align: center;
color: #ffffff !important;
zoom: 80%;
}
.tag i {
margin-right:5px;
}
.assignee {
width:30px;
margin: 5px 5px 0px 0px;
}
{% endblock %}
{% block body %}
<div class="d-flex justify-content-start mt-3">
<div style="width:200px" class="pr-2">
<label class="control-label">Filtre TICKET</label>
<input type="number" id="filterticket" class=" form-control">
</div>
{% if id == 0 %}
<div style="width:300px" class="pr-2">
<label class="control-label">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:300px" class="pr-2">
<label class="control-label">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:600px" class="pr-2">
<label class="control-label">Filtre JALONS</label>
<select id="filtermilestones" multiple="multiple" class="form-control">
{% for giteamilestone in giteamilestones %}
<option value="{{giteamilestone.id}}">{{giteamilestone.title}}</option>
{% endfor %}
</select>
</div>
<div style="width:300px" class="pr-2">
<label class="control-label">Filtre STATUTS</label>
<select id="filtercolumns" multiple="multiple" class="form-control">
{% for giteacolumn in giteacolumns %}
<option value="{{giteacolumn}}">{{giteacolumn}}</option>
{% endfor %}
</select>
</div>
<div style="width:300px" class="pr-2">
<label class="control-label">Filtre ETIQUETTES</label>
<select id="filterlabels" multiple="multiple" class="form-control">
{% for gitealabel in gitealabels %}
{% if gitealabel not in giteacolumns %}
<option value="{{gitealabel}}">{{gitealabel}}</option>
{% endif %}
{% endfor %}
</select>
</div>
<div style="width:300px" class="pr-2">
<label class="control-label">Filtre AFFECTATIONS</label>
<select id="filterassignees" multiple="multiple" class="form-control">
{% for giteaassignee in giteaassignees %}
<option value="{{giteaassignee.username}}">{{giteaassignee.username}}</option>
{% endfor %}
</select>
</div>
</div>
<div class="mt-4" style="zoom:80%">
<table class="table table-striped table-bordered table-hover" id="dataTables" style="width:100%">
<thead>
<tr>
<th class="no-sort"></th>
{%if id==0 %}<th style="width:100px">Projet</th>{%endif%}
<th style="width:200px">Jalon</th>
<th>Statut</th>
<th class="no-string">N°</th>
<th>Titre</th>
<th style="width:135px">Affecté à</th>
<th>Etiquettes</th>
</tr>
</thead>
<tbody>
{% for gitearepo in gitearepos %}
{% for giteaissue in gitearepo.issues %}
{% set dataticket = giteaissue.number %}
{% set datarepo = gitearepo.id %}
{% if giteaissue.milestone %}
{% set datamilestone = giteaissue.milestone.id %}
{%else%}
{% set datamilestone = gitearepo.full_name %}
{%endif%}
{% set statut = "Backlog" %}
{% set labels = "" %}
{% set datalabels = "" %}
{% for label in giteaissue.labels %}
{% if label.id in gitearepo.columns %}
{% set statut= label.name %}
{% else %}
{% set labels=labels~'<span class="btn-link tag mr-1" style="background-color:#'~label.color~'"><i class="fas fa-tag"></i>'~label.name~'</span>' %}
{% set datalabels=datalabels~','~label.name %}
{% endif %}
{% endfor %}
{% set dataassignees="" %}
{% for assignee in giteaissue.assignees %}
{% set dataassignees=dataassignees~','~assignee.username %}
{% endfor %}
<tr data-category="{{gitearepo.category}}" data-repo="{{datarepo}}" data-milestone="{{datamilestone}}" data-ticket="{{dataticket}}" data-column="{{statut}}" data-labels="{{datalabels}}" data-assignees="{{dataassignees}}">
<td>
<a target="_blank" class="btn btn-link fa fa-file" href="{{giteaissue.html_url}}"></a>
</td>
{%if id==0 %}<td>{{ gitearepo.full_name }}</td>{%endif%}
<td>{% if giteaissue.milestone %}{{ giteaissue.milestone.title }} {%endif%}</td>
<td>{{ statut }}</td>
<td>{{ giteaissue.number }}</td>
<td>{{ giteaissue.title }}</td>
<td>
{% for assignee in giteaissue.assignees %}
<img src="{{assignee.avatar_url}}" class="assignee" title="{{assignee.username}}">
{% endfor %}
</td>
<td>{{ labels|raw }}</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{% block localjavascript %}
var table;
function showhide() {
ticketfilter=$("#filterticket").val();
categoryfilters=$("#filtercategorys").val();
repofilters=$("#filterrepos").val();
milestonefilters=$("#filtermilestones").val();
columnfilters=$("#filtercolumns").val();
labelfilters=$("#filterlabels").val();
assigneefilters=$("#filterassignees").val();
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex, rowObj, counter) {
el=table.row(dataIndex).nodes().to$();
{% if id == 0 %}
category = $(el).data('category');
repo = $(el).data('repo');
{% endif %}
ticket= $(el).data('ticket');
milestone = $(el).data('milestone');
column = $(el).data('column');
labels = $(el).data('labels').split(',');
assignees = $(el).data('assignees').split(',');
toreturn=true;
{% if id == 0 %}
if(categoryfilters.length!==0 && jQuery.inArray(category.toString(), categoryfilters )<0) {
toreturn=false;
}
if(repofilters.length!==0 && jQuery.inArray(repo.toString(), repofilters )<0) {
toreturn=false;
}
{% endif %}
if(ticketfilter.length!==0 && ticket.toString()!=ticketfilter) {
toreturn=false;
}
if(milestonefilters.length!==0 && jQuery.inArray(milestone.toString(), milestonefilters )<0) {
toreturn=false;
}
if(columnfilters.length!==0 && jQuery.inArray(column.toString(), columnfilters )<0) {
toreturn=false;
}
if(toreturn&&(labelfilters.length!==0||assigneefilters.length!==0)) {
if(labelfilters.length!==0) {
toreturn=false;
$.each(labelfilters, function( index, value ) {
if(jQuery.inArray(value, labels )>0) {
toreturn=true;
}
});
}
if(assigneefilters.length!==0&&toreturn) {
toreturn=false;
$.each(assigneefilters, function( index, value ) {
if(jQuery.inArray(value, assignees )>0) {
toreturn=true;
}
});
}
}
return toreturn;
});
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() {
$.ajax({
method: "POST",
url: "{{ path('app_user_preference') }}",
data: {
key:'filtermilestones',
id:{{id}},
value: $("#filtermilestones").val()
}
});
showhide();
}
function filtercolumns() {
$.ajax({
method: "POST",
url: "{{ path('app_user_preference') }}",
data: {
key:'filtercolumns',
id:{{id}},
value: $("#filtercolumns").val()
}
});
showhide();
}
function filterlabels() {
$.ajax({
method: "POST",
url: "{{ path('app_user_preference') }}",
data: {
key:'filterlabels',
id:{{id}},
value: $("#filterlabels").val()
}
});
showhide();
}
function filterassignees() {
$.ajax({
method: "POST",
url: "{{ path('app_user_preference') }}",
data: {
key:'filterassignees',
id:{{id}},
value: $("#filterassignees").val()
}
});
showhide();
}
$(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() {
showhide();
});
$('#filtermilestones').select2();
{% if filtermilestones %}
{% for milestone in filtermilestones %}
$("#filtermilestones").val($("#filtermilestones").val().concat("{{milestone}}"));
{%endfor%}
$('#filtermilestones').trigger('change');
{% endif %}
$('#filtermilestones').on("select2:select", function(e) {
filtermilestones();
});
$('#filtermilestones').on("select2:unselect", function(e) {
filtermilestones();
});
$('#filtercolumns').select2();
{% if filtercolumns %}
{% for column in filtercolumns %}
$("#filtercolumns").val($("#filtercolumns").val().concat("{{column}}"));
{%endfor%}
$('#filtercolumns').trigger('change');
{% endif %}
$('#filtercolumns').on("select2:select", function(e) {
filtercolumns();
});
$('#filtercolumns').on("select2:unselect", function(e) {
filtercolumns();
});
$('#filterlabels').select2();
{% if filterlabels %}
{% for label in filterlabels %}
$("#filterlabels").val($("#filterlabels").val().concat("{{label}}"));
{%endfor%}
$('#filterlabels').trigger('change');
{% endif %}
$('#filterlabels').on("select2:select", function(e) {
filterlabels();
});
$('#filterlabels').on("select2:unselect", function(e) {
filterlabels();
});
$('#filterassignees').select2();
{% if filterassignees %}
{% for assignee in filterassignees %}
$("#filterassignees").val($("#filterassignees").val().concat("{{assignee}}"));
{%endfor%}
$('#filterassignees').trigger('change');
{% endif %}
$('#filterassignees').on("select2:select", function(e) {
filterassignees();
});
$('#filterassignees').on("select2:unselect", function(e) {
filterassignees();
});
table = $('#dataTables').DataTable({
columnDefs: [ { "targets": "no-sort", "orderable": false }, { "targets": "no-string", "type" : "num" } ],
responsive: true,
iDisplayLength: 100,
order: [[ 1, "asc" ]],
});
showhide();
});
{% endblock %}

View File

@ -51,6 +51,7 @@
</div>
<div class="card-body">
{{ form_row(form.category) }}
{{ form_row(form.name) }}
{{ form_row(form.giteaid) }}
{{ form_row(form.users) }}
@ -81,6 +82,7 @@
{% block localjavascript %}
$(document).ready(function() {
$("#scrum_giteaid").select2();
$("#scrum_name").focus();
{% if mode=="update" %}
loadscrumcolumns();

View File

@ -1,47 +1,168 @@
{% extends "base.html.twig" %}
{% block localstyle %}
hr { margin:5px 0px 5px 0px; }
{% endblock %}
{% block body %}
<div class="mt-1 mb-3">
<a class="btn btn-success btn-sm" href={{ path('app_scrum_submit') }}><i class="fa fa-plus mr-2"></i>Ajouter un Scrum</a>
<div class="d-flex justify-content-start mt-3">
<div class="pr-2">
<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>
</div>
<div style="width:300px" class="pr-2">
<label class="control-label">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:300px" class="pr-2">
<label class="control-label">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>
</div>
<div id="grid" class="margin:auto">
{% for scrum in scrums %}
<div class="card float-left mb-1 mr-1" style="width:374px">
<div class="card-header">
<a href="{{path('app_scrum_view',{id:scrum.id})}}">{{scrum.name}}</a>
<a class="float-right" href="{{path('app_scrum_update',{id:scrum.id})}}"><i class="fas fa-file"></i></a>
</div>
<div class="card-body">
<small>
<p style="min-height:35px">
{{scrum.giteajson.description}}</p>
Nombre de tickets = {{ scrum.scrumissues|length}}<br>
{% for statistique in scrum.statistique %}
{% if loop.first %}<hr>{%endif%}
{{ statistique[0] }} = {{ statistique[1] }}<br>
{% endfor %}
</small>
</div>
<div class="card-footer small">
<a href="{{scrum.giteajson.html_url}}" target="_blank"">{{scrum.giteajson.html_url}}</a>
</div>
</div>
{% endfor %}
<div class="mt-4" style="zoom:80%">
<table class="table table-striped table-bordered table-hover" id="dataTables" style="width:100%">
<thead>
<tr>
<th class="no-sort"></th>
<th style="width:100px">Catégorie</th>
<th style="width:200px">Projet</th>
<th>Description</th>
<th style="width:100px" class="no-string">Tickets</th>
</tr>
</thead>
<tbody>
{% for scrum in scrums %}
<tr data-category="{{scrum.category}}" data-repo="{{scrum.giteaid}}">
<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_issuescrum',{id:scrum.id})}}"><i class="fas fa-ticket-alt fa-2x mr-1"></i></a>
<a href="{{path('app_scrum_update',{id:scrum.id})}}"><i class="fas fa-file fa-2x"></i></a>
</td>
<td>
{{scrum.category}}
</td>
<td>
{{scrum.name}}
</td>
<td>
{{scrum.giteajson.description}}
</td>
<td>
{{scrum.giteajson.open_issues_count}}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{% block localjavascript %}
$(document).ready(function() {
$('#grid').masonry({
itemSelector: '.card',
var table;
function showhide() {
categoryfilters=$("#filtercategorys").val();
repofilters=$("#filterrepos").val();
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex, rowObj, counter) {
el=table.row(dataIndex).nodes().to$();
category = $(el).data('category');
repo = $(el).data('repo');
toreturn=true;
if(categoryfilters.length!==0 && jQuery.inArray(category.toString(), categoryfilters )<0) {
toreturn=false;
}
if(repofilters.length!==0 && jQuery.inArray(repo.toString(), repofilters )<0) {
toreturn=false;
}
return toreturn;
});
table.draw();
//$.fn.dataTable.ext.search.pop();
}
function filtercategorys() {
$.ajax({
method: "POST",
url: "{{ path('app_user_preference') }}",
data: {
key:'filtercategorys',
id:0,
value: $("#filtercategorys").val()
}
});
showhide();
}
function filterrepos() {
$.ajax({
method: "POST",
url: "{{ path('app_user_preference') }}",
data: {
key:'filterrepos',
id:0,
value: $("#filterrepos").val()
}
});
showhide();
}
$(document).ready(function() {
$('#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();
});
table = $('#dataTables').DataTable({
columnDefs: [ { "targets": "no-sort", "orderable": false }, { "targets": "no-string", "type" : "num" } ],
responsive: true,
iDisplayLength: 100,
order: [[ 1, "asc" ]],
});
showhide();
});
{% endblock %}

View File

@ -38,6 +38,11 @@
{% endblock %}
{% block body %}
<div id="haveupdate" style="display:none" class="alert alert-danger pr-2 mt-3">
Votre projet a été mise à jour par un tier. Souhaitez-vous raffraichir votre projet ?<br>
<a href="{{path('app_scrum_view',{id:scrum.id})}}" class="btn btn-success mt-3">Rafraichir</a>
</div>
<div class="d-flex justify-content-start mt-3">
<div style="width:585px" class="pr-2">
<label class="control-label">Filtre JALONS</label>
@ -66,6 +71,8 @@
{% endfor %}
</select>
</div>
<a href="{{giteaUrl}}/{{scrum.giteajson.owner.login}}/{{scrum.giteajson.name}}/issues/new" class="btn btn-success">Nouveau<br>Ticket</a>
</div>
{% for column in scrum.scrumcolumns %}
@ -285,6 +292,8 @@
// Appliy filters
showhide();
lastupdate="{{scrum.updatedate|date("Ymd H:i:s")}}";
// Sort columns
$( ".scrumcolumn" ).sortable({
handle: ".fa-arrows-alt",
@ -299,6 +308,7 @@
console.log("ID = "+id+" = Column : "+oldcolumn+">>"+newcolumn+" = Milestone : "+oldmilestone+">>"+newmilestone );
if(oldcolumn!=newcolumn||oldmilestone!=newmilestone) {
$.ajax({
method: "POST",
url: "{{path("app_scrumissue_change")}}",
@ -309,9 +319,10 @@
newcolumn:newcolumn,
newmilestone:newmilestone,
},
success: function() {
success: function(data) {
$(ui.item).data("column",newcolumn);
$(ui.item).data("milestone",newmilestone);
if(data) lastupdate=data;
},
error: function (request, status, error) {
$( ".scrumcolumn" ).sortable('cancel');
@ -337,6 +348,25 @@
}
});
}
});
});
var intervalId = window.setInterval(function(){
console.log(lastupdate);
$.ajax({
method: "POST",
url: "{{path("app_scrumissue_ctrlchange")}}",
data: {
id:{{scrum.id}},
lastupdate:lastupdate
},
success: function(fgupdated) {
if(fgupdated) {
$("#haveupdate").show();
}
}
});
}, 60000);
});
{% endblock %}

View File

@ -65,7 +65,9 @@
{% endif %}
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="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>
</div>