diff --git a/src/ninegitea-1.0/config/routes.yaml b/src/ninegitea-1.0/config/routes.yaml index 87b128a..ddc4c8f 100644 --- a/src/ninegitea-1.0/config/routes.yaml +++ b/src/ninegitea-1.0/config/routes.yaml @@ -139,6 +139,10 @@ app_user_profil: path: /user/profil defaults: { _controller: App\Controller\UserController:profil } +app_user_preference: + path: /user/preference + defaults: { _controller: App\Controller\UserController:preference } + #== Group ======================================================================================================== app_group: path: /admin/group @@ -207,3 +211,7 @@ app_scrumcolumn_order: app_scrumissue_change: path: /user/scrumissue/change defaults: { _controller: App\Controller\ScrumissueController:change } + +app_scrumissue_order: + path: /user/scrumissue/order + defaults: { _controller: App\Controller\ScrumissueController:order } diff --git a/src/ninegitea-1.0/src/Controller/ScrumController.php b/src/ninegitea-1.0/src/Controller/ScrumController.php index 67f3af3..6ad5eba 100755 --- a/src/ninegitea-1.0/src/Controller/ScrumController.php +++ b/src/ninegitea-1.0/src/Controller/ScrumController.php @@ -157,17 +157,62 @@ class ScrumController extends AbstractController $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) { + foreach($giteateams as $team) { + $giteamembers=$this->giteaservice->getTeammembers($team->id); + 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 reconnecter"); + 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 reconnecter"); + if(!is_array($giteamilestones)) die("Probleme de connexion avec gitea veuillez vous reconnecter"); + $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 reconnecter"); + 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 reconnecter"); + if(!is_array($giteaissues)) die("Probleme de connexion avec gitea veuillez vous reconnecter"); // 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) { @@ -181,8 +226,14 @@ class ScrumController extends AbstractController $scrumissue->setGiteanumber($giteaissue->number); $scrumissue->setGiteastate($giteaissue->state); $scrumissue->setGiteatitle($giteaissue->title); - if($giteaissue->milestone) $scrumissue->setGiteamilestone($giteaissue->milestone->id); - else $scrumissue->setGiteamilestone(null); + 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); @@ -200,6 +251,7 @@ class ScrumController extends AbstractController } if(!$havecolumn) $scrumissue->setScrumcolumn($firstcolumn); + // Sauvegarde de l'issue $em->persist($scrumissue); $em->flush(); } @@ -211,11 +263,22 @@ class ScrumController extends AbstractController $em->flush(); } } + + // 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); return $this->render($this->render.'view.html.twig', [ 'useheader' => true, 'usesidebar' => false, + 'giteaassignees' => $giteaassignees, + 'giteacolumns' => $giteacolumns, 'giteamilestones' => $giteamilestones, + 'gitealabels' => $gitealabels, + 'filtermilestones' => $filtermilestones, + 'filterlabels' => $filterlabels, + 'filterassignees' => $filterassignees, $this->data => $data, ]); } diff --git a/src/ninegitea-1.0/src/Controller/ScrumissueController.php b/src/ninegitea-1.0/src/Controller/ScrumissueController.php index 7f18740..0089d57 100755 --- a/src/ninegitea-1.0/src/Controller/ScrumissueController.php +++ b/src/ninegitea-1.0/src/Controller/ScrumissueController.php @@ -27,8 +27,8 @@ class ScrumissueController extends AbstractController $em = $this->getDoctrine()->getManager(); $id=$request->get('id'); - $oldlabel=$request->get('oldlabel'); - $newlabel=$request->get('newlabel'); + $oldcolumn=$request->get('oldcolumn'); + $newcolumn=$request->get('newcolumn'); $oldmilestone=$request->get('oldmilestone'); $newmilestone=$request->get('newmilestone'); @@ -40,19 +40,18 @@ class ScrumissueController extends AbstractController $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 label par le nouveau + // Remplacer l'ancien column par la nouvelle $newgitelabels=[]; $haveold=false; foreach($gitealabels as $gitealabel) { - if($gitealabel->id!=$oldlabel) array_push($newgitelabels,$gitealabel->id); + if($gitealabel->id!=$oldcolumn) array_push($newgitelabels,$gitealabel->id); else $haveold=true; } - if(!in_array($newlabel,$newgitelabels)) array_push($newgitelabels,intval($newlabel)); + if(!in_array($newcolumn,$newgitelabels)) array_push($newgitelabels,intval($newcolumn)); // Supprimer l'ancien label if($haveold) { - dump($oldlabel); - $return=$this->giteaservice->deleteIssuelabel($scrumissue->getScrum()->getGiteajson()["owner"]["login"],$scrumissue->getScrum()->getGiteajson()["name"],$scrumissue->getGiteanumber(),$oldlabel); + $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); } @@ -67,4 +66,30 @@ class ScrumissueController extends AbstractController return new JsonResponse(); } + + public function order(Request $request) + { + $em = $this->getDoctrine()->getManager(); + + $id=$request->get('id'); + $lstordered=explode(",",$request->get('lstordered')); + + $scrum=$em->getRepository("App:Scrum")->find($id); + if(!$scrum) return new JsonResponse(['message' => 'No Scrum'], 403); + + $order=0; + foreach($lstordered as $item) { + $scrumissue=$em->getRepository("App:Scrumissue")->find($item); + if($scrumissue) { + $scrumissue->setRowid($order); + $order++; + $em->persist($scrumissue); + } + } + + $em->flush(); + + + return new JsonResponse(); + } } diff --git a/src/ninegitea-1.0/src/Controller/UserController.php b/src/ninegitea-1.0/src/Controller/UserController.php index f7ecf27..e495e7d 100755 --- a/src/ninegitea-1.0/src/Controller/UserController.php +++ b/src/ninegitea-1.0/src/Controller/UserController.php @@ -190,7 +190,23 @@ class UserController extends AbstractController $response->headers->set('Content-Type', 'application/json'); return $response; } + + public function preference(Request $request) + { + // S'assurer que c'est un appel ajax + if (!$request->isXmlHttpRequest()) { + return new JsonResponse(array('message' => 'Interdit'), 400); + } + + $key=$request->request->get('key'); + $id=$request->request->get('id'); + $value=$request->request->get('value'); + $this->getDoctrine()->getManager()->getRepository("App:User")->setUserpreference($this->getUser(),$key,$id,$value); + + return new Response(); + } + protected function getErrorForm($id,$form,$request,$data,$mode) { if ($form->get('submit')->isClicked()&&$mode=="delete") { } diff --git a/src/ninegitea-1.0/src/Entity/Scrumcolumn.php b/src/ninegitea-1.0/src/Entity/Scrumcolumn.php index bedaacf..9a86bd5 100644 --- a/src/ninegitea-1.0/src/Entity/Scrumcolumn.php +++ b/src/ninegitea-1.0/src/Entity/Scrumcolumn.php @@ -50,7 +50,7 @@ class Scrumcolumn /** * @ORM\OneToMany(targetEntity="Scrumissue", mappedBy="scrumcolumn", cascade={"persist"}, orphanRemoval=true) - * @ORM\OrderBy({"giteamilestone" = "DESC", "rowid" = "ASC"}) + * @ORM\OrderBy({"giteamilestonename" = "DESC", "rowid" = "ASC"}) */ private $scrumissues; diff --git a/src/ninegitea-1.0/src/Entity/Scrumissue.php b/src/ninegitea-1.0/src/Entity/Scrumissue.php index 2e315de..7f10e6a 100644 --- a/src/ninegitea-1.0/src/Entity/Scrumissue.php +++ b/src/ninegitea-1.0/src/Entity/Scrumissue.php @@ -52,6 +52,12 @@ class Scrumissue */ private $giteamilestone; + /** + * @ORM\Column(type="string", nullable=true) + * + */ + private $giteamilestonename; + /** * @ORM\Column(type="json") */ @@ -180,5 +186,17 @@ class Scrumissue return $this; } + public function getGiteamilestonename(): ?string + { + return $this->giteamilestonename; + } + + public function setGiteamilestonename(?string $giteamilestonename): self + { + $this->giteamilestonename = $giteamilestonename; + + return $this; + } + } \ No newline at end of file diff --git a/src/ninegitea-1.0/src/Entity/User.php b/src/ninegitea-1.0/src/Entity/User.php index 9794e57..90b4d4b 100644 --- a/src/ninegitea-1.0/src/Entity/User.php +++ b/src/ninegitea-1.0/src/Entity/User.php @@ -80,6 +80,10 @@ class User implements UserInterface, \Serializable */ private $apikey; + /** + * @ORM\Column(name="preference", type="array", nullable=true) + */ + private $preference; /** * @ORM\ManyToMany(targetEntity="Group", inversedBy="users", cascade={"persist"}) @@ -321,4 +325,15 @@ class User implements UserInterface, \Serializable return $this; } + public function getPreference(): ?array + { + return $this->preference; + } + + public function setPreference(?array $preference): self + { + $this->preference = $preference; + + return $this; + } } diff --git a/src/ninegitea-1.0/src/Repository/UserRepository.php b/src/ninegitea-1.0/src/Repository/UserRepository.php index 9e0d923..bb0a829 100644 --- a/src/ninegitea-1.0/src/Repository/UserRepository.php +++ b/src/ninegitea-1.0/src/Repository/UserRepository.php @@ -12,4 +12,46 @@ class UserRepository extends ServiceEntityRepository { parent::__construct($registry, User::class); } + + public function getUserpreference($user,$key,$id) { + // Récupérer les préférences de l'utilisateur + $preference=$user->getPreference(); + + if(is_array($preference)&&array_key_exists($key,$preference)&&array_key_exists($id,$preference[$key])) + return $preference[$key][$id]; + else + return null; + } + + public function setUserpreference($user,$key,$id,$value) { + // Récupérer les préférences de l'utilisateur + $preference=$user->getPreference(); + + // Mise à jour de la préférence + $toupdate=false; + if(!is_array($preference)) { + $toupdate=true; + $preference=[]; + } + + if(!array_key_exists($key,$preference)) { + $toupdate=true; + $preference[$key]=[]; + } + if((!array_key_exists($id,$preference[$key]))) { + $toupdate=true; + $preference[$key][$id]=$value; + } + if($preference[$key][$id]!=$value) { + $toupdate=true; + $preference[$key][$id]=$value; + } + + // Mise à jour des préferences + if($toupdate) { + $user->setPreference($preference); + $this->_em->persist($user); + $this->_em->flush(); + } + } } diff --git a/src/ninegitea-1.0/src/Service/giteaService.php b/src/ninegitea-1.0/src/Service/giteaService.php index 10ac135..779e20f 100644 --- a/src/ninegitea-1.0/src/Service/giteaService.php +++ b/src/ninegitea-1.0/src/Service/giteaService.php @@ -45,6 +45,35 @@ class giteaService else return $response->body; } + 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; + } + + public function getorga($id) { + $apiurl = $this->url."/orgs/$id"; + $response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken")); + if(!$response||$response->code!="200") return false; + else return $response->body; + } + + public function getorgateams($id) { + $apiurl = $this->url."/orgs/$id/teams"; + $response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken")); + if(!$response||$response->code!="200") return false; + else return $response->body; + } + + public function getteammembers($id) { + $apiurl = $this->url."/teams/$id/members"; + $response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken")); + if(!$response||$response->code!="200") return false; + else return $response->body; + } + public function getrepos() { $apiurl = $this->url."/user/repos"; $page=1; @@ -85,6 +114,20 @@ class giteaService else return $response->body; } + public function getcollaborators($owner,$name) { + $apiurl = $this->url."/repos/$owner/$name/collaborators"; + $response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken")); + if(!$response||$response->code!="200") return false; + else return $response->body; + } + + public function getcollaborator($owner,$name,$id) { + $apiurl = $this->url."/repos/$owner/$name/collaborators/$id"; + $response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken")); + if(!$response||$response->code!="200") return false; + else return $response->body; + } + public function getmilestones($owner,$name) { $apiurl = $this->url."/repos/$owner/$name/milestones"; $response=$this->api("GET",$apiurl,null,$this->session->get("giteatoken")); diff --git a/src/ninegitea-1.0/templates/Scrum/view.html.twig b/src/ninegitea-1.0/templates/Scrum/view.html.twig index 45b23d8..2ad3ae2 100644 --- a/src/ninegitea-1.0/templates/Scrum/view.html.twig +++ b/src/ninegitea-1.0/templates/Scrum/view.html.twig @@ -7,14 +7,72 @@ h3 { font-size:14px; margin-top:15px;} #mycontent { width: 5000px;} + + .btn-link { + cursor:pointer; + } + + .control-label { + margin-bottom:0px; + } + + .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 %} +
+
+ + +
+ +
+ + +
+ +
+ + +
+
+ {% for column in scrum.scrumcolumns %} {% set idmiletone="-100" %} {% set tbidmiletone=[] %} {% set haveissues=false %} -
+
{{ column.name }}
{% for issue in column.scrumissues %} @@ -22,22 +80,34 @@ {% if idmiletone!=issue.giteamilestone %} {% if idmiletone!=-100 %}{% endif %} - {% if issue.giteamilestone is empty %} -

