From 0787e377f91ff278ae851a787ff67ad5c65f4921 Mon Sep 17 00:00:00 2001
From: descamps <descamps@cines.fr>
Date: Wed, 14 Apr 2021 18:16:59 +0200
Subject: [PATCH] =?UTF-8?q?fix=20-=20KDE=20-=2014/02/2021=20-=20#38#39=20-?=
 =?UTF-8?q?=20Pb=20de=20chargement=20d'un=20PA=20apr=C3=A8s=20avoir=20?=
 =?UTF-8?q?=C3=A9dit=C3=A9=20un=20PUA=C2=A0=20Apr=C3=A8s=20avoir=20=C3=A9d?=
 =?UTF-8?q?it=C3=A9=20un=20PUA,=20quand=20on=20fait=20un=20retour=20vers?=
 =?UTF-8?q?=20la=20liste=20des=20profils=20et=20qu'on=20veut=20ouvrir=20un?=
 =?UTF-8?q?=20PA,=20l'appli=20plante=20et=20le=20charge=20ind=C3=A9finimen?=
 =?UTF-8?q?t.=C2=A0=20Initialisation=20du=20BehaviourSubject=20provenant?=
 =?UTF-8?q?=20d'un=20service=20=C3=A0=20partir=20du=20component=20pour=20l?=
 =?UTF-8?q?e=20retrouver=20=C3=A0=20jour=20lorsque=20l'on=20sort=20du=20co?=
 =?UTF-8?q?mponent=20/=20fix-=20KDE=20-=2014/04/2021=20-=20#38=20-=20Probl?=
 =?UTF-8?q?=C3=A8me=20corrig=C3=A9=20sur=20la=20fermeture=20de=20la=20pop-?=
 =?UTF-8?q?up=20qui=20=C3=A9tait=20g=C3=A9n=C3=A9ral=20au=20niveau=20de=20?=
 =?UTF-8?q?l'application=20et=20notamment=20de=20l'edit=20component.=20La?=
 =?UTF-8?q?=20pop-up=20ne=20se=20fermait=20plus=20car=20elle=20=C3=A9tait?=
 =?UTF-8?q?=20charg=C3=A9=20autant=20de=20fois=20que=20l'on=20faisait=20de?=
 =?UTF-8?q?s=20aller=20retour=20sur=20cet=20ecran.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../src/app/core/services/file.service.ts     | 89 +++++++++----------
 .../pastis/src/app/main/main.component.html   |  6 +-
 .../pastis/src/app/main/main.component.ts     | 53 +++++++----
 .../edit-profile/edit-profile.component.html  |  2 +-
 .../edit-profile/edit-profile.component.ts    | 27 +++---
 .../file-tree-metadata.component.ts           | 55 ++++++++----
 .../file-tree/file-tree.component.ts          | 74 +++++++--------
 .../pastis-dialog-confirm.component.ts        | 36 ++++----
 8 files changed, 186 insertions(+), 156 deletions(-)

diff --git a/ui/ui-frontend/projects/pastis/src/app/core/services/file.service.ts b/ui/ui-frontend/projects/pastis/src/app/core/services/file.service.ts
index b65e3ed02..662b1d615 100644
--- a/ui/ui-frontend/projects/pastis/src/app/core/services/file.service.ts
+++ b/ui/ui-frontend/projects/pastis/src/app/core/services/file.service.ts
@@ -1,25 +1,25 @@
 /*
-Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020) 
+Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020)
 
 [dad@cines.fr]
 
-This software is a computer program whose purpose is to provide 
-a web application to create, edit, import and export archive 
+This software is a computer program whose purpose is to provide
+a web application to create, edit, import and export archive
 profiles based on the french SEDA standard
 (https://redirect.francearchives.fr/seda/).
 
 
 This software is governed by the CeCILL-C  license under French law and
-abiding by the rules of distribution of free software.  You can  use, 
+abiding by the rules of distribution of free software.  You can  use,
 modify and/ or redistribute the software under the terms of the CeCILL-C
 license as circulated by CEA, CNRS and INRIA at the following URL
-"http://www.cecill.info". 
+"http://www.cecill.info".
 
 As a counterpart to the access to the source code and  rights to copy,
 modify and redistribute granted by the license, users are provided only
 with a limited warranty  and the software's author,  the holder of the
 economic rights,  and the successive licensors  have only  limited
-liability. 
+liability.
 
 In this respect, the user's attention is drawn to the risks associated
 with loading,  using,  modifying and/or developing or reproducing the
@@ -28,25 +28,25 @@ that may mean  that it is complicated to manipulate,  and  that  also
 therefore means  that it is reserved for developers  and  experienced
 professionals having in-depth computer knowledge. Users are therefore
 encouraged to load and test the software's suitability as regards their
-requirements in conditions enabling the security of their systems and/or 
-data to be ensured and,  more generally, to use and operate it in the 
-same conditions as regards security. 
+requirements in conditions enabling the security of their systems and/or
+data to be ensured and,  more generally, to use and operate it in the
+same conditions as regards security.
 
 The fact that you are presently reading this means that you have had
 knowledge of the CeCILL-C license and that you accept its terms.
 */
