diff --git a/src/frontend/app/app.module.ts b/src/frontend/app/app.module.ts index d27b20a55d16d40b50bcd264dd194194bcee0fdc..816313c48b49c25a946438c78d5af414ed9efecb 100755 --- a/src/frontend/app/app.module.ts +++ b/src/frontend/app/app.module.ts @@ -27,6 +27,7 @@ import { FolderTreeComponent } from './folder/folder-tree.compon import { FolderDocumentListComponent } from './folder/document-list/folder-document-list.component'; import { PanelFolderComponent } from './folder/panel/panel-folder.component'; import { FolderMenuComponent } from './folder/folder-menu/folder-menu.component'; +import { FolderUpdateComponent } from './folder/folder-update/folder-update.component'; /*ACTIONS PAGES */ import { ConfirmActionComponent } from './actions/confirm-action/confirm-action.component'; @@ -119,7 +120,8 @@ import { PrintSeparatorComponent } from './separator/prin FolderTreeComponent, PanelFolderComponent, FolderDocumentListComponent, - FolderMenuComponent + FolderMenuComponent, + FolderUpdateComponent ], entryComponents: [ CustomSnackbarComponent, @@ -142,7 +144,8 @@ import { PrintSeparatorComponent } from './separator/prin ProcessActionComponent, RedirectActionComponent, SendShippingActionComponent, - ViewDocActionComponent + ViewDocActionComponent, + FolderUpdateComponent ], providers: [ HeaderService, FiltersListService ], bootstrap: [ AppComponent ] diff --git a/src/frontend/app/folder/document-list/folder-document-list.component.html b/src/frontend/app/folder/document-list/folder-document-list.component.html index ae6820341a249613d40543f653a0676062b4f88c..aec26af4ce1027934ced89e21b72900914745bfc 100644 --- a/src/frontend/app/folder/document-list/folder-document-list.component.html +++ b/src/frontend/app/folder/document-list/folder-document-list.component.html @@ -55,7 +55,7 @@ </div> </div> <div style="height:90%;overflow:auto;position:absolute;width:100%;"> - <table #tableBasketListSort="matSort" cdkDropList id="folder-list" [cdkDropListConnectedTo]="listTodrag()" [cdkDropListData]="data" mat-table [dataSource]="data" matSort + <table #tableBasketListSort="matSort" cdkDropList id="folder-list" [cdkDropListConnectedTo]="listTodrag()" [cdkDropListData]="data" [cdkDropListDisabled]="dragInit" mat-table [dataSource]="data" matSort matSortActive="res_id" matSortDisableClear matSortDirection="asc" style="width:100%;"> <ng-container matColumnDef="res_id"> diff --git a/src/frontend/app/folder/document-list/folder-document-list.component.ts b/src/frontend/app/folder/document-list/folder-document-list.component.ts index a696fd6d9695fc6135c600b3c485a371287a0c41..c3b3134eacb0970040b3fa1058c3128bea92c2d5 100644 --- a/src/frontend/app/folder/document-list/folder-document-list.component.ts +++ b/src/frontend/app/folder/document-list/folder-document-list.component.ts @@ -46,6 +46,8 @@ export class FolderDocumentListComponent implements OnInit { filtersChange = new EventEmitter(); + dragInit: boolean = true; + dialogRef: MatDialogRef<any>; @ViewChild('snav', { static: true }) sidenavLeft: MatSidenav; @@ -119,6 +121,7 @@ export class FolderDocumentListComponent implements OnInit { this.isLoadingResults = false; this.route.params.subscribe(params => { + this.dragInit = true; this.destroy$.next(true); this.http.get('../../rest/folders/' + params['folderId']) @@ -137,6 +140,9 @@ export class FolderDocumentListComponent implements OnInit { window['MainHeaderComponent'].setSnav(this.sidenavLeft); window['MainHeaderComponent'].setSnavRight(null); + setTimeout(() => { + this.dragInit = false; + }, 1000); this.initResultList(); }, diff --git a/src/frontend/app/folder/folder-tree.component.html b/src/frontend/app/folder/folder-tree.component.html index 63fe816acb889ee9fa0ff0ea4af5a7022b02aa6f..127a26955dc35229c7f1bc72a7627a8ec76c92eb 100644 --- a/src/frontend/app/folder/folder-tree.component.html +++ b/src/frontend/app/folder/folder-tree.component.html @@ -23,6 +23,7 @@ <mat-menu #menu="matMenu"> <button mat-menu-item [disabled]="createItemNode" (click)="addNewItem(node)">Nouveau sous-dossier</button> <button mat-menu-item (click)="deleteNode(node)">Supprimer</button> + <button mat-menu-item (click)="openFolderAdmin(node)">Modifier</button> </mat-menu> </a> </mat-tree-node> @@ -61,6 +62,7 @@ <mat-menu #menu="matMenu"> <button mat-menu-item [disabled]="createItemNode" (click)="addNewItem(node)">Nouveau sous-dossier</button> <button mat-menu-item (click)="deleteNode(node)">Supprimer</button> + <button mat-menu-item (click)="openFolderAdmin(node)">Modifier</button> </mat-menu> </a> </mat-tree-node> diff --git a/src/frontend/app/folder/folder-tree.component.ts b/src/frontend/app/folder/folder-tree.component.ts index a6fe1f1493ef5d859edee74c4d76c6089de1eeea..84fe1459d91f87c94ef4dd05ab67bc05f2f9d6cb 100644 --- a/src/frontend/app/folder/folder-tree.component.ts +++ b/src/frontend/app/folder/folder-tree.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, Input, Renderer2 } from '@angular/core'; +import { Component, OnInit, ViewChild, Input, Renderer2, Output, EventEmitter } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../translate.component'; import { map, tap, catchError, filter, exhaustMap, finalize } from 'rxjs/operators'; @@ -11,6 +11,7 @@ import { BehaviorSubject, of } from 'rxjs'; import { NotificationService } from '../notification.service'; import { ConfirmComponent } from '../../plugins/modal/confirm.component'; import { Router } from '@angular/router'; +import { FolderUpdateComponent } from './folder-update/folder-update.component'; declare function $j(selector: any): any; /** @@ -104,6 +105,8 @@ export class FolderTreeComponent implements OnInit { dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); @ViewChild('tree', { static: true }) tree: any; + + @Output('refreshDocList') refreshDocList = new EventEmitter<string>(); constructor( public http: HttpClient, @@ -365,7 +368,10 @@ export class FolderTreeComponent implements OnInit { tap((data: any) => { node.countResources = data.countResources; }), - tap(() => this.notify.success('Courrier classé')), + tap(() => { + this.notify.success('Courrier classé'); + this.refreshDocList.emit(); + }), finalize(() => node.drag = false), catchError((err) => { this.notify.handleErrors(err); @@ -374,8 +380,6 @@ export class FolderTreeComponent implements OnInit { ).subscribe(); } - - dragEnter(node: any) { node.drag = true; } @@ -386,7 +390,6 @@ export class FolderTreeComponent implements OnInit { } else { return []; } - } toggleInput() { @@ -397,4 +400,13 @@ export class FolderTreeComponent implements OnInit { }, 0); } } + + openFolderAdmin(node: any) { + console.log(node); + this.dialogRef = this.dialog.open(FolderUpdateComponent, { autoFocus: false, data: { folderId: node.id } }); + + this.dialogRef.afterClosed().pipe( + + ).subscribe(); + } } diff --git a/src/frontend/app/folder/folder-update/folder-update.component.html b/src/frontend/app/folder/folder-update/folder-update.component.html new file mode 100644 index 0000000000000000000000000000000000000000..3b1d18d4ba31efd987519484501f9549d983a89a --- /dev/null +++ b/src/frontend/app/folder/folder-update/folder-update.component.html @@ -0,0 +1,46 @@ +<h1 mat-dialog-title>Dossier : {{folder.label}}</h1> +<form (ngSubmit)="onSubmit()"> + <mat-dialog-content> + <div class="col-md-12"> + <mat-form-field class="example-full-width"> + <input matInput placeholder="{{lang.label}}" name="label" [(ngModel)]="folder.label"> + </mat-form-field> + </div> + <div [class.col-md-12]="folder.sharing.entities.length === 0" + [class.col-md-6]="folder.sharing.entities.length > 0"> + <div class="formType jstreeEntities"> + <div class="formType-title"> + Périmètre de restriction + </div> + <mat-form-field appearance="outline"> + <input matInput id="jstree_search" type="text" placeholder="{{lang.searchEntities}}"> + </mat-form-field> + <div id="jstree" class="entitiesList"></div> + </div> + </div> + <div class="col-md-6" *ngIf="folder.sharing.entities.length > 0"> + <div class="formType jstreeEntities"> + <div class="formType-title"> + Paramètres + </div> + <ng-container *ngFor="let entity of entities | sortBy : 'entity_label'"> + <mat-expansion-panel class="selectedEntities" + *ngIf="checkSelectedFolder(entity)" opened> + <mat-expansion-panel-header> + <mat-panel-title> + {{entity.entity_label}} + </mat-panel-title> + </mat-expansion-panel-header> + <mat-slide-toggle color="primary">Droit de modification / suppression du dossier + </mat-slide-toggle> + </mat-expansion-panel> + </ng-container> + </div> + </div> + </mat-dialog-content> + <mat-dialog-actions> + <button mat-raised-button color="primary" type="submit" + (click)="dialogRef.close(this.data)">{{lang.validate}}</button> + <button mat-raised-button type="button" color="default" (click)="dialogRef.close()">{{lang.cancel}}</button> + </mat-dialog-actions> +</form> \ No newline at end of file diff --git a/src/frontend/app/folder/folder-update/folder-update.component.scss b/src/frontend/app/folder/folder-update/folder-update.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..98c9836f1334eb9c4c3a21d9e94bce92c16383f5 --- /dev/null +++ b/src/frontend/app/folder/folder-update/folder-update.component.scss @@ -0,0 +1,44 @@ +@import '../../../css/vars.scss'; + +.mat-form-field-appearance-outline { + font-size: 11px; +} + +.formType { + display: flex; + flex-direction: column; + margin: 10px; + border-radius: 4px; + border: solid 1px #ccc; + position: relative; + padding: 10px; + + &-title { + white-space: pre; + overflow: hidden; + max-width: 85%; + text-overflow: ellipsis; + z-index: 1; + font-size: 20px; + font-weight: bold; + background: white; + position: absolute; + top: -18px; + left: 10px; + padding: 0px; + margin: 0px; + color: #135f7f; + } +} +.modal-body{ + min-height: 600px; +} + +.entitiesList { + overflow: auto; +} + +.selectedEntities { + margin-top: 5px; + margin-bottom: 5px; +} \ No newline at end of file diff --git a/src/frontend/app/folder/folder-update/folder-update.component.ts b/src/frontend/app/folder/folder-update/folder-update.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..81a17fdbb62d5bbc2218806a6fa9bbe6f518bc61 --- /dev/null +++ b/src/frontend/app/folder/folder-update/folder-update.component.ts @@ -0,0 +1,139 @@ +import { Component, OnInit, Input, Output, EventEmitter, Inject } from '@angular/core'; +import { LANG } from '../../translate.component'; +import { HttpClient } from '@angular/common/http'; +import { map, tap, catchError, exhaustMap } from 'rxjs/operators'; +import { of } from 'rxjs'; +import { NotificationService } from '../../notification.service'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; + +declare function $j(selector: any): any; + +@Component({ + templateUrl: "folder-update.component.html", + styleUrls: ['folder-update.component.scss'], + providers: [NotificationService], +}) +export class FolderUpdateComponent implements OnInit { + + lang: any = LANG; + + folder: any = { + id: 0, + label: '', + public: true, + user_id: 0, + parent_id: 0, + level: 0, + sharing: { + entities: [] + } + } + + entities: any[] = []; + + constructor( + public http: HttpClient, + private notify: NotificationService, + public dialogRef: MatDialogRef<FolderUpdateComponent>, + @Inject(MAT_DIALOG_DATA) public data: any + ) { } + + ngOnInit(): void { + this.getFolder(); + } + + getFolder() { + this.http.get('../../rest/folders/' + this.data.folderId).pipe( + tap((data: any) => this.folder = data.folder), + exhaustMap(() => this.http.get('../../rest/entities')), + map((data: any) => { + this.entities = data.entities; + data.entities.forEach((element: any) => { + if (this.folder.sharing.entities.map((data: any) => data.entity_id).indexOf(element.serialId) > -1) { + element.state.selected = true; + } + element.state.allowed = true; + element.state.disabled = false; + }); + return data; + }), + tap((data: any) => { + this.initEntitiesTree(data.entities); + }), + catchError((err: any) => { + this.notify.handleErrors(err); + return of(false); + }) + ).subscribe(); + } + + initEntitiesTree(entities: any) { + $j('#jstree').jstree({ + "checkbox": { + "three_state": false //no cascade selection + }, + 'core': { + 'themes': { + 'name': 'proton', + 'responsive': true + }, + 'data': entities + }, + "plugins": ["checkbox", "search"] + }); + $j('#jstree') + // listen for event + .on('select_node.jstree', (e: any, data: any) => { + this.selectEntity(data.node.original); + + }).on('deselect_node.jstree', (e: any, data: any) => { + this.deselectEntity(data.node.original); + }) + // create the instance + .jstree(); + var to: any = false; + $j('#jstree_search').keyup(function () { + if (to) { clearTimeout(to); } + to = setTimeout(function () { + var v = $j('#jstree_search').val(); + $j('#jstree').jstree(true).search(v); + }, 250); + }); + } + + selectEntity(newEntity: any) { + this.folder.sharing.entities.push( + { + entity_id : newEntity.serialId, + edition : false + } + ); + } + + deselectEntity(entity: any) { + let index = this.folder.sharing.entities.map((data: any) => data.entity_id).indexOf(entity.id); + this.folder.sharing.entities.splice(index, 1); + } + + onSubmit(): void { + this.http.put('../../rest/folders/' + this.folder.id, this.folder).pipe( + exhaustMap(() => this.http.put('../../rest/folders/' + this.folder.id + '/sharing', { public: this.folder.sharing.entities.length > 0, sharing: this.folder.sharing })), + tap((data: any) => { + this.notify.success('Dossier modifié'); + this.dialogRef.close(); + }), + catchError((err: any) => { + this.notify.handleErrors(err); + return of(false); + }) + ).subscribe(); + } + + checkSelectedFolder(entity: any) { + if (this.folder.sharing.entities.map((data: any) => data.entity_id).indexOf(entity.serialId) > -1) { + return true; + } else { + return false; + } + } +} diff --git a/src/frontend/app/folder/panel/panel-folder.component.html b/src/frontend/app/folder/panel/panel-folder.component.html index 1236cb99dd2e5ee8238c70041de38cec0c270dc0..2fac3f028798f1fb773e49e4dd5aff57eb561a81 100644 --- a/src/frontend/app/folder/panel/panel-folder.component.html +++ b/src/frontend/app/folder/panel/panel-folder.component.html @@ -4,5 +4,5 @@ {{lang.folders}} </mat-panel-title> </mat-expansion-panel-header> - <folder-tree #folderTree [selectedId]="id"></folder-tree> + <folder-tree #folderTree [selectedId]="id" (refreshDocList)="refreshDocList()"></folder-tree> </mat-expansion-panel> diff --git a/src/frontend/app/folder/panel/panel-folder.component.ts b/src/frontend/app/folder/panel/panel-folder.component.ts index b613cfaa15bd8eef3e616afb689de32ef59d2fcf..43b49a802f54debfad5ad2f6a766d40a37957770 100644 --- a/src/frontend/app/folder/panel/panel-folder.component.ts +++ b/src/frontend/app/folder/panel/panel-folder.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input, ViewChild } from '@angular/core'; +import { Component, OnInit, Input, ViewChild, Output, EventEmitter } from '@angular/core'; import { LANG } from '../../translate.component'; import { FolderTreeComponent } from '../folder-tree.component'; @@ -16,6 +16,8 @@ export class PanelFolderComponent implements OnInit { @Input('selectedId') id: number; @ViewChild('folderTree', { static: true }) folderTree: FolderTreeComponent; + @Output('refreshEvent') refreshEvent = new EventEmitter<string>(); + constructor() { } ngOnInit(): void { } @@ -31,4 +33,8 @@ export class PanelFolderComponent implements OnInit { initTree() { this.folderTree.openTree(this.id); } + + refreshDocList() { + this.refreshEvent.emit(); + } } diff --git a/src/frontend/app/list/basket-list.component.html b/src/frontend/app/list/basket-list.component.html index 68916c2cf6b0df5d9fb7fd7ad791520029201ef7..b41ae3490d941843c070f4cbd1e3327d3ecb3237 100644 --- a/src/frontend/app/list/basket-list.component.html +++ b/src/frontend/app/list/basket-list.component.html @@ -8,7 +8,7 @@ <basket-home *ngIf="homeData" #basketHome (refreshEvent)="refreshDao()" [homeData]="homeData" [snavL]="snav" [currentBasketInfo]="currentBasketInfo"></basket-home> <mat-divider></mat-divider> - <panel-folder #panelFolder></panel-folder> + <panel-folder #panelFolder (refreshEvent)="refreshDao()"></panel-folder> </mat-sidenav> <mat-sidenav-content> <mat-card id="viewThumbnail" style="display:none;position: fixed;z-index: 2;margin-left: 1px;"><img style="max-height: 100vh;" src="{{thumbnailUrl}}" /></mat-card> @@ -62,8 +62,8 @@ </div> </div> <div style="height:90%;overflow:auto;position:absolute;width:100%;"> - <table cdkDropList id="document-list" [cdkDropListConnectedTo]="panelFolder.getDragIds()" [cdkDropListData]="data" #tableBasketListSort="matSort" mat-table [dataSource]="data" matSort - matSortActive="res_id" matSortDisableClear matSortDirection="asc" style="width:100%;"> + <table cdkDropList id="document-list" [cdkDropListConnectedTo]="listTodrag()" [cdkDropListData]="data" #tableBasketListSort="matSort" mat-table [dataSource]="data" matSort + matSortActive="res_id" matSortDisableClear matSortDirection="asc" style="width:100%;" [cdkDropListDisabled]="dragInit"> <ng-container matColumnDef="res_id"> <td mat-cell *matCellDef="let row" diff --git a/src/frontend/app/list/basket-list.component.ts b/src/frontend/app/list/basket-list.component.ts index 3b43aeb5467d79c3659f5392ba5c2dcd6348dae0..9b627fe08947cd9e7dbd815ec89004e9981f6e8e 100755 --- a/src/frontend/app/list/basket-list.component.ts +++ b/src/frontend/app/list/basket-list.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, EventEmitter, ViewContainerRef } from '@angular/core'; +import { Component, OnInit, ViewChild, EventEmitter, ViewContainerRef, ApplicationRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../translate.component'; import { merge, Observable, of as observableOf, Subject } from 'rxjs'; @@ -48,6 +48,8 @@ export class BasketListComponent implements OnInit { filtersChange = new EventEmitter(); + dragInit: boolean = true; + @ViewChild('snav', { static: true }) sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) sidenavRight: MatSidenav; @@ -124,6 +126,7 @@ export class BasketListComponent implements OnInit { this.isLoadingResults = false; this.route.params.subscribe(params => { + this.dragInit = true; this.destroy$.next(true); this.basketUrl = '../../rest/resourcesList/users/' + params['userSerialId'] + '/groups/' + params['groupSerialId'] + '/baskets/' + params['basketId']; @@ -141,6 +144,10 @@ export class BasketListComponent implements OnInit { this.listProperties = this.filtersListService.initListsProperties(this.currentBasketInfo.ownerId, this.currentBasketInfo.groupId, this.currentBasketInfo.basketId); + + setTimeout(() => { + this.dragInit = false; + }, 1000); this.initResultList(); }, @@ -178,7 +185,6 @@ export class BasketListComponent implements OnInit { this.currentBasketInfo.basket_id = data.basket_id; this.defaultAction = data.defaultAction; this.headerService.setHeader(data.basketLabel); - return data.resources; }), catchError((err: any) => { @@ -422,7 +428,14 @@ export class BasketListComponent implements OnInit { setTimeout(() => { this.actionsList.launchEvent(action, row); }, 200); - + } + + listTodrag() { + if (this.panelFolder !== undefined) { + return this.panelFolder.getDragIds(); + } else { + return [0]; + } } } export interface BasketList { diff --git a/src/frontend/tsconfig.app.json b/src/frontend/tsconfig.app.json index 79143525f9a50464d13635dc92d61629586d0a3f..6d8e476354de8dbe6c94fbc1d460221276a4e140 100755 --- a/src/frontend/tsconfig.app.json +++ b/src/frontend/tsconfig.app.json @@ -8,5 +8,8 @@ }, "exclude": [ "**/*.spec.ts" - ] + ], + "angularCompilerOptions": { + "enableIvy": false + } }