mise en oeuvre des estimations de tickets
This commit is contained in:
parent
3fd8afbc8f
commit
6df0706729
7
src/ninegitea-1.0/composer.lock
generated
7
src/ninegitea-1.0/composer.lock
generated
@ -3613,6 +3613,7 @@
|
||||
"mail",
|
||||
"mailer"
|
||||
],
|
||||
"abandoned": "symfony/mailer",
|
||||
"time": "2019-11-12T09:31:26+00:00"
|
||||
},
|
||||
{
|
||||
@ -5226,6 +5227,7 @@
|
||||
"symfony",
|
||||
"words"
|
||||
],
|
||||
"abandoned": "EnglishInflector from the String component",
|
||||
"time": "2020-05-20T17:43:50+00:00"
|
||||
},
|
||||
{
|
||||
@ -7293,6 +7295,7 @@
|
||||
],
|
||||
"description": "Symfony SwiftmailerBundle",
|
||||
"homepage": "http://symfony.com",
|
||||
"abandoned": "symfony/mailer",
|
||||
"time": "2019-11-14T16:18:31+00:00"
|
||||
},
|
||||
{
|
||||
@ -8362,12 +8365,12 @@
|
||||
"version": "1.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozart/assert.git",
|
||||
"url": "https://github.com/webmozarts/assert.git",
|
||||
"reference": "9dc4f203e36f2b486149058bade43c851dd97451"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozart/assert/zipball/9dc4f203e36f2b486149058bade43c851dd97451",
|
||||
"url": "https://api.github.com/repos/webmozarts/assert/zipball/9dc4f203e36f2b486149058bade43c851dd97451",
|
||||
"reference": "9dc4f203e36f2b486149058bade43c851dd97451",
|
||||
"shasum": ""
|
||||
},
|
||||
|
@ -164,6 +164,11 @@ app_group_select:
|
||||
path: /user/group/select
|
||||
defaults: { _controller: App\Controller\GroupController:select }
|
||||
|
||||
#== Report =======================================================================================================
|
||||
app_report:
|
||||
path: /user/report/{id}
|
||||
defaults: { _controller: App\Controller\ReportController:list }
|
||||
|
||||
#== Scrum ========================================================================================================
|
||||
app_scrum:
|
||||
path: /user/scrum
|
||||
@ -181,6 +186,10 @@ 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:
|
||||
path: /master/scrum/update/{id}
|
||||
defaults: { _controller: App\Controller\ScrumController:update }
|
||||
@ -265,6 +274,14 @@ app_scrumissue_order:
|
||||
path: /user/scrumissue/order
|
||||
defaults: { _controller: App\Controller\ScrumissueController:order }
|
||||
|
||||
app_scrumissue_info:
|
||||
path: /user/scrumissue/info
|
||||
defaults: { _controller: App\Controller\ScrumissueController:info }
|
||||
|
||||
app_scrumissue_update:
|
||||
path: /user/scrumissue/update
|
||||
defaults: { _controller: App\Controller\ScrumissueController:update }
|
||||
|
||||
app_scrumissue_ctrlchange:
|
||||
path: /user/scrumissue/ctrlchange
|
||||
defaults: { _controller: App\Controller\ScrumissueController:ctrlchange }
|
||||
|
@ -64,6 +64,19 @@ class IssueController extends AbstractController
|
||||
$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) {
|
||||
|
310
src/ninegitea-1.0/src/Controller/ReportController.php
Executable file
310
src/ninegitea-1.0/src/Controller/ReportController.php
Executable file
@ -0,0 +1,310 @@
|
||||
<?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\Scrum as Entity;
|
||||
use App\Entity\Scrumissue as Scrumissue;
|
||||
use App\Form\ScrumType as Form;
|
||||
|
||||
use App\Service\giteaService;
|
||||
|
||||
class ReportController extends AbstractController
|
||||
{
|
||||
public function __construct(giteaService $giteaservice) { $this->giteaservice = $giteaservice; }
|
||||
|
||||
public function list($id,Request $request)
|
||||
{
|
||||
set_time_limit(0);
|
||||
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$scrum = $em->getRepository("App:Scrum")->find($id);
|
||||
$repoid = $scrum->getGiteaid();
|
||||
$repoowner = $scrum->getGiteajson()["owner"]["login"];
|
||||
$reponame = $scrum->getGiteajson()["name"];
|
||||
|
||||
$repo=$this->giteaservice->getRepo($repoid);
|
||||
$issues=$this->giteaservice->getIssues($repoowner,$reponame,"?state=all");
|
||||
|
||||
foreach($issues as $keyissue => $issue) {
|
||||
$issues[$keyissue]->body = $this->giteaservice->markdown("/".$scrum->getGiteajson()["full_name"],"comment",$issues[$keyissue]->body);
|
||||
$issues[$keyissue]->comments=$this->giteaservice->getIssueComments($repoowner,$reponame,$issue->number);
|
||||
foreach($issues[$keyissue]->comments as $keycomment => $comment) {
|
||||
$issues[$keyissue]->comments[$keycomment]->body=$this->giteaservice->markdown("/".$scrum->getGiteajson()["full_name"],"comment",$issues[$keyissue]->comments[$keycomment]->body);
|
||||
}
|
||||
|
||||
$issues[$keyissue]->timelines=$this->giteaservice->getIssueTimelines($repoowner,$reponame,$issue->number);
|
||||
}
|
||||
|
||||
// Affichage du formulaire
|
||||
return $this->render('Report/list.html.twig', [
|
||||
'useheader' => false,
|
||||
'usesidebar' => false,
|
||||
'maxwidth' => true,
|
||||
'repo' => $repo,
|
||||
'issues' => $issues,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function submit(Request $request)
|
||||
{
|
||||
// Initialisation de l'enregistrement
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$data = new Entity();
|
||||
|
||||
// Récupérer les repos de gitea
|
||||
$gitearepos=$this->giteaservice->getRepos();
|
||||
|
||||
// Création du formulaire
|
||||
$form = $this->createForm(Form::class,$data,array("mode"=>"submit","gitearepos"=>$gitearepos));
|
||||
|
||||
// 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();
|
||||
$gitearepo=$this->giteaservice->getRepo($data->getGiteaid());
|
||||
$data->setGiteaname($gitearepo->full_name);
|
||||
$data->setGiteajson(json_decode(json_encode($gitearepo), true));
|
||||
|
||||
$em->persist($data);
|
||||
$em->flush();
|
||||
|
||||
// Retour à la liste
|
||||
return $this->redirectToRoute($this->route);
|
||||
}
|
||||
|
||||
// Affichage du formulaire
|
||||
return $this->render($this->render.'edit.html.twig', [
|
||||
'useheader' => true,
|
||||
'usesidebar' => false,
|
||||
'maxwidth' => true,
|
||||
$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);
|
||||
|
||||
// Récupérer les repos de gitea
|
||||
$gitearepos=$this->giteaservice->getRepos();
|
||||
|
||||
// Création du formulaire
|
||||
$form = $this->createForm(Form::class,$data,array("mode"=>"update","gitearepos"=>$gitearepos));
|
||||
|
||||
// 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();
|
||||
$gitearepo=$this->giteaservice->getRepo($data->getGiteaid());
|
||||
$data->setGiteaname($gitearepo->full_name);
|
||||
$data->setGiteajson(json_decode(json_encode($gitearepo), true));
|
||||
|
||||
$em->persist($data);
|
||||
$em->flush();
|
||||
|
||||
// Retour à la liste
|
||||
return $this->redirectToRoute($this->route);
|
||||
}
|
||||
|
||||
// Affichage du formulaire
|
||||
return $this->render($this->render.'edit.html.twig', [
|
||||
'useheader' => true,
|
||||
'usesidebar' => false,
|
||||
'maxwidth' => true,
|
||||
$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->redirectToRoute($this->route);
|
||||
}
|
||||
}
|
||||
|
||||
public function view($id,Request $request)
|
||||
{
|
||||
// Initialisation de l'enregistrement
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$data=$em->getRepository($this->entity)->find($id);
|
||||
if(!$data) return $this->redirectToRoute($this->route);
|
||||
|
||||
$em->getRepository("App:Scrum")->getGitea($data,$giteaassignees,$giteacolumns,$giteamilestones,$giteateams,$giteaprioritys,$gitealabels);
|
||||
|
||||
// Préférences utilisateur
|
||||
$filtermilestones = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtermilestones",$id);
|
||||
$filterteams = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterteams",$id);
|
||||
$filterprioritys = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterprioritys",$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);
|
||||
|
||||
return $this->render($this->render.'view.html.twig', [
|
||||
'useheader' => true,
|
||||
'usesidebar' => false,
|
||||
'usetitle' => $data->getName(),
|
||||
'giteaassignees' => $giteaassignees,
|
||||
'giteacolumns' => $giteacolumns,
|
||||
'giteamilestones' => $giteamilestones,
|
||||
'giteateams' => $giteateams,
|
||||
'giteaprioritys' => $giteaprioritys,
|
||||
'gitealabels' => $gitealabels,
|
||||
'filtermilestones' => $filtermilestones,
|
||||
'filterteams' => $filterteams,
|
||||
'filterprioritys' => $filterprioritys,
|
||||
'filterlabels' => $filterlabels,
|
||||
'filterassignees' => $filterassignees,
|
||||
'filterexcludes' => $filterexcludes,
|
||||
'showfilters' => $showfilters,
|
||||
$this->data => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
public function stat($id,Request $request)
|
||||
{
|
||||
// Initialisation de l'enregistrement
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
$data=$em->getRepository($this->entity)->find($id);
|
||||
if(!$data) return $this->redirectToRoute($this->route);
|
||||
|
||||
$em->getRepository("App:Scrum")->getGitea($data,$giteaassignees,$giteacolumns,$giteamilestones,$giteateams,$giteaprioritys,$gitealabels);
|
||||
|
||||
// Préférences utilisateur
|
||||
$filtermilestones = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filtermilestones",$id);
|
||||
$filterteams = $em->getRepository("App:User")->getUserpreference($this->getUser(),"filterteams",$id);
|
||||
$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(!array_key_exists($issue->getScrumcolumn()->getId(),$tbstat[$idmilestone]["stat"])) {
|
||||
$tbstat[$idmilestone]["stat"][$issue->getScrumcolumn()->getId()]=[
|
||||
"id"=>$issue->getScrumcolumn()->getId(),
|
||||
"label"=>$issue->getScrumcolumn()->getName(),
|
||||
"total"=>0,
|
||||
"color"=>"#".$issue->getScrumcolumn()->getGiteajson()["color"],
|
||||
"labels"=>[],
|
||||
];
|
||||
}
|
||||
|
||||
foreach($labels as $label) {
|
||||
if($issue->getScrumcolumn()->getGiteaid()!=$label["id"]) {
|
||||
if(!array_key_exists($label["id"],$tbstat[$idmilestone]["stat"][$issue->getScrumcolumn()->getId()]["labels"])) {
|
||||
$tbstat[$idmilestone]["stat"][$issue->getScrumcolumn()->getId()]["labels"][$label["id"]] = [
|
||||
"id"=>$label["id"],
|
||||
"label"=>$label["name"],
|
||||
"total"=>0,
|
||||
"color"=>"#".$label["color"],
|
||||
];
|
||||
}
|
||||
$tbstat[$idmilestone]["stat"][$issue->getScrumcolumn()->getId()]["labels"][$label["id"]]["total"]++;
|
||||
}
|
||||
}
|
||||
|
||||
$tbstat[$idmilestone]["stat"][$issue->getScrumcolumn()->getId()]["total"]++;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($tbstat as $k1=>$milestone) {
|
||||
foreach($milestone["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,
|
||||
'gitealabels' => $gitealabels,
|
||||
'filtermilestones' => $filtermilestones,
|
||||
'filterteams' => $filterteams,
|
||||
'showfilters' => $showfilters,
|
||||
$this->data => $data,
|
||||
'tbstat' => $tbstat,
|
||||
]);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ namespace App\Controller;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\Form\FormError;
|
||||
|
||||
use App\Entity\Scrum as Entity;
|
||||
@ -298,6 +299,34 @@ class ScrumController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
public function info($id,Request $request)
|
||||
{
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
||||
// Rechercher du scrum en cours
|
||||
$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"]);
|
||||
|
||||
$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["weights"]=$weights;
|
||||
|
||||
return new JsonResponse($output);
|
||||
}
|
||||
|
||||
protected function getErrorForm($id,$form,$request,$data,$mode) {
|
||||
if ($form->get('submit')->isClicked()&&$mode=="delete") {
|
||||
}
|
||||
|
@ -105,10 +105,55 @@ class ScrumissueController extends AbstractController
|
||||
|
||||
$em->flush();
|
||||
|
||||
|
||||
return new JsonResponse();
|
||||
}
|
||||
|
||||
public function info(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);
|
||||
|
||||
$output=[];
|
||||
$output["weight"]=$scrumissue->getWeight();
|
||||
|
||||
return new JsonResponse($output);
|
||||
}
|
||||
|
||||
public function update(Request $request)
|
||||
{
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
||||
$id=$request->get('id');
|
||||
$weight=$request->get('weight');
|
||||
|
||||
// Rechercher l'issue en cours
|
||||
$scrumissue=$em->getRepository("App:Scrumissue")->find($id);
|
||||
if(!$scrumissue) return new JsonResponse(['message' => 'No Issue'], 403);
|
||||
|
||||
$scrumissue->setWeight($weight);
|
||||
$em->flush();
|
||||
|
||||
$giteaissues=$this->giteaservice->getIssues($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"]);
|
||||
|
||||
$weights=[];
|
||||
foreach($giteaissues as $giteaissue) {
|
||||
$issue=$em->getRepository("App:Scrumissue")->findOneBy(["scrum"=>$scrumissue->getScrum(),"giteaid"=>$giteaissue->id]);
|
||||
if($issue) {
|
||||
if($giteaissue->milestone) $milestoneid=$giteaissue->milestone->id;
|
||||
else $milestoneid=-100;
|
||||
|
||||
if(!array_key_exists($milestoneid,$weights)) $weights[$milestoneid]=0;
|
||||
$weights[$milestoneid]=$weights[$milestoneid]+$issue->getWeight();
|
||||
}
|
||||
}
|
||||
return new JsonResponse($weights);
|
||||
}
|
||||
|
||||
public function ctrlchange(Request $request)
|
||||
{
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
@ -26,6 +26,11 @@ class Scrumissue
|
||||
*/
|
||||
private $rowid;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $weight=0;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
@ -198,5 +203,17 @@ class Scrumissue
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWeight(): ?int
|
||||
{
|
||||
return $this->weight;
|
||||
}
|
||||
|
||||
public function setWeight(int $weight): self
|
||||
{
|
||||
$this->weight = $weight;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -10,10 +10,12 @@ class giteaService
|
||||
private $params;
|
||||
private $session;
|
||||
private $url;
|
||||
|
||||
private $giteaUrl;
|
||||
|
||||
public function __construct(SessionInterface $session,ParameterBagInterface $params,$giteaUrl)
|
||||
{
|
||||
$this->params = $params;
|
||||
$this->giteaUrl = $giteaUrl;
|
||||
$this->url = $giteaUrl."/api/v1";
|
||||
$this->session = $session;
|
||||
}
|
||||
@ -29,6 +31,7 @@ class giteaService
|
||||
];
|
||||
$body = \Unirest\Request\Body::json($query);
|
||||
|
||||
|
||||
$response=$this->api("POST",$apiurl,$body);
|
||||
|
||||
if(!$response||$response->code!="200") return false;
|
||||
@ -38,6 +41,31 @@ class giteaService
|
||||
}
|
||||
}
|
||||
|
||||
public function deletetoken($username) {
|
||||
$apiurl=$this->url."/users/".$username."/tokens/".$this->session->get("giteatoken");
|
||||
$response=$this->api("DELETE",$apiurl,null,$this->session->get("giteatoken"));
|
||||
}
|
||||
|
||||
public function markdown($context,$mode,$body) {
|
||||
$apiurl = $this->url."/markdown";
|
||||
$query= [
|
||||
"Context" => $context,
|
||||
"Mode" => $mode,
|
||||
"Text" => $body,
|
||||
"Wiki" => false,
|
||||
];
|
||||
|
||||
$body = \Unirest\Request\Body::json($query);
|
||||
|
||||
|
||||
$response=$this->api("POST",$apiurl,$body,$this->session->get("giteatoken"));
|
||||
if(!$response||$response->code!="200") return false;
|
||||
else {
|
||||
$response->body= str_replace($this->giteaUrl,$this->giteaUrl.$context,$response->body);
|
||||
return $response->body;
|
||||
}
|
||||
}
|
||||
|
||||
public function getuser() {
|
||||
$apiurl = $this->url."/user";
|
||||
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
|
||||
@ -48,7 +76,6 @@ class giteaService
|
||||
public function getuserprofil($id) {
|
||||
$apiurl = $this->url."/users/$id";
|
||||
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
|
||||
dump($response);
|
||||
if(!$response||$response->code!="200") return false;
|
||||
else return $response->body;
|
||||
}
|
||||
@ -156,8 +183,9 @@ class giteaService
|
||||
else return $response->body;
|
||||
}
|
||||
|
||||
public function getissues($owner,$name) {
|
||||
$apiurl = $this->url."/repos/$owner/$name/issues?state=open";
|
||||
public function getissues($owner,$name,$state="?state=open") {
|
||||
$apiurl = $this->url."/repos/$owner/$name/issues".$state;
|
||||
|
||||
$page=1;
|
||||
$limit=20;
|
||||
$issues=[];
|
||||
@ -210,11 +238,25 @@ class giteaService
|
||||
$apiurl = $this->url."/repos/$owner/$name/issues/$index";
|
||||
$body = \Unirest\Request\Body::json($patchs);
|
||||
$response=$this->api("PATCH",$apiurl,$body,$this->session->get("giteatoken"));
|
||||
dump($response);
|
||||
if(!$response||$response->code!="201") return false;
|
||||
else return $response->body;
|
||||
}
|
||||
|
||||
public function getissuecomments($owner,$name,$index) {
|
||||
$apiurl = $this->url."/repos/$owner/$name/issues/$index/comments";
|
||||
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
|
||||
if(!$response||$response->code!="200") return false;
|
||||
else return $response->body;
|
||||
}
|
||||
|
||||
|
||||
public function getissuetimelines($owner,$name,$index) {
|
||||
$apiurl = $this->url."/repos/$owner/$name/issues/$index/timeline";
|
||||
$response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken"));
|
||||
if(!$response||$response->code!="200") return false;
|
||||
else return $response->body;
|
||||
}
|
||||
|
||||
private function api($method,$url,$query,$token=null) {
|
||||
// Entete
|
||||
$headers = [
|
||||
|
@ -146,6 +146,7 @@
|
||||
<th style="width:1000px">Titre</th>
|
||||
<th style="width:200px">Equipe</th>
|
||||
<th style="width:250px">Priorité</th>
|
||||
<th style="width:70px">Poid</th>
|
||||
<th style="width:135px">Affecté à</th>
|
||||
<th style="width:135px">Statut</th>
|
||||
<th style="width:300px">Etiquettes</th>
|
||||
@ -204,6 +205,13 @@
|
||||
<td><a target="_blank" href="{{giteaissue.html_url}}">{{ giteaissue.title }}</a></td>
|
||||
<td>{{ teams|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="" %}
|
||||
{% for assignee in giteaissue.assignees %}
|
||||
{% set dataorder=dataorder~assignee.username %}
|
||||
@ -224,6 +232,31 @@
|
||||
</table>
|
||||
</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"></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="integer" 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 %}
|
||||
@ -580,6 +613,58 @@
|
||||
showhide();
|
||||
}
|
||||
|
||||
function refreshinfo() {
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "{{path("app_scrum_info",{id:id})}}",
|
||||
success: function(data) {
|
||||
$(".totalweight").html("0");
|
||||
|
||||
Object.entries(data.weights).forEach(entry => {
|
||||
const [key, value] = entry;
|
||||
$("#total"+key).html(value);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on('click','.modissu',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-issueweight").val(data.weight);
|
||||
$("#mymodalissue").modal('show');
|
||||
$("#modal-issueweight").focus();
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
$("#issu_update").click(function(){
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "{{path("app_scrumissue_update")}}",
|
||||
data: {
|
||||
id:$("#modal-issueid").val(),
|
||||
weight:$("#modal-issueweight").val(),
|
||||
},
|
||||
success: function(data) {
|
||||
$("#issue"+$("#modal-issueid").val()+"-weight").html($("#modal-issueweight").val());
|
||||
refreshinfo();
|
||||
$("#mymodalissue").modal('hide');
|
||||
},
|
||||
error: function (request, status, error) {
|
||||
$("#mymodalissue").modal('hide');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).ready(function() {
|
||||
{% if id== 0 %}
|
||||
$('#filtercategorys').select2();
|
||||
@ -725,7 +810,8 @@
|
||||
$("#filters").removeClass("d-flex");
|
||||
{% endif %}
|
||||
|
||||
showhide();
|
||||
showhide();
|
||||
|
||||
$("#mycontent").show();
|
||||
});
|
||||
{% endblock %}
|
153
src/ninegitea-1.0/templates/Report/list.html.twig
Normal file
153
src/ninegitea-1.0/templates/Report/list.html.twig
Normal file
@ -0,0 +1,153 @@
|
||||
{% extends "base.html.twig" %}
|
||||
|
||||
{% block localstyle %}
|
||||
body {
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
.issuetitle {
|
||||
margin-top:100px;
|
||||
page-break-before: always;
|
||||
}
|
||||
|
||||
.issuediv {
|
||||
zoom:60%;
|
||||
}
|
||||
|
||||
.issuecontent {
|
||||
width:80%;
|
||||
}
|
||||
.issuedetail {
|
||||
width:20%;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<h1>{{repo.full_name}}</h1>
|
||||
{% for issue in issues %}
|
||||
<h2 id='issuetitle{{issue.number}}' class='issuetitle'>#{{issue.number}} = {{issue.title}}</h2>
|
||||
|
||||
<div id='issuediv{{issue.number}}' class='issuediv d-flex'>";
|
||||
<div class='issuecontent'>
|
||||
<h3>{{issue.user.login}} le {{issue.created_at|date("d/m/Y H:i")}}</h3>
|
||||
<div class='card card-body'>
|
||||
{{issue.body|raw}}
|
||||
</div>
|
||||
|
||||
{% if 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>
|
||||
<div class='card card-body'>
|
||||
{{comment.body|raw}}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class='pl-3 issuedetail'>
|
||||
<h3>Statut</h3>
|
||||
<div class='card card-body mb-3'>
|
||||
{% if issue.closed_at %}
|
||||
Clos le {{issue.closed_at|date("d/m/Y H:i")}}
|
||||
{% else %}
|
||||
En Cours
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<h3>Jalon</h3>
|
||||
<div class='card card-body mb-3'>
|
||||
{% if issue.milestone %}
|
||||
{{ issue.milestone.title|raw }}
|
||||
{% else %}
|
||||
Backlog
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if issue.labels %}
|
||||
<h3>Labels</h3>
|
||||
<div class='card'>
|
||||
<div class='card-body mb-3'>
|
||||
{% for label in issue.labels %}
|
||||
<span class='badge mr-2 mb-2 p-2' style='background-color:#{{label.color}}'>{{label.name}}</span>
|
||||
{% endfor%}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if issue.timelines %}
|
||||
<h3>Historique</h3>
|
||||
<div class='card card-body mb-3'>
|
||||
|
||||
{% for timeline in issue.timelines %}
|
||||
{% if 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 == "label" %}
|
||||
<div class='pl-4'>Affectation au Label <i>{{timeline.label.name}}</i></div>
|
||||
|
||||
{% 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 révision <i>#{{timeline.body|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>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
||||
|
@ -98,7 +98,15 @@
|
||||
<option value="{{gitealabel.id}}">{{gitealabel.name}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="color:var(--colorftbodydark)" 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 class="pl-3" style="width:100%;">
|
||||
@ -164,7 +172,7 @@
|
||||
{% set dataassignees=dataassignees~"dataassignee"~assignee.id~" " %}
|
||||
{% endfor %}
|
||||
|
||||
<div data-id="{{ issue.id }}" data-issue="{{ issue.id }}" data-column="{{column.giteaid}}" data-milestone="{{idmilestone}}" class="card mb-1 issue issue-{{issue.id}} {{datateams}} {{dataprioritys}} {{datalabels}} {{dataassignees}}">
|
||||
<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}} {{dataprioritys}} {{datalabels}} {{dataassignees}}">
|
||||
<div class="card-footer p-1" style="line-height:10px; border-top:none;">
|
||||
<div class="float-left btn btn-link p-0 m-0 fas fa-arrows-alt" style="cursor:move"></div>
|
||||
<a target="_blank" class="modcolumn btn btn-link float-right fa fa-file p-0 m-0" href="{{issue.giteajson.html_url}}"></a>
|
||||
@ -208,6 +216,10 @@
|
||||
<img src="{{assignee.avatar_url}}" class="assignee" title="{{assignee.username}}">
|
||||
{% endfor %}
|
||||
</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">
|
||||
<i class="fas fa-weight-hanging"></i> = <span id="issue{{issue.id}}-weight">{{ issue.weight }}</span>
|
||||
</div>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
@ -234,9 +246,36 @@
|
||||
{% endfor %}
|
||||
</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"></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="integer" 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 %}
|
||||
|
||||
|
||||
|
||||
function showFilters() {
|
||||
if($("#filters").hasClass("d-flex")) {
|
||||
toshow=0;
|
||||
@ -374,9 +413,61 @@
|
||||
});
|
||||
}
|
||||
|
||||
$("#textfilters").html(textfilters);
|
||||
$("#textfilters").html(textfilters);
|
||||
}
|
||||
|
||||
function refreshinfo() {
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "{{path("app_scrum_info",{id:scrum.id})}}",
|
||||
success: function(data) {
|
||||
$(".totalweight").html("0");
|
||||
|
||||
Object.entries(data.weights).forEach(entry => {
|
||||
const [key, value] = entry;
|
||||
$("#total"+key).html(value);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on('click','.modissu',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-issueweight").val(data.weight);
|
||||
$("#mymodalissue").modal('show');
|
||||
$("#modal-issueweight").focus();
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
$("#issu_update").click(function(){
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "{{path("app_scrumissue_update")}}",
|
||||
data: {
|
||||
id:$("#modal-issueid").val(),
|
||||
weight:$("#modal-issueweight").val(),
|
||||
},
|
||||
success: function(data) {
|
||||
$("#issue"+$("#modal-issueid").val()+"-weight").html($("#modal-issueweight").val());
|
||||
refreshinfo();
|
||||
$("#mymodalissue").modal('hide');
|
||||
},
|
||||
error: function (request, status, error) {
|
||||
$("#mymodalissue").modal('hide');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Filter Milestones
|
||||
function filtermilestones() {
|
||||
$.ajax({
|
||||
@ -556,6 +647,7 @@
|
||||
|
||||
// Appliy filters
|
||||
showhide();
|
||||
refreshinfo();
|
||||
$("#mycontent").show();
|
||||
|
||||
lastupdate="{{scrum.updatedate|date("Ymd H:i:s")}}";
|
||||
@ -589,6 +681,8 @@
|
||||
$(ui.item).data("column",newcolumn);
|
||||
$(ui.item).data("milestone",newmilestone);
|
||||
if(data) lastupdate=data;
|
||||
|
||||
refreshinfo();
|
||||
},
|
||||
error: function (request, status, error) {
|
||||
$( ".scrumcolumn" ).sortable('cancel');
|
||||
@ -604,7 +698,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
console.log(lstordered);
|
||||
$.ajax({
|
||||
method: "POST",
|
||||
url: "{{path("app_scrumissue_order")}}",
|
||||
@ -612,8 +705,8 @@
|
||||
id:{{scrum.id}},
|
||||
lstordered:lstordered,
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user