diff --git a/src/frontend/app/app.module.ts b/src/frontend/app/app.module.ts index 51d5d1957553df98f90fb9235f0adbcf6c7f1486..15424e3b893a57001a33d2a9b55d715b9fc6753b 100755 --- a/src/frontend/app/app.module.ts +++ b/src/frontend/app/app.module.ts @@ -2,7 +2,7 @@ import { NgModule } from '@angular/core'; import { SharedModule } from './app-common.module'; -import { CustomSnackbarComponent } from './notification.service'; +import { CustomSnackbarComponent, NotificationService } from './notification.service'; import { ConfirmModalComponent } from './confirmModal.component'; import { HeaderService } from '../service/header.service'; import { FiltersListService } from '../service/filtersList.service'; @@ -23,6 +23,7 @@ import { ActivateUserComponent } from './activate-user.component' import { ActionsListComponent } from './actions/actions-list.component'; +import { FolderPinnedComponent } from './folder/folder-pinned/folder-pinned.component'; import { FolderTreeComponent } from './folder/folder-tree.component'; import { FolderDocumentListComponent } from './folder/document-list/folder-document-list.component'; import { PanelFolderComponent } from './folder/panel/panel-folder.component'; @@ -66,6 +67,7 @@ import { PrintSeparatorComponent } from './separator/prin import { IndexationComponent } from './indexation/indexation.component'; import { AddPrivateIndexingModelModalComponent } from './indexation/private-indexing-model/add-private-indexing-model-modal.component'; +import { FoldersService } from './folder/folders.service'; @NgModule({ @@ -119,6 +121,7 @@ import { AddPrivateIndexingModelModalComponent } from './ SendShippingActionComponent, ActionsListComponent, PrintSeparatorComponent, + FolderPinnedComponent, FolderTreeComponent, PanelFolderComponent, FolderDocumentListComponent, @@ -153,7 +156,7 @@ import { AddPrivateIndexingModelModalComponent } from './ FolderUpdateComponent, AddPrivateIndexingModelModalComponent ], - providers: [ HeaderService, FiltersListService ], + providers: [ HeaderService, FiltersListService, FoldersService, NotificationService ], bootstrap: [ AppComponent ] }) export class AppModule { } 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 f414ed4ed441586c90ca9e9fca098e8088747fe8..71b5cc2817722ed3d793444b41ca3923c88935b4 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 @@ -22,6 +22,7 @@ import { ConfirmComponent } from '../../../plugins/modal/confirm.component'; import { FolderActionListComponent } from '../folder-action-list/folder-action-list.component'; import { FiltersListService } from '../../../service/filtersList.service'; import { trigger, transition, style, animate } from '@angular/animations'; +import { FoldersService } from '../folders.service'; declare function $j(selector: any): any; @@ -115,11 +116,13 @@ export class FolderDocumentListComponent implements OnInit { private notify: NotificationService, public overlay: Overlay, public viewContainerRef: ViewContainerRef, - public appService: AppService) { + public appService: AppService, + private foldersService: FoldersService) { $j("link[href='merged_css.php']").remove(); } ngOnInit(): void { + this.appService.openBasketMenu(false); this.loading = false; @@ -144,7 +147,7 @@ export class FolderDocumentListComponent implements OnInit { 'ownerDisplayName': data.folder.ownerDisplayName, 'entitiesSharing': data.folder.sharing.entities.map((entity: any) => entity.label), }; - + this.foldersService.setFolder(this.folderInfo); this.headerService.setHeader(this.folderInfo.label, '', 'fa fa-folder-open'); }); this.basketUrl = '../../rest/folders/' + params['folderId'] + '/resources'; diff --git a/src/frontend/app/folder/folder-menu/folder-menu.component.ts b/src/frontend/app/folder/folder-menu/folder-menu.component.ts index d8e34382c5d531f10c9dcca37f39a66f3f6cfa75..2f6da6e6a7deb7145e5460448c2ab6bf61d8df73 100644 --- a/src/frontend/app/folder/folder-menu/folder-menu.component.ts +++ b/src/frontend/app/folder/folder-menu/folder-menu.component.ts @@ -7,6 +7,7 @@ import { NotificationService } from '../../notification.service'; import { ConfirmComponent } from '../../../plugins/modal/confirm.component'; import { MatDialogRef, MatDialog } from '@angular/material/dialog'; import { FormControl } from '@angular/forms'; +import { FoldersService } from '../folders.service'; @Component({ selector: 'folder-menu', @@ -33,7 +34,8 @@ export class FolderMenuComponent implements OnInit { public http: HttpClient, private notify: NotificationService, public dialog: MatDialog, - private renderer: Renderer2 + private renderer: Renderer2, + private foldersService: FoldersService ) { } ngOnInit(): void { @@ -68,7 +70,7 @@ export class FolderMenuComponent implements OnInit { } getFolders() { - this.http.get("../../rest/folders").pipe( + this.http.get("../../rest/pinnedFolders").pipe( map((data: any) => data.folders), tap((data: any) => { this.foldersList = data; @@ -80,7 +82,7 @@ export class FolderMenuComponent implements OnInit { this.http.post('../../rest/folders/' + folder.id + '/resources', { resources: this.resIds }).pipe( tap(() => { - this.refreshFolders.emit(); + this.foldersService.getPinnedFolders(); this.refreshList.emit(); this.notify.success(this.lang.mailClassified); }), diff --git a/src/frontend/app/folder/folder-pinned/folder-pinned.component.html b/src/frontend/app/folder/folder-pinned/folder-pinned.component.html new file mode 100644 index 0000000000000000000000000000000000000000..933a5671f2a1c36c6477383a1e9948f4eaa6f8c4 --- /dev/null +++ b/src/frontend/app/folder/folder-pinned/folder-pinned.component.html @@ -0,0 +1,28 @@ +<ng-container *ngIf="foldersService.getPinnedList().length > 0; else elseTemplate"> + <mat-list class="pinnedFolderList"> + <mat-list-item cdkDropList *ngFor="let folder of foldersService.getPinnedList();let i=index" + (click)="gotToFolder(folder)" [class.selectedFolder]="foldersService.getCurrentFolder().id == folder.id" + [id]="'folder-list-'+folder.id" cdkDropListConnectedTo="['document-list','folder-list']" + (cdkDropListDropped)="drop($event, folder)" (cdkDropListEntered)="dragEnter(folder)" + (cdkDropListExited)="folder.drag=false"> + <mat-icon mat-list-icon class="pinnedIcon" [title]="'Désépingler le dossier'" + (click)="$event.stopPropagation();foldersService.unpinFolder(folder)"> + <i class="fa fa-thumbtack"></i> + </mat-icon> + <span class="pinnedFolderItem"> + <span class="treeLabel" [title]="folder.label" [class.drag]="folder.drag" + [class.public]="folder.public"> + {{folder.label}} + </span> + </span> + <span class="countResources" [class.empty]="folder.countResources === 0"> + {{folder.countResources}} + </span> + </mat-list-item> + </mat-list> +</ng-container> +<ng-template #elseTemplate> + <div class="noPinnedFolder"> + Aucun dossier épinglé + </div> +</ng-template> \ No newline at end of file diff --git a/src/frontend/app/folder/folder-pinned/folder-pinned.component.scss b/src/frontend/app/folder/folder-pinned/folder-pinned.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..2cc1d9b729c89eb6f0978f7f2a10b3d4df192cfc --- /dev/null +++ b/src/frontend/app/folder/folder-pinned/folder-pinned.component.scss @@ -0,0 +1,81 @@ +@import '../../../css/vars.scss'; + +.pinnedFolderList { + .mat-list-item { + cursor: pointer; + height: 45px; + + &:hover { + background: rgba(0, 0, 0, 0.04); + } + } + + ::ng-deep.mat-list-text { + padding-left: 0px !important; + } + + .pinnedFolderItem { + color: rgb(102, 102, 102); + font-weight: bold; + font-size: 12px; + width: 90%; + overflow: hidden; + text-overflow: ellipsis; + } + + .folderAction { + color: rgb(102, 102, 102); + } + +} + +.pinnedIcon { + cursor: pointer; + color: $primary; + text-align: center; + + i { + + font-size: 13px; + transition: all 0.3s; + } + + &:hover { + color: $warn; + + i { + transition: all 0.3s; + transform: rotate(45deg) translate(0px, -50%); + } + } +} + +.countResources { + color: $primary; + font-weight: bold; + font-size: 14px; +} + +button:disabled { + opacity: 1; +} + +.selectedFolder { + border-left: solid 5px $primary; + background: rgba($primary, 0.14); +} + +.public { + color: $secondary; +} + +.drag { + color: $primary !important; +} + +.noPinnedFolder { + text-align: center; + font-size: 13px; + opacity: 0.5; + font-style: italic; +} \ No newline at end of file diff --git a/src/frontend/app/folder/folder-pinned/folder-pinned.component.ts b/src/frontend/app/folder/folder-pinned/folder-pinned.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..f4291921f3eec75b5b0fb0884bc0e1cab186d04e --- /dev/null +++ b/src/frontend/app/folder/folder-pinned/folder-pinned.component.ts @@ -0,0 +1,66 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { LANG } from '../../translate.component'; + +import { NotificationService } from '../../notification.service'; +import { tap, filter, catchError, exhaustMap, map } from 'rxjs/operators'; +import { ConfirmComponent } from '../../../plugins/modal/confirm.component'; +import { MatDialog } from '@angular/material'; +import { of, Subscription } from 'rxjs'; +import { Router } from '@angular/router'; +import { FolderUpdateComponent } from '../folder-update/folder-update.component'; +import { FoldersService } from '../folders.service'; + +@Component({ + selector: 'folder-pinned', + templateUrl: "folder-pinned.component.html", + styleUrls: ['folder-pinned.component.scss'], + providers: [NotificationService], +}) +export class FolderPinnedComponent implements OnInit { + + lang: any = LANG; + + subscription: Subscription; + + constructor( + public http: HttpClient, + private notify: NotificationService, + private dialog: MatDialog, + private router: Router, + private foldersService: FoldersService + ) { + // Event after process action + this.subscription = this.foldersService.catchEvent().subscribe((result: any) => { + //console.log(result); + }); + } + + ngOnInit(): void { + this.foldersService.initFolder(); + this.foldersService.getPinnedFolders(); + } + + gotToFolder(folder: any) { + this.foldersService.goToFolder(folder); + } + + dragEnter(folder: any) { + folder.drag = true; + } + + drop(ev: any, node: any) { + this.foldersService.classifyDocument(ev, node); + /*if (ev.previousContainer.id === 'folder-list') { + this.moveFolder(ev, node); + } else { + this.classifyDocument(ev, node); + }*/ + } + + ngOnDestroy() { + // unsubscribe to ensure no memory leaks + this.subscription.unsubscribe(); + } + +} diff --git a/src/frontend/app/folder/folder-tree.component.html b/src/frontend/app/folder/folder-tree.component.html index 4f85dfb7031427ad3bda67604e8f9d959736e9e1..641e642779511800785877d7a4b73c4d3c3e9c60 100644 --- a/src/frontend/app/folder/folder-tree.component.html +++ b/src/frontend/app/folder/folder-tree.component.html @@ -11,7 +11,7 @@ </div> </div> <div *ngIf="dataSource.data.length === 0" class="noFolder"> - {{lang.noAvailableFolder}}<br/><a (click)="toggleInput()">{{lang.addFolder}}</a> + {{lang.noAvailableFolder}}<br /><a (click)="toggleInput()">{{lang.addFolder}}</a> </div> <mat-list *ngIf="createRootNode"> <mat-list-item role="listitem" class="rootFolder"> @@ -36,8 +36,9 @@ *matTreeNodeDef="let node" matTreeNodePadding matTreeNodePaddingIndent="20px"> <!-- use a disabled button to provide padding for tree leaf --> <button class="expandButton" mat-icon-button disabled></button> - <a mat-list-item disableRipple class="folderTreeItem" [class.selectedFolder]="node.selected" - (mouseenter)="showAction(node)" (mouseleave)="hideAction(node)" (click)="selectFolder(node)"> + <a mat-list-item disableRipple class="folderTreeItem" + [class.selectedFolder]="foldersService.getCurrentFolder().id == node.id" (mouseenter)="showAction(node)" + (mouseleave)="hideAction(node)" (click)="selectFolder(node)"> <span style="width: 90%;overflow: hidden;text-overflow: ellipsis;"> <span class="treeLabel" [title]="node.label" [class.drag]="node.drag"> <i class="fa fa-users private" *ngIf="node.public" title="{{lang.sharedFolder}}"></i> @@ -52,10 +53,17 @@ {{node.countResources}} </span> </button> - <mat-menu #menu="matMenu"> + <mat-menu #menu="matMenu" [class]="'folderListMenu'"> + <button mat-menu-item (click)="togglePinFolder(node)"> + <mat-icon [class.pinnedActionIcon]="!node.pinned" [class.revertPinnedActionIcon]="node.pinned"> + <i class="fas fa-thumbtack"></i> + </mat-icon> + <span>{{node.pinned ? 'Désépingler' : 'Épingler'}}</span> + </button> <button mat-menu-item [disabled]="createItemNode || !node.canAdd" (click)="addNewItem(node)">{{lang.addSubFolder}}</button> - <button mat-menu-item (click)="deleteNode(node)" [disabled]="!node.canDelete">{{lang.delete}}</button> + <button mat-menu-item (click)="deleteNode(node)" + [disabled]="!node.canDelete">{{lang.delete}}</button> <button mat-menu-item (click)="openFolderAdmin(node)" [disabled]="!node.edition">{{lang.update}}</button> </mat-menu> @@ -82,8 +90,9 @@ class="mat-icon-rtl-mirror fa {{treeControl.isExpanded(node) ? 'fa-chevron-down' : 'fa-chevron-right'}}"> </mat-icon> </button> - <a mat-list-item disableRipple class="folderTreeItem" [class.selectedFolder]="node.selected" - (mouseleave)="hideAction(node)" (mouseenter)="showAction(node)" (click)="selectFolder(node)"> + <a mat-list-item disableRipple class="folderTreeItem" + [class.selectedFolder]="foldersService.getCurrentFolder().id == node.id" (mouseleave)="hideAction(node)" + (mouseenter)="showAction(node)" (click)="selectFolder(node)"> <span style="width: 90%;overflow: hidden;text-overflow: ellipsis;"> <span class="treeLabel" [title]="node.label" [class.drag]="node.drag"> <i class="fa fa-users private" *ngIf="node.public" title="{{lang.sharedFolder}}"></i> @@ -97,10 +106,18 @@ {{node.countResources}} </span> </button> - <mat-menu #menu="matMenu"> + <mat-menu #menu="matMenu" [class]="'folderListMenu'"> + <button mat-menu-item (click)="togglePinFolder(node)"> + <mat-icon [class.pinnedActionIcon]="!node.pinned" [class.revertPinnedActionIcon]="node.pinned"> + <i class="fas fa-thumbtack"></i> + </mat-icon> + <span>{{node.pinned ? 'Désépingler' : 'Épingler'}}</span> + </button> + <button mat-menu-item [disabled]="createItemNode || !node.canAdd" (click)="addNewItem(node)">{{lang.addSubFolder}}</button> - <button mat-menu-item (click)="deleteNode(node)" [disabled]="!node.canDelete">{{lang.delete}}</button> + <button mat-menu-item (click)="deleteNode(node)" + [disabled]="!node.canDelete">{{lang.delete}}</button> <button mat-menu-item (click)="openFolderAdmin(node)" [disabled]="!node.edition">{{lang.update}}</button> </mat-menu> diff --git a/src/frontend/app/folder/folder-tree.component.scss b/src/frontend/app/folder/folder-tree.component.scss index f9659c1e28da08c7ec0740f316fe6c1f908f21ae..30706c9d5bcddc29b5f30283171b06e4e7822b0f 100644 --- a/src/frontend/app/folder/folder-tree.component.scss +++ b/src/frontend/app/folder/folder-tree.component.scss @@ -136,4 +136,55 @@ button:disabled { a { cursor: pointer; } +} + +::ng-deep.folderListMenu { + .mat-menu-content { + padding-top: 0; + padding-bottom: 0; + + .mat-menu-item { + .pinnedActionIcon { + color: $warn; + height: auto; + + i { + font-size: 13px; + transition: all 0.3s; + transform: rotate(15deg) translate(0px, -50%); + } + + } + .revertPinnedActionIcon { + color: $primary; + height: auto; + + i { + font-size: 13px; + transition: all 0.3s; + transform: rotate(0deg) translate(0px, 0px); + } + + } + } + + .mat-menu-item:hover { + .pinnedActionIcon { + color: $primary; + i { + transition: all 0.3s; + transform: rotate(0deg) translate(0px, 0px); + } + } + + .revertPinnedActionIcon { + color: $warn; + i { + transition: all 0.3s; + transform: rotate(15deg) translate(0px, -50%); + } + } + } + + } } \ No newline at end of file diff --git a/src/frontend/app/folder/folder-tree.component.ts b/src/frontend/app/folder/folder-tree.component.ts index 7ac8c68958edddb1cac1e8e34de38555f7830977..dbecc3b8971b5518307d34eb767d0e78d4ba93de 100644 --- a/src/frontend/app/folder/folder-tree.component.ts +++ b/src/frontend/app/folder/folder-tree.component.ts @@ -7,11 +7,12 @@ import { trigger, transition, style, animate } from '@angular/animations'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatInput } from '@angular/material/input'; import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree'; -import { BehaviorSubject, of } from 'rxjs'; +import { BehaviorSubject, of, Subscription } 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'; +import { FoldersService } from './folders.service'; declare function $j(selector: any): any; /** @@ -23,6 +24,7 @@ export class ItemNode { label: string; parent_id: number; public: boolean; + pinned: boolean; countResources: number; } @@ -34,6 +36,7 @@ export class ItemFlatNode { countResources: number; level: number; public: boolean; + pinned: boolean; expandable: boolean; } @Component({ @@ -87,6 +90,7 @@ export class FolderTreeComponent implements OnInit { flatNode.label = node.label; flatNode.countResources = node.countResources; flatNode.public = node.public; + flatNode.pinned = node.pinned; flatNode.parent_id = node.parent_id; flatNode.id = node.id; flatNode.level = level; @@ -104,6 +108,8 @@ export class FolderTreeComponent implements OnInit { dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); + subscription: Subscription; + @ViewChild('tree', { static: true }) tree: any; @Output('refreshDocList') refreshDocList = new EventEmitter<string>(); @@ -114,8 +120,14 @@ export class FolderTreeComponent implements OnInit { private notify: NotificationService, private dialog: MatDialog, private router: Router, - private renderer: Renderer2 - ) { } + private renderer: Renderer2, + public foldersService: FoldersService + ) { + // Event after process action + this.subscription = this.foldersService.catchEvent().subscribe((result: any) => { + this.openTree(this.foldersService.getCurrentFolder().id); + }); + } ngOnInit(): void { this.getFolders(); @@ -126,10 +138,8 @@ export class FolderTreeComponent implements OnInit { map((data: any) => this.flatToNestedObject(data.folders)), filter((data: any) => data.length > 0), tap((data) => this.initTree(data)), - //filter(() => this.seletedId !== undefined), tap(() => { - this.openTree(this.seletedId); - this.selectTree(this.seletedId); + this.openTree(this.foldersService.getCurrentFolder().id); }) ).subscribe(); } @@ -152,13 +162,6 @@ export class FolderTreeComponent implements OnInit { } } - selectTree(id: any) { - let indexSelectedFolder = this.treeControl.dataNodes.map((folder: any) => folder.id).indexOf(parseInt(id)); - if (indexSelectedFolder != -1) { - this.treeControl.dataNodes[indexSelectedFolder].selected = true; - } - } - hasChild = (_: number, node: any) => node.expandable; hasNoContent = (_: number, _nodeData: any) => _nodeData.label === ''; @@ -409,6 +412,7 @@ export class FolderTreeComponent implements OnInit { tap((data) => { if (data !== undefined) { this.getFolders(); + this.foldersService.getPinnedFolders(); } }) ).subscribe(); @@ -456,4 +460,17 @@ export class FolderTreeComponent implements OnInit { this.getFolders(); this.router.navigate(["/folders/" + folder.id]); } + + togglePinFolder(folder: any) { + if (folder.pinned) { + this.foldersService.unpinFolder(folder); + } else { + this.foldersService.pinFolder(folder); + } + } + + ngOnDestroy() { + // unsubscribe to ensure no memory leaks + this.subscription.unsubscribe(); + } } diff --git a/src/frontend/app/folder/folders.service.ts b/src/frontend/app/folder/folders.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..9f9988fdc931f48c78f7c97976cd10395522ae4d --- /dev/null +++ b/src/frontend/app/folder/folders.service.ts @@ -0,0 +1,136 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { LANG } from '../../app/translate.component'; +import { Subject, Observable, of } from 'rxjs'; +import { NotificationService } from '../notification.service'; +import { MatDialog } from '@angular/material'; +import { Router } from '@angular/router'; +import { map, tap, filter, exhaustMap, catchError, finalize } from 'rxjs/operators'; +import { ConfirmComponent } from '../../plugins/modal/confirm.component'; + + +@Injectable() +export class FoldersService { + + lang: any = LANG; + + loading: boolean = false; + + pinnedFolders: any = []; + + currentFolder: any = { id: 0 }; + + private eventAction = new Subject<any>(); + + constructor( + public http: HttpClient, + public dialog: MatDialog, + private notify: NotificationService, + private router: Router + ) { + } + + ngOnInit(): void { } + + initFolder() { + this.currentFolder = { id: 0 }; + } + + catchEvent(): Observable<any> { + return this.eventAction.asObservable(); + } + + goToFolder(folder: any) { + this.setFolder(folder); + this.router.navigate(['/folders/' + folder.id]); + } + + setFolder(folder: any) { + this.currentFolder = folder; + this.eventAction.next(folder); + } + + getCurrentFolder() { + return this.currentFolder; + } + + getPinnedFolders() { + this.http.get("../../rest/pinnedFolders").pipe( + map((data: any) => { + data.folders = data.folders.map((folder: any) => { + return { + ...folder, + showAction: false + } + }); + return data; + }), + tap((data: any) => { + this.pinnedFolders = data.folders; + }), + ).subscribe(); + } + + getPinnedList() { + return this.pinnedFolders; + } + + pinFolder(folder: any) { + const dialogRef = this.dialog.open(ConfirmComponent, { autoFocus: false, disableClose: true, data: { title: this.lang.confirm, msg: this.lang.confirmAction } }); + + dialogRef.afterClosed().pipe( + filter((data: string) => data === 'ok'), + exhaustMap(() => this.http.post(`../../rest/folders/${folder.id}/pin`, {})), + tap(() => { + this.getPinnedFolders(); + this.notify.success('Dossier Épinglé'); + }), + catchError((err: any) => { + this.notify.handleErrors(err); + return of(false); + }) + ).subscribe(); + } + + unpinFolder(folder: any) { + const dialogRef = this.dialog.open(ConfirmComponent, { autoFocus: false, disableClose: true, data: { title: this.lang.delete, msg: this.lang.confirmAction } }); + + dialogRef.afterClosed().pipe( + filter((data: string) => data === 'ok'), + exhaustMap(() => this.http.delete(`../../rest/folders/${folder.id}/unpin`)), + tap(() => { + this.getPinnedFolders(); + this.notify.success('Dossier desépinglé'); + }), + catchError((err: any) => { + this.notify.handleErrors(err); + return of(false); + }) + ).subscribe(); + } + + getDragIds() { + return this.pinnedFolders.map((folder: any) => 'folder-list-' + folder.id); + } + + classifyDocument(ev: any, folder: any) { + const dialogRef = this.dialog.open(ConfirmComponent, { autoFocus: false, disableClose: true, data: { title: this.lang.classify + ' ' + ev.item.data.alt_identifier, msg: this.lang.classifyQuestion + ' <b>' + ev.item.data.alt_identifier + '</b> ' + this.lang.in + ' <b>' + folder.label + '</b> ?' } }); + + dialogRef.afterClosed().pipe( + filter((data: string) => data === 'ok'), + exhaustMap(() => this.http.post(`../../rest/folders/${folder.id}/resources`, { resources: [ev.item.data.res_id] })), + tap((data: any) => { + folder.countResources = data.countResources; + }), + tap(() => { + this.notify.success(this.lang.mailClassified); + this.eventAction.next({type:'function', content: 'refreshDao'}); + }), + finalize(() => folder.drag = false), + catchError((err) => { + this.notify.handleErrors(err); + return of(false); + }) + ).subscribe(); + } +} diff --git a/src/frontend/app/folder/panel/panel-folder.component.html b/src/frontend/app/folder/panel/panel-folder.component.html index 104fb582d1137e646254f0a2df6de05926ef28bd..3c55fe04a41e608f51d0e13c82ef880cd3d0ca7d 100644 --- a/src/frontend/app/folder/panel/panel-folder.component.html +++ b/src/frontend/app/folder/panel/panel-folder.component.html @@ -4,5 +4,9 @@ <i class="fa fa-folder panelIconMenu"></i> {{lang.folders}} </mat-panel-title> </mat-expansion-panel-header> - <folder-tree #folderTree [selectedId]="id" (refreshDocList)="refreshDocList()"></folder-tree> + <folder-pinned></folder-pinned> + <button mat-button class="showFolderTree" (click)="showTree = !showTree"> + {{showTree ? lang.less : lang.more}} + </button> + <folder-tree #folderTree *ngIf="showTree" [selectedId]="id" (refreshDocList)="refreshDocList()"></folder-tree> </mat-expansion-panel> diff --git a/src/frontend/app/folder/panel/panel-folder.component.scss b/src/frontend/app/folder/panel/panel-folder.component.scss index b4a186883bf60692571c09c3d3b2958c99cc7460..97bbdfe7ed22d011df31b60e71b3502a6b78d383 100644 --- a/src/frontend/app/folder/panel/panel-folder.component.scss +++ b/src/frontend/app/folder/panel/panel-folder.component.scss @@ -28,4 +28,12 @@ .panelIconMenu { font-size: 22px; +} + +.showFolderTree { + font-size: 13px; + opacity: 0.8; + font-weight: bold; + color: #666; + width: 100%; } \ No newline at end of file diff --git a/src/frontend/app/folder/panel/panel-folder.component.ts b/src/frontend/app/folder/panel/panel-folder.component.ts index bcccf8699772c2fd12424650c85f04687698e976..0eccafaeac24746b1026f849661692e1f6bad082 100644 --- a/src/frontend/app/folder/panel/panel-folder.component.ts +++ b/src/frontend/app/folder/panel/panel-folder.component.ts @@ -13,6 +13,7 @@ export class PanelFolderComponent implements OnInit { lang: any = LANG; + showTree: boolean = false; @Input('selectedId') id: number; @ViewChild('folderTree', { static: true }) folderTree: FolderTreeComponent; diff --git a/src/frontend/app/list/basket-list.component.ts b/src/frontend/app/list/basket-list.component.ts index 479006e89b8c2cd840bc87cc0f903f3eca3ad663..d4d0a55ac88a518bc6da06cdb89b3aea6e1b1949 100755 --- a/src/frontend/app/list/basket-list.component.ts +++ b/src/frontend/app/list/basket-list.component.ts @@ -1,7 +1,7 @@ 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'; +import { merge, Observable, of as observableOf, Subject, Subscription } from 'rxjs'; import { NotificationService } from '../notification.service'; import { MatDialog } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; @@ -21,6 +21,7 @@ import { BasketHomeComponent } from '../basket/basket-home.component'; import { PanelListComponent } from './panel/panel-list.component'; import { AppService } from '../../service/app.service'; import { PanelFolderComponent } from '../folder/panel/panel-folder.component'; +import { FoldersService } from '../folder/folders.service'; declare function $j(selector: any): any; @@ -90,6 +91,7 @@ export class BasketListComponent implements OnInit { displayFolderTags: boolean = false; private destroy$ = new Subject<boolean>(); + subscription: Subscription; @ViewChild('actionsListContext', { static: true }) actionsList: ActionsListComponent; @ViewChild('filtersTool', { static: true }) filtersTool: FiltersToolComponent; @@ -114,11 +116,19 @@ export class BasketListComponent implements OnInit { private notify: NotificationService, public overlay: Overlay, public viewContainerRef: ViewContainerRef, - public appService: AppService) { + public appService: AppService, + private foldersService: FoldersService) { _activatedRoute.queryParams.subscribe( params => this.specificChrono = params.chrono ); + // Event after process action + this.subscription = this.foldersService.catchEvent().subscribe((result: any) => { + if (result.type === 'function') { + this[result.content](); + } + }); + $j("link[href='merged_css.php']").remove(); } @@ -166,6 +176,7 @@ export class BasketListComponent implements OnInit { ngOnDestroy() { this.destroy$.next(true); + this.subscription.unsubscribe(); } initResultList() { @@ -448,11 +459,7 @@ export class BasketListComponent implements OnInit { } listTodrag() { - if (this.panelFolder !== undefined) { - return this.panelFolder.getDragIds(); - } else { - return [0]; - } + return this.foldersService.getDragIds(); } } export interface BasketList { diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts index b9ee7a141f097597588694ba7b4e744067392dd8..09c7bd6f9a145e7ad42b3f53261b034f3903af56 100755 --- a/src/frontend/lang/lang-en.ts +++ b/src/frontend/lang/lang-en.ts @@ -1163,4 +1163,5 @@ export const LANG_EN = { "mustFixErrors" : "You must fix the errors.", "badActionParam" : "Bad action parameter", "technicalId" : "Technical identifier", + "foldersTree" : "Folders tree", }; diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts index c37a77ad55d83e81f56e1afe71cf61f587081eb7..20ce5c272a204792617e8c71360011370ab1c80f 100755 --- a/src/frontend/lang/lang-fr.ts +++ b/src/frontend/lang/lang-fr.ts @@ -1200,4 +1200,5 @@ export const LANG_FR = { "mustFixErrors" : "Veuillez corriger les erreurs.", "badActionParam" : "Mauvais paramétrage de l'action", "technicalId" : "Identifiant technique", + "foldersTree" : "Arborescence des dossiers", }; diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts index 9d56ea9b7a53c3ce8f57d1c24b52cb0b40e7ca71..d3d0673f65c773eb4f41fa607e340987366af484 100755 --- a/src/frontend/lang/lang-nl.ts +++ b/src/frontend/lang/lang-nl.ts @@ -1189,4 +1189,5 @@ export const LANG_NL = { "mustFixErrors" : "You must fix the errors.", //_TO_TRANSLATE "badActionParam" : "Bad action parameter", //_TO_TRANSLATE "technicalId" : "Technical identifier", //_TO_TRANSLATE + "foldersTree" : "Folders tree", //_TO_TRANSLATE };