From 2a6f46d68e65d3a0905e6a72076a56935cb0a6ce Mon Sep 17 00:00:00 2001
From: Guillaume Heurtier <guillaume.heurtier@maarch.org>
Date: Mon, 24 Feb 2020 11:25:27 +0100
Subject: [PATCH] FEAT #12069 TIME 1:30 fix merge message in dialog + show only
 tag that can be merged in list

---
 src/app/tag/controllers/TagController.php     | 25 +++++++++++++++++++
 src/app/tag/models/TagModel.php               | 17 +++++++------
 .../tag/tag-administration.component.html     |  4 +--
 .../tag/tag-administration.component.ts       |  9 +++++--
 src/frontend/lang/lang-en.ts                  |  6 +++--
 src/frontend/lang/lang-fr.ts                  | 12 +++++----
 src/frontend/lang/lang-nl.ts                  |  4 ++-
 7 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/src/app/tag/controllers/TagController.php b/src/app/tag/controllers/TagController.php
index bbe962bf2b0..21e6ee263c3 100644
--- a/src/app/tag/controllers/TagController.php
+++ b/src/app/tag/controllers/TagController.php
@@ -38,9 +38,12 @@ class TagController
         ]);
         $countResources = array_column($countResources, 'count', 'tag_id');
 
+        $hasChildren = TagController::hasChildren(['ids' => $ids]);
+
         foreach ($tags as $key => $tag) {
             $tags[$key]['countResources'] = $countResources[$tag['id']] ?? 0;
             $tags[$key]['links'] = json_decode($tags[$key]['links'], true);
+            $tags[$key]['canMerge'] = empty($tag['parent_id']) && !$hasChildren[$tag['id']];
         }
 
         return $response->withJson(['tags' => $tags]);
@@ -495,4 +498,26 @@ class TagController
         }
         return false;
     }
+
+    private static function hasChildren(array $args)
+    {
+        ValidatorModel::notEmpty($args, ['ids']);
+        ValidatorModel::arrayType($args, ['ids']);
+
+        $tags = array_fill_keys($args['ids'], false);
+
+        $childTags = TagModel::get([
+            'select'  => ['count(id)', 'parent_id'],
+            'where'   => ['parent_id in (?)'],
+            'data'    => [$args['ids']],
+            'groupBy' => ['parent_id']
+        ]);
+        $children = array_column($childTags, 'count', 'parent_id');
+
+        foreach ($tags as $id => $item) {
+            $tags[$id] = !empty($children[$id]) && $children[$id] > 0;
+        }
+
+        return $tags;
+    }
 }