JALON = Aucun

- {% else %} -

JALON = {{issue.giteajson.milestone.title}}

- {% endif %} - {% if issue.giteamilestone is empty %} {% set tbidmiletone = tbidmiletone|merge([-100]) %} + {% set idmilestone = -100 %} + {% set namemilestone = "Aucun" %} {% else %} {% set tbidmiletone = tbidmiletone|merge([issue.giteamilestone]) %} + {% set idmilestone = issue.giteamilestone %} + {% set namemilestone = issue.giteajson.milestone.title %} {% endif %} -
    + +

    JALON = {{namemilestone}}

    +
      {% set idmiletone=issue.giteamilestone %} {% endif %} -
      + {% set datalabels="" %} + {% for label in issue.giteajson.labels %} + {% if label.id not in giteacolumns %} + {% set datalabels=datalabels~"datalabel"~label.id~" " %} + {% endif %} + {% endfor %} + + {% set dataassignees="" %} + {% for assignee in issue.giteajson.assignees %} + {% set dataassignees=dataassignees~"dataassignee"~assignee.id~" " %} + {% endfor %} + +
      @@ -74,32 +159,158 @@ {% endblock %} {% block localjavascript %} + $(document).ready(function() { + // Apply Filter + function showhide() { + if($("#filtermilestones").val().length !== 0) { + $("[data-milestone]").hide(); + $.each($("#filtermilestones").val(), function( index, value ) { + $("[data-milestone="+value+"]").show(); + }); + } + else $("[data-milestone]").show(); + + $(".issue").hide(); + + if($("#filterlabels").val().length !== 0) { + $( ".issue" ).each(function( index ) { + domissue=$(this); + $.each($("#filterlabels").val(), function( index, value ) { + if (domissue.hasClass("datalabel"+value)) + domissue.show(); + }); + }); + } + + if($("#filterassignees").val().length !== 0) { + $( ".issue" ).each(function( index ) { + domissue=$(this); + $.each($("#filterassignees").val(), function( index, value ) { + if (domissue.hasClass("dataassignee"+value)) + domissue.show(); + }); + }); + } + + if($("#filterlabels").val().length === 0 && $("#filterassignees").val().length === 0) + $(".issue").show(); + } + + // Filter Milestones + function filtermilestones() { + $.ajax({ + method: "POST", + url: "{{ path('app_user_preference') }}", + data: { + key:'filtermilestones', + id:{{scrum.id}}, + value: $("#filtermilestones").val() + } + }); + + 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(); + }); + + // Filter Labels + function filterlabels() { + $.ajax({ + method: "POST", + url: "{{ path('app_user_preference') }}", + data: { + key:'filterlabels', + id:{{scrum.id}}, + value: $("#filterlabels").val() + } + }); + + showhide(); + } + $('#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(); + }); + + // Filtre Assignees + function filterassignees() { + $.ajax({ + method: "POST", + url: "{{ path('app_user_preference') }}", + data: { + key:'filterassignees', + id:{{scrum.id}}, + value: $("#filterassignees").val() + } + }); + + showhide(); + } + $('#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(); + }); + + // Appliy filters + showhide(); + + // Sort columns $( ".scrumcolumn" ).sortable({ handle: ".fa-arrows-alt", connectWith: ".scrumcolumn", cursor: "move", update: function( event, ui ) { id=$(ui.item).data("issue"); - oldlabel=$(ui.item).data("label"); + oldcolumn=$(ui.item).data("column"); oldmilestone=$(ui.item).data("milestone"); - newlabel=$(ui.item).parent().data("label"); + newcolumn=$(ui.item).parent().data("column"); newmilestone=$(ui.item).parent().data("milestone"); - console.log("ID = "+id+" = Label : "+oldlabel+">>"+newlabel+" = Milestone : "+oldmilestone+">>"+newmilestone ); + console.log("ID = "+id+" = Column : "+oldcolumn+">>"+newcolumn+" = Milestone : "+oldmilestone+">>"+newmilestone ); - if(oldlabel!=newlabel||oldmilestone!=newmilestone) { + if(oldcolumn!=newcolumn||oldmilestone!=newmilestone) { $.ajax({ method: "POST", url: "{{path("app_scrumissue_change")}}", data: { id:id, - oldlabel:oldlabel, + oldcolumn:oldcolumn, oldmilestone:oldmilestone, - newlabel:newlabel, + newcolumn:newcolumn, newmilestone:newmilestone, }, success: function() { - $(ui.item).data("label",newlabel); + $(ui.item).data("column",newcolumn); $(ui.item).data("milestone",newmilestone); }, error: function (request, status, error) { @@ -113,10 +324,18 @@ if($(this).data("id")) { if(index==0) lstordered=$(this).data("id"); else lstordered=lstordered+","+$(this).data("id"); - } - + } }); + console.log(lstordered); + $.ajax({ + method: "POST", + url: "{{path("app_scrumissue_order")}}", + data: { + id:{{scrum.id}}, + lstordered:lstordered, + } + }); } }); });