-import { EventEmitter, Injectable, Output } from '@angular/core';
-import { MatDialog } from '@angular/material/dialog';
-import { BehaviorSubject, Observable } from 'rxjs';
-import { SedaData, SedaElementConstants, SedaCardinalityConstants } from '../../profile/edit-profile/classes/seda-data';
-import { FileNode, TypeConstants,FileNodeInsertParams, FileNodeInsertAttributeParams } from '../../profile/edit-profile/classes/file-node';
-import { PastisDialogConfirmComponent } from '../../shared/pastis-dialog/pastis-dialog-confirm/pastis-dialog-confirm.component';
-import { ProfileService } from './profile.service';
-import { PastisDialogData } from 'projects/pastis/src/app/shared/pastis-dialog/classes/pastis-dialog-data';
-import { SedaService } from './seda.service';
-import { FileTreeMetadataService } from '../../profile/edit-profile/file-tree-metadata/file-tree-metadata.service';
-import { PuaService } from './pua.service';
-import { ComponentType } from '@angular/cdk/portal';
+import {Injectable} from '@angular/core';
+import {MatDialog} from '@angular/material/dialog';
+import {BehaviorSubject, Observable} from 'rxjs';
+import {SedaCardinalityConstants, SedaData, SedaElementConstants} from '../../profile/edit-profile/classes/seda-data';
+import {FileNode, TypeConstants} from '../../profile/edit-profile/classes/file-node';
+import {PastisDialogConfirmComponent} from '../../shared/pastis-dialog/pastis-dialog-confirm/pastis-dialog-confirm.component';
+import {ProfileService} from './profile.service';
+import {PastisDialogData} from 'projects/pastis/src/app/shared/pastis-dialog/classes/pastis-dialog-data';
+import {SedaService} from './seda.service';
+import {FileTreeMetadataService} from '../../profile/edit-profile/file-tree-metadata/file-tree-metadata.service';
+import {PuaService} from './pua.service';
+import {ComponentType} from '@angular/cdk/portal';
 
 @Injectable({
   providedIn: 'root'
@@ -54,17 +54,6 @@ import { ComponentType } from '@angular/cdk/portal';
 
 export class FileService  {
 
-  @Output()
-  public addNode: EventEmitter<FileNode> = new EventEmitter<FileNode>();
-  @Output()
-  public insertItem: EventEmitter<FileNodeInsertParams> = new EventEmitter<FileNodeInsertParams>();
-  @Output()
-  public insertAttributes: EventEmitter<FileNodeInsertAttributeParams> = new EventEmitter<FileNodeInsertAttributeParams>();
-  @Output()
-  public removeNode: EventEmitter<FileNode> = new EventEmitter<FileNode>();
-  @Output()
-  public renderChanges: EventEmitter<boolean> = new EventEmitter<boolean>();
-
   dataChange = new BehaviorSubject<FileNode[]>([]);
   profile = new BehaviorSubject<any>([]);
   notice = new BehaviorSubject<any>([]);
@@ -79,7 +68,7 @@ export class FileService  {
   tabChildrenRulesChange = new BehaviorSubject<string[][]>([]);
 
 
-  
+
   parentNodeMap = new Map<FileNode, FileNode>();
 
   constructor(private profileService: ProfileService,  private fileMetadataService: FileTreeMetadataService,
@@ -90,6 +79,10 @@ export class FileService  {
       return this.dataChange;
   }
 
+  reinitialisaDataChange() {
+    this.dataChange = new BehaviorSubject<FileNode[]>([]);
+  }
+
   addSedaMetadataToFileTree(id:number){
     this.profileService.getProfile(id).subscribe((response) => {
       this.profile.next(response);
@@ -116,7 +109,7 @@ export class FileService  {
   return this.dataChange;
   }
 
-  
+
 
   sedaDataArchiveUnit : SedaData;
 
@@ -125,9 +118,9 @@ export class FileService  {
    *
    * Les nodes correspondant aux ArchivesUnit
    * se réfèrent à la définition SEDA de l'ArchiveUnit mère (ils sont récursifs...)
-   * @param parent 
-   * @param _nodes 
-   * @param sedaData 
+   * @param parent
+   * @param _nodes
+   * @param sedaData
    */
   linkFileNodeToSedaData(parent: FileNode, _nodes: FileNode[], sedaData: SedaData[]){
     Array.prototype.forEach.call((_nodes: any,node: any) => {
@@ -202,7 +195,7 @@ export class FileService  {
 
   openPopup(popData: PastisDialogData){
     const dialogConfirmRef = this.dialog.open(PastisDialogConfirmComponent, {
-      width: popData.width, 
+      width: popData.width,
       height: popData.height,
       data: popData,
       panelClass: 'pastis-popup-modal-box'
@@ -232,7 +225,7 @@ export class FileService  {
       }
     }
   }
-  
+
   setCollectionName(collectionName:string){
     this.collectionName.next(collectionName);
   }
@@ -240,12 +233,12 @@ export class FileService  {
   setTabRootMetadataName(rootTabMetadataName:string){
     this.rootTabMetadataName.next(rootTabMetadataName);
   }
-  
+
 
   openDialogWithTemplateRef(templateRef: ComponentType<unknown>) {
     this.dialog.open(templateRef);
   }
-  
+
   setNewChildrenRules(rules:string[][]){
       this.tabChildrenRulesChange.next(rules);
   }
@@ -271,7 +264,7 @@ export class FileService  {
     updateItem(node: FileNode) {
       this.dataChange.next(node[0]);
       console.log("Node updated to : ", this.dataChange.getValue())
-  
+
     }
 
     removeItem(nodesToBeDeleted: FileNode[], root: FileNode) {
@@ -286,7 +279,7 @@ export class FileService  {
             if (index !== -1) {
               parentNode.children.splice(index, 1);
               this.parentNodeMap.delete(nodeToBeDeleted);
-            } 
+            }
             console.log("Deleted node : ", nodeToBeDeleted, "and his parent : ", parentNode);
           }
         }
@@ -388,11 +381,11 @@ export class FileService  {
 
    getComplexSedaChildrenAsFileNode(sedaElement:SedaData):FileNode[] {
     // Insert all children of complex elements based on SEDA definition
-    if (sedaElement.Element === SedaElementConstants.complex && 
+    if (sedaElement.Element === SedaElementConstants.complex &&
       sedaElement.Children.length > 0) {
           let fileNodeComplexChildren : FileNode[] = [];
           sedaElement.Children.forEach((child: { Cardinality: string; Name: string; Type: string; }) => {
-                if (child.Cardinality === SedaCardinalityConstants.one || 
+                if (child.Cardinality === SedaCardinalityConstants.one ||
                     child.Cardinality === SedaCardinalityConstants.oreOrMore) {
                       let aFileNode : FileNode = {} as FileNode;
                       aFileNode.name = child.Name;
@@ -400,13 +393,13 @@ export class FileService  {
                       aFileNode.children = [];
                       aFileNode.type = TypeConstants[child.Type as keyof typeof TypeConstants];
                       fileNodeComplexChildren.push(aFileNode);
-                } 
+                }
               })
               return fileNodeComplexChildren
             }
 
     }
-    
+
     updateMedataTable(node:FileNode){
       //let isNodeComplex = this.sedaService.checkSedaElementType(node.name,this.sedaService.selectedSedaNodeParent.getValue())
       let rulesFromService = this.tabChildrenRulesChange.getValue()
@@ -415,7 +408,7 @@ export class FileService  {
       this.sedaService.selectedSedaNode.next(node.sedaData);
       let dataTable = this.fileMetadataService.fillDataTable(node.sedaData, node, tabChildrenToInclude, tabChildrenToExclude);
       let hasAtLeastOneComplexChild = node.children.some(el=> el.type  === TypeConstants.element);
-  
+
       if(node.sedaData.Element === SedaElementConstants.complex){
         this.fileMetadataService.shouldLoadMetadataTable.next(hasAtLeastOneComplexChild);
         console.log("The the current tab root node is : ", node)
diff --git a/ui/ui-frontend/projects/pastis/src/app/main/main.component.html b/ui/ui-frontend/projects/pastis/src/app/main/main.component.html
index 58f22e385..b0691a9d7 100644
--- a/ui/ui-frontend/projects/pastis/src/app/main/main.component.html
+++ b/ui/ui-frontend/projects/pastis/src/app/main/main.component.html
@@ -16,7 +16,11 @@
     <mat-sidenav-content >
         <div class="pastis-entete-bandeau"></div>
         <div>
-            <pastis-file-tree-metadata style="text-align: center;" *ngIf="!noticeDisplay"></pastis-file-tree-metadata>
+            <pastis-file-tree-metadata style="text-align: center;" *ngIf="!noticeDisplay" (insertItem)="insertionItem($event)"
+                                       (addNode)="addNode($event)"
+                                       (insertAttributes)="insertAttribute($event)"
+                                       (removeNode)="removeNode($event)">
+            </pastis-file-tree-metadata>
 
             <pastis-notice *ngIf="noticeDisplay"></pastis-notice>
 
diff --git a/ui/ui-frontend/projects/pastis/src/app/main/main.component.ts b/ui/ui-frontend/projects/pastis/src/app/main/main.component.ts
index 7dba75f99..79bcc0bcd 100644
--- a/ui/ui-frontend/projects/pastis/src/app/main/main.component.ts
+++ b/ui/ui-frontend/projects/pastis/src/app/main/main.component.ts
@@ -1,25 +1,25 @@
 /*
-Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020) 
+Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020)
 
 [dad@cines.fr]
 
-This software is a computer program whose purpose is to provide 
-a web application to create, edit, import and export archive 
+This software is a computer program whose purpose is to provide
+a web application to create, edit, import and export archive
 profiles based on the french SEDA standard
 (https://redirect.francearchives.fr/seda/).
 
 
 This software is governed by the CeCILL-C  license under French law and
-abiding by the rules of distribution of free software.  You can  use, 
+abiding by the rules of distribution of free software.  You can  use,
 modify and/ or redistribute the software under the terms of the CeCILL-C
 license as circulated by CEA, CNRS and INRIA at the following URL
-"http://www.cecill.info". 
+"http://www.cecill.info".
 
 As a counterpart to the access to the source code and  rights to copy,
 modify and redistribute granted by the license, users are provided only
 with a limited warranty  and the software's author,  the holder of the
 economic rights,  and the successive licensors  have only  limited
-liability. 
+liability.
 
 In this respect, the user's attention is drawn to the risks associated
 with loading,  using,  modifying and/or developing or reproducing the
@@ -28,19 +28,21 @@ that may mean  that it is complicated to manipulate,  and  that  also
 therefore means  that it is reserved for developers  and  experienced
 professionals having in-depth computer knowledge. Users are therefore
 encouraged to load and test the software's suitability as regards their
-requirements in conditions enabling the security of their systems and/or 
-data to be ensured and,  more generally, to use and operate it in the 
-same conditions as regards security. 
+requirements in conditions enabling the security of their systems and/or
+data to be ensured and,  more generally, to use and operate it in the
+same conditions as regards security.
 
 The fact that you are presently reading this means that you have had
 knowledge of the CeCILL-C license and that you accept its terms.
 */
-import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
-import { CdkTextareaAutosize } from '@angular/cdk/text-field';
-import { ActivatedRoute } from '@angular/router';
-import { ToggleSidenavService } from '../core/services/toggle-sidenav.service';
-import { ToastContainerDirective, ToastrService } from 'ngx-toastr';
-import { Subscription } from 'rxjs';
+import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
+import {CdkTextareaAutosize} from '@angular/cdk/text-field';
+import {ActivatedRoute} from '@angular/router';
+import {ToggleSidenavService} from '../core/services/toggle-sidenav.service';
+import {ToastContainerDirective, ToastrService} from 'ngx-toastr';
+import {Subscription} from 'rxjs';
+import {EditProfileComponent} from '../profile/edit-profile/edit-profile.component';
+import {FileNode, FileNodeInsertAttributeParams, FileNodeInsertParams} from "../profile/edit-profile/classes/file-node";
 
 @Component({
   selector: 'app-home',
@@ -54,6 +56,8 @@ export class MainComponent implements OnInit, OnDestroy {
   @ViewChild('autosize', { static: false }) autosize: CdkTextareaAutosize;
   @ViewChild(ToastContainerDirective, { static: true })
   toastContainer: ToastContainerDirective;
+  @ViewChild(EditProfileComponent)
+  editProfileComponent: EditProfileComponent;
 
   opened: boolean;
   events: string[] = [];
@@ -88,6 +92,25 @@ export class MainComponent implements OnInit, OnDestroy {
     this.opened = false;
   }
 
+  insertionItem($event: FileNodeInsertParams) {
+    this.editProfileComponent.fileTreeComponent.insertItem($event.node, $event.elementsToAdd);
+    console.log("Params : ", $event);
+  }
+
+  addNode($event: FileNode) {
+    this.editProfileComponent.fileTreeComponent.addNewItem($event);
+
+  }
+
+  insertAttribute($event: FileNodeInsertAttributeParams) {
+    console.log("Params in attributes : ", $event);
+    this.editProfileComponent.fileTreeComponent.insertAttributes($event.node, $event.elementsToAdd);
+  }
+
+  removeNode($event: FileNode) {
+    this.editProfileComponent.fileTreeComponent.remove($event);
+  }
+
   ngOnDestroy(): void {
     this.noticeDisplaySub.unsubscribe();
   }
diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.html b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.html
index 23c515b64..795deccfc 100644
--- a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.html
+++ b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.html
@@ -6,7 +6,7 @@
         <span class="pastis-edit-profile-header-name">Nom du profil d'archivage</span>
     </div>
 
-    <div class="pastis-edit-profile-header-id">Identifiant : 1223435596993056</div>
+    <div class="pastis-edit-profile-header-id">Identifiant : {{profileId}}</div>
 </div>
 <mat-tab-group
         [selectedIndex]="activeTabIndex"
diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.ts b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.ts
index cbab8f39c..b51a55983 100644
--- a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.ts
+++ b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/edit-profile.component.ts
@@ -1,25 +1,25 @@
 /*
-Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020) 
+Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020)
 
 [dad@cines.fr]
 
-This software is a computer program whose purpose is to provide 
-a web application to create, edit, import and export archive 
+This software is a computer program whose purpose is to provide
+a web application to create, edit, import and export archive
 profiles based on the french SEDA standard
 (https://redirect.francearchives.fr/seda/).
 
 
 This software is governed by the CeCILL-C  license under French law and
-abiding by the rules of distribution of free software.  You can  use, 
+abiding by the rules of distribution of free software.  You can  use,
 modify and/ or redistribute the software under the terms of the CeCILL-C
 license as circulated by CEA, CNRS and INRIA at the following URL
-"http://www.cecill.info". 
+"http://www.cecill.info".
 
 As a counterpart to the access to the source code and  rights to copy,
 modify and redistribute granted by the license, users are provided only
 with a limited warranty  and the software's author,  the holder of the
 economic rights,  and the successive licensors  have only  limited
-liability. 
+liability.
 
 In this respect, the user's attention is drawn to the risks associated
 with loading,  using,  modifying and/or developing or reproducing the
@@ -28,9 +28,9 @@ that may mean  that it is complicated to manipulate,  and  that  also
 therefore means  that it is reserved for developers  and  experienced
 professionals having in-depth computer knowledge. Users are therefore
 encouraged to load and test the software's suitability as regards their
-requirements in conditions enabling the security of their systems and/or 
-data to be ensured and,  more generally, to use and operate it in the 
-same conditions as regards security. 
+requirements in conditions enabling the security of their systems and/or
+data to be ensured and,  more generally, to use and operate it in the
+same conditions as regards security.
 
 The fact that you are presently reading this means that you have had
 knowledge of the CeCILL-C license and that you accept its terms.
@@ -44,7 +44,7 @@ import { FileNode } from './classes/file-node';
 import { MatTabChangeEvent } from '@angular/material/tabs';
 import { MatTreeNestedDataSource } from '@angular/material/tree';
 import { NestedTreeControl } from '@angular/cdk/tree';
-import { BehaviorSubject } from 'rxjs';
+import { BehaviorSubject} from 'rxjs';
 import { FileTreeComponent } from './file-tree/file-tree.component';
 import { SedaData } from './classes/seda-data';
 import { NgxUiLoaderService } from 'ngx-ui-loader';
@@ -126,6 +126,7 @@ export class EditProfileComponent implements OnInit, OnDestroy {
               private sideNavService: ToggleSidenavService, private profileService: ProfileService,
               private loaderService: NgxUiLoaderService) {
 
+
     let uploadedProfileResponse = this.router.getCurrentNavigation().extras.state;
 
     // Get profile type if profile is user uploads a file
@@ -134,12 +135,14 @@ export class EditProfileComponent implements OnInit, OnDestroy {
       this.profileType =  this.profile[0].name === "ArchiveTransfer" ? "PA" : "PUA";
       this.profileService.setProfileMode(this.profileType);
       this.initActiveTabAndProfileMode();
+      console.log(this.puaMode)
     } else {
       // Get profile type if profile is selected from the list of profiles
       this.profileService.getAllProfiles().subscribe(profiles => {
         this.profileType = profiles.find(p => p.id.toString() === this.profileId.toString()).type;
         this.profileService.setProfileMode(this.profileType);
         this.initActiveTabAndProfileMode();
+        console.warn(this.puaMode)
       })
     }
 
@@ -178,7 +181,7 @@ export class EditProfileComponent implements OnInit, OnDestroy {
         [this.objectTabChildrenToInclude, this.objectTabChildrenToExclude])
   }
   ngOnInit() {
-
+    this.fileService.reinitialisaDataChange();
     this.setTabsAndMetadataRules(this.activeTabIndex);
     //Set initial rules
     this.fileService.setCollectionName(this.collectionName);
@@ -244,7 +247,7 @@ export class EditProfileComponent implements OnInit, OnDestroy {
     // If you want to see notice don't need to load profile
     if(this.puaMode && event.index == 0){
       this.noticeSelected = true;
-      this.sideNavService.statusNotice(this.noticeSelected);      
+      this.sideNavService.statusNotice(this.noticeSelected);
     }else{
       this.setTabsAndMetadataRules(event.index);
       this.loadProfileData();
diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.ts b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.ts
index a4aadda09..8dd321671 100644
--- a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.ts
+++ b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.ts
@@ -1,25 +1,25 @@
 /*
-Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020) 
+Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020)
 
 [dad@cines.fr]
 
-This software is a computer program whose purpose is to provide 
-a web application to create, edit, import and export archive 
+This software is a computer program whose purpose is to provide
+a web application to create, edit, import and export archive
 profiles based on the french SEDA standard
 (https://redirect.francearchives.fr/seda/).
 
 
 This software is governed by the CeCILL-C  license under French law and
-abiding by the rules of distribution of free software.  You can  use, 
+abiding by the rules of distribution of free software.  You can  use,
 modify and/ or redistribute the software under the terms of the CeCILL-C
 license as circulated by CEA, CNRS and INRIA at the following URL
-"http://www.cecill.info". 
+"http://www.cecill.info".
 
 As a counterpart to the access to the source code and  rights to copy,
 modify and redistribute granted by the license, users are provided only
 with a limited warranty  and the software's author,  the holder of the
 economic rights,  and the successive licensors  have only  limited
-liability. 
+liability.
 
 In this respect, the user's attention is drawn to the risks associated
 with loading,  using,  modifying and/or developing or reproducing the
@@ -28,15 +28,15 @@ that may mean  that it is complicated to manipulate,  and  that  also
 therefore means  that it is reserved for developers  and  experienced
 professionals having in-depth computer knowledge. Users are therefore
 encouraged to load and test the software's suitability as regards their
-requirements in conditions enabling the security of their systems and/or 
-data to be ensured and,  more generally, to use and operate it in the 
-same conditions as regards security. 
+requirements in conditions enabling the security of their systems and/or
+data to be ensured and,  more generally, to use and operate it in the
+same conditions as regards security.
 
 The fact that you are presently reading this means that you have had
 knowledge of the CeCILL-C license and that you accept its terms.
 */
 import { CdkTextareaAutosize } from '@angular/cdk/text-field';
-import { Component, ViewChild, ViewEncapsulation } from '@angular/core';
+import { Component, EventEmitter, Output, ViewChild, ViewEncapsulation} from '@angular/core';
 import { FormBuilder, FormControl, Validators } from '@angular/forms';
 import { MatTableDataSource } from '@angular/material/table';
 import { FileService } from '../../../core/services/file.service';
@@ -51,6 +51,7 @@ import { AttributeData } from './attributes/models/edit-attribute-models';
 import { NotificationService } from 'projects/pastis/src/app/core/services/notification.service';
 import { NgxUiLoaderService } from 'ngx-ui-loader';
 import { Router } from '@angular/router';
+import {Subscription} from "rxjs";
 
 
 
@@ -102,6 +103,20 @@ export class FileTreeMetadataComponent {
 
   config: {};
 
+  @Output()
+  public insertItem: EventEmitter<FileNodeInsertParams> = new EventEmitter<FileNodeInsertParams>();
+
+  @Output()
+  public addNode: EventEmitter<FileNode> = new EventEmitter<FileNode>();
+
+  @Output()
+  public insertAttributes: EventEmitter<FileNodeInsertAttributeParams> = new EventEmitter<FileNodeInsertAttributeParams>();
+
+  @Output()
+  public removeNode: EventEmitter<FileNode> = new EventEmitter<FileNode>();
+
+  private _fileServiceSubscription : Subscription;
+
   metadatadaValueFormControl = new FormControl('', [Validators.required, Validators.pattern(this.regexPattern)]);
 
   valueForm = this.fb.group({
@@ -122,7 +137,7 @@ export class FileTreeMetadataComponent {
   ngOnInit() {
     //Subscription to fileNode service
     this.ngxLoader.startLoader('table-metadata');
-    this.fileService.getCurrentFileTree().subscribe(fileTree => {
+    this._fileServiceSubscription=this.fileService.getCurrentFileTree().subscribe(fileTree => {
       if (fileTree) {
         this.clickedNode = fileTree[0];
         this.fileService.allData.next(fileTree);
@@ -259,11 +274,11 @@ export class FileTreeMetadataComponent {
         node: this.clickedNode,
         elementsToAdd: ['ArchiveUnit']
       }
-      this.fileService.insertItem.emit(params);
+      this.insertItem.emit(params);
       this.notificationService.showSuccess('La métadonnée ArchiveUnit a été ajoutée');
 
     } else {
-      this.fileService.addNode.emit(this.clickedNode)
+      this.addNode.emit(this.clickedNode)
     }
   }
 
@@ -304,7 +319,7 @@ export class FileTreeMetadataComponent {
           let fileNode: FileNode = {} as FileNode;
           fileNode.name = attr.nomDuChamp;
           attributeFileNodeListToRemove.push(fileNode);
-        })
+        });
         if (attributeFileNodeListToAdd) {
           let insertOrEditParams: FileNodeInsertAttributeParams = { node: popData.fileNode, elementsToAdd: attributeFileNodeListToAdd }
           let attrsToAdd = attributeFileNodeListToAdd.map(e => e.name);
@@ -312,7 +327,7 @@ export class FileTreeMetadataComponent {
 
           //Add attribute (if it does not exist), or update them if they do
           if (attrsToAdd && !attributeExists) {
-            this.fileService.insertAttributes.emit(insertOrEditParams);
+            this.insertAttributes.emit(insertOrEditParams);
           } else {
             this.fileService.updateNodeChildren(popData.fileNode, attributeFileNodeListToAdd)
           }
@@ -326,7 +341,7 @@ export class FileTreeMetadataComponent {
 
   onDeleteNode(nodeId: number) {
     const nodeToDelete = this.fileService.getFileNodeById(this.fileService.nodeChange.getValue(), nodeId);
-    this.fileService.removeNode.emit(nodeToDelete)
+    this.removeNode.emit(nodeToDelete)
   }
 
   onButtonClicked(elementId: number) {
@@ -369,7 +384,7 @@ export class FileTreeMetadataComponent {
   }
 
   /**
-   * Returns a boolean if a given node has one or more attributes 
+   * Returns a boolean if a given node has one or more attributes
    * regarding its seda specification
    * @param nodeName The node's name to be tested
    */
@@ -417,4 +432,10 @@ export class FileTreeMetadataComponent {
     this.router.navigate(['/'],{skipLocationChange: false});
   }
 
+  ngOnDestroy(){
+    if(this._fileServiceSubscription!= null){
+      this._fileServiceSubscription.unsubscribe();
+    }
+  }
+
 }
diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree/file-tree.component.ts b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree/file-tree.component.ts
index b966e35c3..e4e6118a1 100644
--- a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree/file-tree.component.ts
+++ b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree/file-tree.component.ts
@@ -1,25 +1,25 @@
 /*
-Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020) 
+Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020)
 
 [dad@cines.fr]
 
-This software is a computer program whose purpose is to provide 
-a web application to create, edit, import and export archive 
+This software is a computer program whose purpose is to provide
+a web application to create, edit, import and export archive
 profiles based on the french SEDA standard
 (https://redirect.francearchives.fr/seda/)
 
 
 This software is governed by the CeCILL-C  license under French law and
-abiding by the rules of distribution of free software.  You can  use, 
+abiding by the rules of distribution of free software.  You can  use,
 modify and/ or redistribute the software under the terms of the CeCILL-C
 license as circulated by CEA, CNRS and INRIA at the following URL
-"http://www.cecill.info". 
+"http://www.cecill.info".
 
 As a counterpart to the access to the source code and  rights to copy,
 modify and redistribute granted by the license, users are provided only
 with a limited warranty  and the software's author,  the holder of the
 economic rights,  and the successive licensors  have only  limited
-liability. 
+liability.
 
 In this respect, the user's attention is drawn to the risks associated
 with loading,  using,  modifying and/or developing or reproducing the
@@ -28,27 +28,27 @@ that may mean  that it is complicated to manipulate,  and  that  also
 therefore means  that it is reserved for developers  and  experienced
 professionals having in-depth computer knowledge. Users are therefore
 encouraged to load and test the software's suitability as regards their
-requirements in conditions enabling the security of their systems and/or 
-data to be ensured and,  more generally, to use and operate it in the 
-same conditions as regards security. 
+requirements in conditions enabling the security of their systems and/or
+data to be ensured and,  more generally, to use and operate it in the
+same conditions as regards security.
 
 The fact that you are presently reading this means that you have had
 knowledge of the CeCILL-C license and that you accept its terms.
 */
-import { CdkTextareaAutosize } from '@angular/cdk/text-field';
-import { NestedTreeControl } from '@angular/cdk/tree';
-import { Component, Input, ViewChild, } from '@angular/core';
-import { MatTreeNestedDataSource } from '@angular/material/tree';
-import { BehaviorSubject, throwError } from 'rxjs';
-import { SedaData, SedaElementConstants, SedaCardinalityConstants } from '../classes/seda-data';
-import { SedaService } from '../../../core/services/seda.service';
-import { NotificationService } from '../../../core/services/notification.service';
-import { FileService } from '../../../core/services/file.service';
-import { CardinalityConstants, FileNode, TypeConstants, DataTypeConstants, FileNodeInsertParams, FileNodeInsertAttributeParams } from '../classes/file-node';
-import { FileTreeMetadataService } from '../file-tree-metadata/file-tree-metadata.service';
-import { UserActionAddMetadataComponent } from '../../../user-actions/add-metadata/add-metadata.component';
-import { PastisDialogData } from '../../../shared/pastis-dialog/classes/pastis-dialog-data';
-import { UserActionRemoveMetadataComponent } from '../../../user-actions/remove-metadata/remove-metadata.component';
+import {CdkTextareaAutosize} from '@angular/cdk/text-field';
+import {NestedTreeControl} from '@angular/cdk/tree';
+import {Component, Input, ViewChild,} from '@angular/core';
+import {MatTreeNestedDataSource} from '@angular/material/tree';
+import {BehaviorSubject, throwError} from 'rxjs';
+import {SedaCardinalityConstants, SedaData, SedaElementConstants} from '../classes/seda-data';
+import {SedaService} from '../../../core/services/seda.service';
+import {NotificationService} from '../../../core/services/notification.service';
+import {FileService} from '../../../core/services/file.service';
+import {CardinalityConstants, DataTypeConstants, FileNode, TypeConstants} from '../classes/file-node';
+import {FileTreeMetadataService} from '../file-tree-metadata/file-tree-metadata.service';
+import {UserActionAddMetadataComponent} from '../../../user-actions/add-metadata/add-metadata.component';
+import {PastisDialogData} from '../../../shared/pastis-dialog/classes/pastis-dialog-data';
+import {UserActionRemoveMetadataComponent} from '../../../user-actions/remove-metadata/remove-metadata.component';
 
 @Component({
   selector: 'pastis-file-tree',
@@ -109,20 +109,6 @@ export class FileTreeComponent {
         this.sedaService.selectedSedaNodeParent.next(this.sedaData);
         console.log("Init seda node on file tree : %o", this.sedaService.selectedSedaNode.getValue(), " on tab : ", this.rootElementName);
       })
-      this.fileService.addNode.subscribe((node: FileNode) => {
-        this.addNewItem(node)
-      })
-      this.fileService.insertItem.subscribe((params: FileNodeInsertParams) => {
-        console.log("Params : ", params)
-        this.insertItem(params.node, params.elementsToAdd)
-      })
-      this.fileService.insertAttributes.subscribe((params: FileNodeInsertAttributeParams) => {
-        console.log("Params in attributes : ", params)
-        this.insertAttributes(params.node, params.elementsToAdd)
-      })
-      this.fileService.removeNode.subscribe((node: FileNode) => {
-        this.remove(node)
-      })
       this.fileService.tabChildrenRulesChange.subscribe(rules => {
         this.rulesChange = rules;
       })
@@ -226,7 +212,7 @@ export class FileTreeComponent {
           sedaChild.Children.filter((c: { Element: any; }) => c.Element === SedaElementConstants.attribute).forEach((child: { Name: string; Element: any; Cardinality: any; }) => {
             let isAttributeAlreadyIncluded = newNode.children.some(nodeChild => nodeChild.name.includes(child.Name));
             // If the added node contains an obligatory attribute,
-            // on its seda definition and the attribute is not already part of the node, 
+            // on its seda definition and the attribute is not already part of the node,
             // we then, build an attribute node based on the seda atribute defintion
             if (child.Element === SedaElementConstants.attribute &&
               child.Cardinality === SedaCardinalityConstants.one &&
@@ -254,7 +240,7 @@ export class FileTreeComponent {
       this.sendNodeMetadata(parent);
       console.log("New fileNode data is : %o", this.nestedDataSource.data)
 
-      // 6. No more nodes to add  
+      // 6. No more nodes to add
     } else {
       console.log('No More Nodes can be inserted : No node was selected or node name is invalid');
     }
@@ -323,7 +309,7 @@ export class FileTreeComponent {
 
 
   // Refresh Tree by opening an given node (option)
-  // If the a node name is not prodived, the function will open the root tab element 
+  // If the a node name is not prodived, the function will open the root tab element
   renderChanges(node: FileNode, nodeIdToExpand?: number) {
     let data: FileNode;
     if (nodeIdToExpand) {
@@ -388,7 +374,7 @@ export class FileTreeComponent {
         let nodeLevel = (FileTreeComponent.archiveUnits.children.indexOf(node) + 1);
         let parent = this.fileService.getFileNodeById(FileTreeComponent.archiveUnits,node.parentId)
         let parentLevel = parent.level - 2
-  
+
         let archiveUnilNumber = nodeLevel > 0 ? nodeLevel : parentLevel
         let archiveUnitDecimal = parentLevel === 0 ? "" :  "." +parentLevel;
         return 'UA ' + archiveUnilNumber + archiveUnitDecimal ;
@@ -494,16 +480,16 @@ export class FileTreeComponent {
   }
 
   // Checks if a node belongs to the clicked tab collection.
-  // For a given node, searches the required node in the seda.json file and 
+  // For a given node, searches the required node in the seda.json file and
   // returns true if the node's value of "Collection" is equal to the clicked tab
   isPartOfCollection(node: FileNode): boolean {
-    return this.collectionName === node.sedaData.Collection.valueOf();   
+    return this.collectionName === node.sedaData.Collection.valueOf();
   }
 
   shouldBeOnTab(node: FileNode): boolean {
     let rootNodeName = this.fileService.rootTabMetadataName.getValue();
     let filteredNode = Object.assign({} as FileNode, this.nestedDataSource.data[0]);
-    
+
     let includedDataObjectPackageChildren = ['DataObjectGroup', 'BinaryDataObject', 'PhysicalDataObject']
     if (rootNodeName === 'DataObjectPackage' && !includedDataObjectPackageChildren.includes(node.name)) {
       filteredNode.children = filteredNode.children.filter(child => child.name !== 'DescriptiveMetadata' &&
diff --git a/ui/ui-frontend/projects/pastis/src/app/shared/pastis-dialog/pastis-dialog-confirm/pastis-dialog-confirm.component.ts b/ui/ui-frontend/projects/pastis/src/app/shared/pastis-dialog/pastis-dialog-confirm/pastis-dialog-confirm.component.ts
index c054d0cc6..e05bf96c0 100644
--- a/ui/ui-frontend/projects/pastis/src/app/shared/pastis-dialog/pastis-dialog-confirm/pastis-dialog-confirm.component.ts
+++ b/ui/ui-frontend/projects/pastis/src/app/shared/pastis-dialog/pastis-dialog-confirm/pastis-dialog-confirm.component.ts
@@ -1,25 +1,25 @@
 /*
-Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020) 
+Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020)
 
 [dad@cines.fr]
 
-This software is a computer program whose purpose is to provide 
-a web application to create, edit, import and export archive 
+This software is a computer program whose purpose is to provide
+a web application to create, edit, import and export archive
 profiles based on the french SEDA standard
 (https://redirect.francearchives.fr/seda/).
 
 
 This software is governed by the CeCILL-C  license under French law and
-abiding by the rules of distribution of free software.  You can  use, 
+abiding by the rules of distribution of free software.  You can  use,
 modify and/ or redistribute the software under the terms of the CeCILL-C
 license as circulated by CEA, CNRS and INRIA at the following URL
-"http://www.cecill.info". 
+"http://www.cecill.info".
 
 As a counterpart to the access to the source code and  rights to copy,
 modify and redistribute granted by the license, users are provided only
 with a limited warranty  and the software's author,  the holder of the
 economic rights,  and the successive licensors  have only  limited
-liability. 
+liability.
 
 In this respect, the user's attention is drawn to the risks associated
 with loading,  using,  modifying and/or developing or reproducing the
@@ -28,19 +28,19 @@ that may mean  that it is complicated to manipulate,  and  that  also
 therefore means  that it is reserved for developers  and  experienced
 professionals having in-depth computer knowledge. Users are therefore
 encouraged to load and test the software's suitability as regards their
-requirements in conditions enabling the security of their systems and/or 
-data to be ensured and,  more generally, to use and operate it in the 
-same conditions as regards security. 
+requirements in conditions enabling the security of their systems and/or
+data to be ensured and,  more generally, to use and operate it in the
+same conditions as regards security.
 
 The fact that you are presently reading this means that you have had
 knowledge of the CeCILL-C license and that you accept its terms.
 */
-import { Component, OnInit, Inject,  } from '@angular/core';
-import { PastisDialogData } from '../classes/pastis-dialog-data';
-import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
-import { SedaService } from '../../../core/services/seda.service';
-import { ComponentPortal } from '@angular/cdk/portal';
-import { PopupService } from 'projects/pastis/src/app/core/services/popup.service';
+import {Component, Inject, OnInit,} from '@angular/core';
+import {PastisDialogData} from '../classes/pastis-dialog-data';
+import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
+import {SedaService} from '../../../core/services/seda.service';
+import {ComponentPortal} from '@angular/cdk/portal';
+import {PopupService} from 'projects/pastis/src/app/core/services/popup.service';
 
 @Component({
   selector: 'pastis-pastis-dialog-confirm',
@@ -68,8 +68,8 @@ export class PastisDialogConfirmComponent implements OnInit {
       this.portal = new ComponentPortal(this.dialogReceivedData.component);
       this.popUpService.setPopUpDataOnOpen(this.dialogReceivedData);
     }
-      if (!this.dialogReceivedData.okLabel) this.dialogReceivedData.okLabel = 'Oui' 
-      if (!this.dialogReceivedData.cancelLabel) this.dialogReceivedData.cancelLabel = 'Non'  
+      if (!this.dialogReceivedData.okLabel) this.dialogReceivedData.okLabel = 'Oui'
+      if (!this.dialogReceivedData.cancelLabel) this.dialogReceivedData.cancelLabel = 'Non'
 
       this.popUpService.popUpDataBeforeClose.subscribe(data=>{
         this.dataBeforeClose = data;
@@ -99,7 +99,7 @@ export class PastisDialogConfirmComponent implements OnInit {
 
   ngOnDestroy() {
 
-  }  
+  }
 
 
 }
-- 
GitLab