diff --git a/src/app/tag/models/TagModel.php b/src/app/tag/models/TagModel.php
index 55c7d7dc2eb..c9e6c8b5766 100644
--- a/src/app/tag/models/TagModel.php
+++ b/src/app/tag/models/TagModel.php
@@ -19,18 +19,19 @@ use SrcCore\models\DatabaseModel;
 
 class TagModel
 {
-    public static function get(array $aArgs = [])
+    public static function get(array $args = [])
     {
-        ValidatorModel::arrayType($aArgs, ['select', 'where', 'data', 'orderBy']);
-        ValidatorModel::intType($aArgs, ['limit']);
+        ValidatorModel::arrayType($args, ['select', 'where', 'data', 'orderBy']);
+        ValidatorModel::intType($args, ['limit']);
 
         $tags = DatabaseModel::select([
-            'select'    => empty($aArgs['select']) ? ['*'] : $aArgs['select'],
+            'select'    => empty($args['select']) ? ['*'] : $args['select'],
             'table'     => ['tags'],
-            'where'     => empty($aArgs['where']) ? [] : $aArgs['where'],
-            'data'      => empty($aArgs['data']) ? [] : $aArgs['data'],
-            'order_by'  => empty($aArgs['orderBy']) ? [] : $aArgs['orderBy'],
-            'limit'     => empty($aArgs['limit']) ? 0 : $aArgs['limit']
+            'where'     => empty($args['where']) ? [] : $args['where'],
+            'data'      => empty($args['data']) ? [] : $args['data'],
+            'order_by'  => empty($args['orderBy']) ? [] : $args['orderBy'],
+            'groupBy'   => empty($args['groupBy']) ? [] : $args['groupBy'],
+            'limit'     => empty($args['limit']) ? 0 : $args['limit']
         ]);
 
         return $tags;
diff --git a/src/frontend/app/administration/tag/tag-administration.component.html b/src/frontend/app/administration/tag/tag-administration.component.html
index de963b968f0..76143916c55 100644
--- a/src/frontend/app/administration/tag/tag-administration.component.html
+++ b/src/frontend/app/administration/tag/tag-administration.component.html
@@ -33,10 +33,10 @@
                         <mat-form-field>
                             <input matInput type="text" [formControl]="tag.usage" [placeholder]="lang.usage">
                         </mat-form-field>
-                        <div *ngIf="!tag.canMerge" class="alert-message alert-message-danger">
+                        <div *ngIf="!creationMode && !tag.canMerge.value" class="alert-message alert-message-danger">
                             {{this.lang.cannotMergeTags}}
                         </div>
-                        <plugin-select-search *ngIf="!loadingTags && tag.canMerge" [label]="this.lang.mergeTagWith" [placeholderLabel]="this.lang.mergeTagWith"
+                        <plugin-select-search *ngIf="!loadingTags && tag.canMerge.value" [label]="this.lang.mergeTagWith" [placeholderLabel]="this.lang.mergeTagWith"
                                 [formControlSelect]="selectMergeTag" [datas]="tags" (afterOpened)="getTags()"
                                 (afterSelected)="mergeTag($event)" style="width:100%;">
                          </plugin-select-search>
diff --git a/src/frontend/app/administration/tag/tag-administration.component.ts b/src/frontend/app/administration/tag/tag-administration.component.ts
index 894143705b4..426a0e803fd 100644
--- a/src/frontend/app/administration/tag/tag-administration.component.ts
+++ b/src/frontend/app/administration/tag/tag-administration.component.ts
@@ -35,6 +35,8 @@ export class TagAdministrationComponent implements OnInit {
         label: new FormControl({ value: '', disabled: false }, [Validators.required]),
         description: new FormControl({ value: '', disabled: false }),
         usage: new FormControl({ value: '', disabled: false }),
+        canMerge: new FormControl({ value: true, disabled: false }),
+        countResources: new FormControl({ value: 0, disabled: false })
     };
 
     selectMergeTag = new FormControl({ value: '', disabled: false });
@@ -133,7 +135,7 @@ export class TagAdministrationComponent implements OnInit {
     getTags() {
         this.http.get('../../rest/tags').pipe(
             tap((data: any) => {                
-                this.tags = data.tags.filter((tag: any) => tag.id != this.id).map((tag: any) => {
+                this.tags = data.tags.filter((tag: any) => tag.id != this.id && tag.canMerge).map((tag: any) => {
                     return {
                         id: tag.id,
                         label: tag.label,
@@ -152,7 +154,10 @@ export class TagAdministrationComponent implements OnInit {
     mergeTag(tagId: any) {
         this.selectMergeTag.reset();
         const selectedTag = this.tags.filter(tag => tag.id === tagId)[0];
-        const dialogRef = this.dialog.open(ConfirmComponent, { autoFocus: false, disableClose: true, data: { title: `${this.lang.mergeWith}  "${selectedTag.label}"`, msg: `${this.lang.confirmAction}<br/><br/><b>${selectedTag.countResources}</b>&nbsp;${this.lang.mails} ${this.lang.willBeTransferedToNewTag}`   } });
+
+        const dialogMessage = `${this.lang.confirmAction}<br/><br/>${this.lang.theTag}<b> "${this.tag.label.value}" </b>${this.lang.willBeDeletedAndMerged}<b> "${selectedTag.label}"</b><br/><b>${this.tag.countResources.value}</b>&nbsp;${this.lang.mails} ${this.lang.willBeTransferredToNewTag}<b> "${selectedTag.label}"</b>`;
+
+        const dialogRef = this.dialog.open(ConfirmComponent, { autoFocus: false, disableClose: true, data: { title: `${this.lang.mergeWith}  "${selectedTag.label}"`, msg: dialogMessage } });
         dialogRef.afterClosed().pipe(
             filter((data: string) => data === 'ok'),
             exhaustMap(() => this.http.put(`../../rest/mergeTags`, { idMaster: selectedTag.id, idMerge: this.id })),
diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts
index 15fc9ff66cb..c4870bc2c3b 100755
--- a/src/frontend/lang/lang-en.ts
+++ b/src/frontend/lang/lang-en.ts
@@ -1551,7 +1551,7 @@ export const LANG_EN = {
     "tagUpdated" : "Tag updated",
     "tagMerged" : "Tag merged",
     "mergeWith" : "Merge with",
-    "willBeTransferedToNewTag" : "will be transfered to selected tag",
+    "willBeTransferredToNewTag" : "will be transferred to tag",
     "detailDoc" : "Detail page",
     "emptySubject" : "Empty subject",
     "noAvailableMenu" : "No available menu",
@@ -1564,5 +1564,7 @@ export const LANG_EN = {
     "generateAndDownloadPrintedFolder" : "Generate the printed folder",
     "mainDocument" : "Main document",
     "attachSummarySheet" : "Attach the summary sheet",
-    "generateSeparators" : "Generate separators for each elements", 
+    "generateSeparators" : "Generate separators for each elements",
+    "theTag" : "The tag",
+    "willBeDeletedAndMerged" : "will be deleted and merged with the tag",
 };
diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts
index f2e1fad0641..188e84bb1ad 100755
--- a/src/frontend/lang/lang-fr.ts
+++ b/src/frontend/lang/lang-fr.ts
@@ -1590,7 +1590,7 @@ export const LANG_FR = {
     "tagUpdated" : "Mot-clé modifié",
     "tagMerged" : "Mot-clé fusionné",
     "mergeWith" : "Fusionner avec",
-    "willBeTransferedToNewTag" : "seront transférés au mot clé sélectionné",
+    "willBeTransferredToNewTag" : "seront transférés au mot clé ",
     "detailDoc" : "Fiche détaillée",
     "emptySubject" : "Objet vide",
     "noAvailableMenu" : "Aucun menu disponible",
@@ -1600,8 +1600,10 @@ export const LANG_FR = {
     "insufficientPrivilege" : "Privilège insuffisant",
     "cannotMergeTags" : "Ce mot-clé possède un parent ou des enfants : impossible de le fusionner avec un autre mot clé.",
     "mergeTagWith" : "Fusionner le mot-clé avec",
-    "generateAndDownloadPrintedFolder" : "Générer le dossier d'impression", 
-    "mainDocument" : "Document principal", 
-    "attachSummarySheet" : "Attacher la fiche de liaison", 
-    "generateSeparators" : "Générer des intercalaires entre les élements", 
+    "generateAndDownloadPrintedFolder" : "Générer le dossier d'impression",
+    "mainDocument" : "Document principal",
+    "attachSummarySheet" : "Attacher la fiche de liaison",
+    "generateSeparators" : "Générer des intercalaires entre les élements",
+    "theTag" : "Le mot-clé",
+    "willBeDeletedAndMerged" : "sera supprimé et fusionné avec le mot-clé",
 };
diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts
index f70f7d8b5f2..7f40780f111 100755
--- a/src/frontend/lang/lang-nl.ts
+++ b/src/frontend/lang/lang-nl.ts
@@ -1576,7 +1576,7 @@ export const LANG_NL = {
     "tagUpdated" : "Tag updated", //_TO_TRANSLATE
     "tagMerged" : "Tag merged", //_TO_TRANSLATE
     "mergeWith" : "Merge with", //_TO_TRANSLATE
-    "willBeTransferedToNewTag" : "will be transfered to selected tag", //_TO_TRANSLATE
+    "willBeTransferredToNewTag" : "will be transferred to tag ", //_TO_TRANSLATE
     "detailDoc" : "Detail page", //_TO_TRANSLATE
     "emptySubject" : "Empty subject", //_TO_TRANSLATE
     "noAvailableMenu" : "No available menu", //_TO_TRANSLATE
@@ -1590,4 +1590,6 @@ export const LANG_NL = {
     "mainDocument" : "Main document", //_TO_TRANSLATE
     "attachSummarySheet" : "Attach the summary sheet", //_TO_TRANSLATE
     "generateSeparators" : "Generate separators for each elements", //_TO_TRANSLATE
+    "theTag" : "The tag",//_TO_TRANSLATE
+    "willBeDeletedAndMerged" : "will be deleted and merged with the tag",//_TO_TRANSLATE
 };
-- 
GitLab