diff --git a/composer.json b/composer.json index 9030b36..ab2965e 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,7 @@ "symfony/web-link": "5.1.*", "symfony/webpack-encore-bundle": "^1.7", "symfony/yaml": "5.1.*", - "tetranz/select2entity-bundle": "^3.0", + "tetranz/select2entity-bundle": "^3.0" }, "require-dev": { "symfony/debug-pack": "*", diff --git a/config/routes.yaml b/config/routes.yaml index 54b7586..83a423b 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -338,6 +338,14 @@ app_scrumissue_update: path: /user/scrumissue/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_ctrlchange: path: /user/scrumissue/ctrlchange defaults: { _controller: App\Controller\ScrumissueController:ctrlchange } diff --git a/src/Controller/ScrumController.php b/src/Controller/ScrumController.php index 5669baf..0399796 100755 --- a/src/Controller/ScrumController.php +++ b/src/Controller/ScrumController.php @@ -199,7 +199,7 @@ class ScrumController extends AbstractController $viewclosed = $this->get('session')->get("viewclosed"); foreach($issues as $issue) { // bypass closed - if($viewclosed=="false"&&$issue->getGiteastate()=="closed") continue; + if($viewclosed=="false"&&($issue->getGiteastate()=="closed"||($issue->getScrumsprint()&&$issue->getScrumsprint()->getClosed()))) continue; // Ids $idcol=($issue->getScrumcolumn()?$issue->getScrumcolumn()->getId():$firstcolumn->getId()); @@ -334,8 +334,11 @@ class ScrumController extends AbstractController // 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(), @@ -398,7 +401,7 @@ class ScrumController extends AbstractController 'giteaassignees' => $giteaassignees, 'giteacolumns' => $giteacolumns, 'giteamilestones' => $giteamilestones, - 'sprints' => $data->getScrumsprints(), + 'sprints' => $data->getScrumsprintstosee($viewclosed), 'giteateams' => $giteateams, 'giteaprioritys' => $giteaprioritys, 'giteatypes' => $giteatypes, @@ -662,7 +665,7 @@ class ScrumController extends AbstractController $viewclosed = $this->get('session')->get("viewclosed"); foreach($issues as $issue) { // bypass closed - if($viewclosed=="false"&&$issue->getGiteastate()=="closed") continue; + if($viewclosed=="false"&&($issue->getGiteastate()=="closed"||($issue->getScrumsprint()&&$issue->getScrumsprint()->getClosed()))) continue; // Ids $idcol=($issue->getScrumcolumn()?$issue->getScrumcolumn()->getId():$firstcolumn->getId()); diff --git a/src/Controller/ScrumissueController.php b/src/Controller/ScrumissueController.php index 83ce8cd..60ad378 100755 --- a/src/Controller/ScrumissueController.php +++ b/src/Controller/ScrumissueController.php @@ -237,6 +237,44 @@ class ScrumissueController extends AbstractController 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); + dump($response); + 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 ctrlchange(Request $request) { $em = $this->getDoctrine()->getManager(); diff --git a/src/Controller/ScrumsprintController.php b/src/Controller/ScrumsprintController.php index ee0ad14..2287c1f 100755 --- a/src/Controller/ScrumsprintController.php +++ b/src/Controller/ScrumsprintController.php @@ -145,7 +145,9 @@ class ScrumsprintController extends AbstractController $scrumsprints = $scrum->getScrumsprints(); $output=array(); foreach($scrumsprints as $scrumsprint) { - array_push($output,array("id"=>$scrumsprint->getId(),"name"=>"".$scrumsprint->getName()."
liè au jalon gitea ".$scrumsprint->getGiteamilestonename()."")); + $title = "Jalon = ".$scrumsprint->getGiteamilestonename()."
"; + $title.= "Sprint = ".$scrumsprint->getName(); + array_push($output,array("id"=>$scrumsprint->getId(),"name"=>$title,"closed"=>$scrumsprint->getClosed())); } $response = new Response(json_encode($output)); diff --git a/src/Entity/Scrum.php b/src/Entity/Scrum.php index e5f1e7b..7500fa7 100644 --- a/src/Entity/Scrum.php +++ b/src/Entity/Scrum.php @@ -114,6 +114,18 @@ class Scrum 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() { $this->users = new ArrayCollection(); diff --git a/src/Entity/Scrumissue.php b/src/Entity/Scrumissue.php index efb57a3..2ef309e 100644 --- a/src/Entity/Scrumissue.php +++ b/src/Entity/Scrumissue.php @@ -71,22 +71,33 @@ class Scrumissue private $giteajson; /** - * @ORM\ManyToOne(targetEntity="Scrum", inversedBy="Scrumissues") + * @ORM\ManyToOne(targetEntity="Scrum", inversedBy="scrumissues") */ private $scrum; /** - * @ORM\ManyToOne(targetEntity="Scrumcolumn", inversedBy="Scrumissues") + * @ORM\ManyToOne(targetEntity="Scrumcolumn", inversedBy="scrumissues") * @ORM\JoinColumn(nullable=true, onDelete="SET NULL") */ private $scrumcolumn; /** - * @ORM\ManyToOne(targetEntity="Scrumsprint", inversedBy="Scrumissues") + * @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) + */ + private $scrumissuedependencies; + /** * @ORM\OneToMany(targetEntity="Userpoker", mappedBy="scrumissue", cascade={"persist"}, orphanRemoval=true) */ @@ -95,6 +106,8 @@ class Scrumissue public function __construct() { $this->userpokers = new ArrayCollection(); + $this->scrumissuedependcies = new ArrayCollection(); + $this->scrumissuedependencies = new ArrayCollection(); } public function getId(): ?int @@ -277,6 +290,46 @@ class Scrumissue 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; + } } \ No newline at end of file diff --git a/src/Entity/Scrumsprint.php b/src/Entity/Scrumsprint.php index b280875..bb628af 100644 --- a/src/Entity/Scrumsprint.php +++ b/src/Entity/Scrumsprint.php @@ -33,6 +33,11 @@ class Scrumsprint */ private $rowid; + /** + * @ORM\Column(type="boolean") + */ + private $closed; + /** * @ORM\Column(type="integer", nullable=true) */ @@ -155,5 +160,17 @@ class Scrumsprint return $this; } + public function getClosed(): ?bool + { + return $this->closed; + } + + public function setClosed(bool $closed): self + { + $this->closed = $closed; + + return $this; + } + } \ No newline at end of file diff --git a/src/Form/ScrumsprintType.php b/src/Form/ScrumsprintType.php index 651553c..8027c8f 100644 --- a/src/Form/ScrumsprintType.php +++ b/src/Form/ScrumsprintType.php @@ -32,6 +32,11 @@ class ScrumsprintType extends AbstractType ] ); + $choices=["non"=>0,"oui"=>1]; + $builder->add('closed', + ChoiceType::class, ['choices' => $choices] + ); + $choices=[]; foreach($options["giteamilestones"] as $milestone) { $choices[$milestone->title]=$milestone->id; diff --git a/src/Repository/ScrumRepository.php b/src/Repository/ScrumRepository.php index e7d9913..a779146 100644 --- a/src/Repository/ScrumRepository.php +++ b/src/Repository/ScrumRepository.php @@ -36,6 +36,9 @@ class ScrumRepository extends ServiceEntityRepository return $scrums; } } + + + public function getGitea($scrum,&$giteaassignees,&$giteacolumns,&$giteamilestones,&$giteateams,&$giteaprioritys,&$giteatypes,&$gitealabels, $forcereload=false) { $viewclosed = $this->session->get("viewclosed"); @@ -272,6 +275,19 @@ class ScrumRepository extends ServiceEntityRepository } } + $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->flush(); diff --git a/src/Service/giteaService.php b/src/Service/giteaService.php index 114a333..b2a162c 100644 --- a/src/Service/giteaService.php +++ b/src/Service/giteaService.php @@ -317,7 +317,6 @@ class giteaService 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")); @@ -325,6 +324,33 @@ class giteaService 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") 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) { // Entete $headers = [ diff --git a/templates/Include/style.css.twig b/templates/Include/style.css.twig index ffec452..db446a6 100644 --- a/templates/Include/style.css.twig +++ b/templates/Include/style.css.twig @@ -17,6 +17,9 @@ --colorfttitlelight-darker: {{ app.session.get('colorfttitlelight-darker')|raw }}; } +.hidden { + display: none !important; +} /* COLOR BODY */ body { diff --git a/templates/Scrum/edit.html.twig b/templates/Scrum/edit.html.twig index c9cc02d..58cdd82 100755 --- a/templates/Scrum/edit.html.twig +++ b/templates/Scrum/edit.html.twig @@ -63,6 +63,11 @@
Sprints + +
+ + +
@@ -423,6 +428,15 @@ loadscrumsprints(); }); + $('#viewsprintclosed').change(function() { + if(this.checked) { + $(".sprintclosed").removeClass("hidden"); + } + else { + $(".sprintclosed").addClass("hidden"); + } + }); + function loadscrumsprints() { $("#scrumsprints").empty(); $.ajax({ @@ -431,7 +445,17 @@ success: function(datas, dataType) { jQuery.each(datas, function(i, wid) { - html ='
  • '; + style=''; + classname=''; + if(wid.closed) { + style='background-color:#cdcdcd;'; + classname='sprintclosed'; + if(!$("#viewsprintclosed").is(':checked')) { + classname+=' hidden'; + } + } + + html ='
  • '; html+='
    '; html+='
    '; html+='
    '; diff --git a/templates/Scrum/view.html.twig b/templates/Scrum/view.html.twig index 9e463df..62d81c1 100644 --- a/templates/Scrum/view.html.twig +++ b/templates/Scrum/view.html.twig @@ -221,23 +221,45 @@
    + + {% if issue.scrumissueblock is empty %} +
    + + + Ajouter ce ticket comme bloquant à + +
    + {% else %} +
    + + + N'est plus bloquant pour #{{ issue.scrumissueblock.giteanumber}} + +
    + + {% endif %}
    @@ -368,6 +407,30 @@
    + + {% endblock %} {% block localjavascript %} @@ -557,10 +620,64 @@ $("#textfilters").html(textfilters); } + + $(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({ + method: "POST", + url: "{{path("app_scrumissue_block")}}", + data: { + id:$("#modal-issueid").val(), + issueblocked:$("#modal-issueblocked").val(), + }, + success: function(data) { + location.reload(); + }, + error: function (request, status, error) { + $("#issueblocked").modal('hide'); + } + }); + }); + + $(document).on('click','.unlockissu',function(){ + if (window.confirm("Souhaitez-vous enlever le blocage ?")) { + $.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(){ $(".modal-title").html("#"+$(this).data("giteaid")+" - "+$(this).data("giteatitle")); $("#modal-issueid").val($(this).data("issue")); - + $.ajax({ method: "POST", url: "{{path("app_scrumissue_info")}}", @@ -575,14 +692,6 @@ }); }); - $(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); - }); - $("#issu_update").click(function(){ $.ajax({ method: "POST", diff --git a/templates/Scrumsprint/edit.html.twig b/templates/Scrumsprint/edit.html.twig index cd374de..94dee03 100755 --- a/templates/Scrumsprint/edit.html.twig +++ b/templates/Scrumsprint/edit.html.twig @@ -3,7 +3,7 @@ {% block body %} {{ form_start(form) }} {{ form_widget(form.submit) }} - + Annuler {% if mode=="update" %}