From f22940719c1d109695be4e5b4b302dca228b5da1 Mon Sep 17 00:00:00 2001 From: Alex ORLUC <alex.orluc@maarch.org> Date: Tue, 28 Jan 2020 15:16:21 +0100 Subject: [PATCH] FEAT #12869 TIME 3 front linked resource list --- src/frontend/app/app.module.ts | 7 +- .../link-resource-modal.component.html | 11 +++ .../link-resource-modal.component.scss | 15 +++ .../link-resource-modal.component.ts | 20 ++++ .../linked-resource-list.component.html | 71 +++++++++---- .../linked-resource-list.component.scss | 26 +++++ .../linked-resource-list.component.ts | 99 ++++++++++++++++++- .../app/list/basket-list.component.ts | 2 +- .../app/process/process.component.html | 4 +- src/frontend/app/process/process.component.ts | 2 +- src/frontend/lang/lang-en.ts | 2 + src/frontend/lang/lang-fr.ts | 2 + src/frontend/lang/lang-nl.ts | 2 + 13 files changed, 235 insertions(+), 28 deletions(-) create mode 100644 src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.html create mode 100644 src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.scss create mode 100644 src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.ts diff --git a/src/frontend/app/app.module.ts b/src/frontend/app/app.module.ts index 90274498768..c32ab57c838 100755 --- a/src/frontend/app/app.module.ts +++ b/src/frontend/app/app.module.ts @@ -104,6 +104,7 @@ import { AddAvisModelModalComponent } from './avis/addAvisModel/add-avis-model-m import { CriteriaToolComponent } from './adv-search/criteria-tool/criteria-tool.component'; import { SearchAdvListComponent } from './adv-search/list/search-adv-list.component'; import { LinkedResourceListComponent } from './linkedResource/linked-resource-list.component'; +import { LinkResourceModalComponent } from './linkedResource/linkResourceModal/link-resource-modal.component'; @NgModule({ @@ -197,7 +198,8 @@ import { LinkedResourceListComponent } from './linkedResource/linked-resource-li AddAvisModelModalComponent, CriteriaToolComponent, SearchAdvListComponent, - LinkedResourceListComponent + LinkedResourceListComponent, + LinkResourceModalComponent ], entryComponents: [ ConfirmModalComponent, @@ -241,7 +243,8 @@ import { LinkedResourceListComponent } from './linkedResource/linked-resource-li ContactModalComponent, VisaWorkflowModalComponent, AddVisaModelModalComponent, - AddAvisModelModalComponent + AddAvisModelModalComponent, + LinkResourceModalComponent ], providers: [ FiltersListService, FoldersService, ActionsService, PrivilegeService ], bootstrap: [ AppComponent ] diff --git a/src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.html b/src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.html new file mode 100644 index 00000000000..9e5f0edf5af --- /dev/null +++ b/src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.html @@ -0,0 +1,11 @@ +<h1 mat-dialog-title> + <span style="flex: 1;" [title]="lang.linkResource"> + {{lang.linkResource}} + </span> + <button [title]="lang.close" mat-icon-button (click)="dialogRef.close();"> + <mat-icon class="fa fa-times"></mat-icon> + </button></h1> +<mat-dialog-content class="modal-container"> + <app-criteria-tool></app-criteria-tool> + <search-adv-list [search]="'&resourceField=aléa'"></search-adv-list> +</mat-dialog-content> \ No newline at end of file diff --git a/src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.scss b/src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.scss new file mode 100644 index 00000000000..7abd563bb58 --- /dev/null +++ b/src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.scss @@ -0,0 +1,15 @@ +@import '../../../css/vars.scss'; + +.mat-dialog-title { + padding: 10px; + display: flex; + align-items: center; +} +.modal-container{ + min-height: 250px; + height: auto; +} + +.modal-body{ + min-height: auto; +} diff --git a/src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.ts b/src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.ts new file mode 100644 index 00000000000..0875fa58c37 --- /dev/null +++ b/src/frontend/app/linkedResource/linkResourceModal/link-resource-modal.component.ts @@ -0,0 +1,20 @@ +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { LANG } from '../../translate.component'; +import { HttpClient } from '@angular/common/http'; + +@Component({ + templateUrl: 'link-resource-modal.component.html', + styleUrls: ['link-resource-modal.component.scss'], +}) +export class LinkResourceModalComponent { + lang: any = LANG; + + constructor( + public http: HttpClient, + @Inject(MAT_DIALOG_DATA) public data: any, + public dialogRef: MatDialogRef<LinkResourceModalComponent>) { + } + + ngOnInit(): void { } +} diff --git a/src/frontend/app/linkedResource/linked-resource-list.component.html b/src/frontend/app/linkedResource/linked-resource-list.component.html index 6d6c190a90f..cb0a90637df 100644 --- a/src/frontend/app/linkedResource/linked-resource-list.component.html +++ b/src/frontend/app/linkedResource/linked-resource-list.component.html @@ -1,6 +1,4 @@ -<!--<app-criteria-tool></app-criteria-tool> -<search-adv-list [search]="'&resourceField=aléa'"></search-adv-list>--> - +<mat-card id="viewThumbnail" style="display:none;position: fixed;z-index: 2;margin-left: 1px;left: 50%;transform: translate(-50%,-50%);top: 50%;"><img style="max-height: 100vh;" src="{{thumbnailUrl}}" /></mat-card> <div class="row"> <div class="col-md-12"> <mat-paginator #paginator [length]="100" [hidePageSize]="true" [pageSize]="10"> @@ -9,21 +7,58 @@ </div> <mat-table #table [dataSource]="dataSource" matSort matSortActive="resId" matSortDirection="asc"> <ng-container matColumnDef="resId"> - <mat-cell *matCellDef="let element" style="flex:1;"> - <span> - {{element.resId}} - </span> + <mat-cell *matCellDef="let row" style="flex: 1;flex-direction: column;padding: 0px;"> + <div class="sub-info"> + <span class="sub-info-data col-md-4"> + <i class="fas fa-exchange-alt" title="{{lang.category}}"></i> + + <span title="{{lang[row.categoryId]}}">{{lang[row.categoryId]}}</span> + </span> + <span class="sub-info-data col-md-4 text-center"> + <i class="fas fa-user" title="{{lang.contact}}"></i> + + <span [title]="'Pierre BRUNEL'">Pierre BRUNEL</span> + </span> + <span class="sub-info-data col-md-4 text-right"> + <i class="fas fa-calendar" title="{{lang.creationDate}}"></i> + + <span [title]="row.documentDate | fullDate">{{row.documentDate | timeAgo : 'full' | ucfirst}}</span> + </span> + <span class="sub-info-data col-md-6"> + <i class="fas fa-sitemap" title="{{lang.getAssignee}}"></i> + + <span + [title]="row.destUserLabel + ' (' + row.destinationLabel + ')'">{{row.destUserLabel + ' (' + row.destinationLabel + ')'}}</span> + </span> + <span class="sub-info-data col-md-6 text-right" *ngIf="row.visaCircuit.length > 0"> + <i class="fas fa-list-ol" title="{{lang.visaWorkflow}}"></i> + + <span [title]="getUsersVisaCircuit(row)">{{getUsersVisaCircuit(row)}}</span> + </span> + </div> + <div class="main-info"> + <span class="main-info-status"> + <mat-icon title="{{row.statusLabel}}" [ngStyle]="{'color': row.priorityColor}" color="primary" + class="{{row.statusImage.charAt(0)}}{{row.statusImage.charAt(1)}} {{row.statusImage}} {{row.statusImage.charAt(0)}}{{row.statusImage.charAt(1)}}-2x"> + </mat-icon> + <span *ngIf="row.confidentiality" class="watermark">{{lang.confidential}}</span> + </span> + <span class="main-info-data" style="width:200px;text-align:center;"> + {{row.chrono}} + </span> + <span class="main-info-data" style="font-weight:bold;flex:1;" + [class.undefined]="row.subject == lang.undefined" + title="{{row.subject}}">{{row.subject | shorten: 150: '...'}}</span> + <span class="main-info-data"> + <button mat-icon-button color="warn" [title]="lang.unlink" (click)="$event.stopPropagation();unlinkResource(row)"> + <mat-icon class="fa fa-unlink fa-2x" aria-hidden="true"></mat-icon> + </button> + </span> + </div> </mat-cell> </ng-container> - <ng-container matColumnDef="actions"> - <mat-cell *matCellDef="let element" style="justify-content: flex-end;"> - <button mat-icon-button color="warn" (click)="$event.stopPropagation();"> - <mat-icon class="fa fa-unlink fa-2x" aria-hidden="true"></mat-icon> - </button> - </mat-cell> - </ng-container> - <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumns;" (mouseenter)="viewThumbnail(row);" (mouseleave)="closeThumbnail();"></mat-row> </mat-table> -<!--<button mat-fab class="linkRes" color="primary" [title]="lang.link" (click)="createAttachment()">--> -<!-- <mat-icon class="fa fa-link" style="height:auto;"></mat-icon>--> -<!--</button>--> +<button mat-fab class="linkRes" color="primary" [title]="lang.linkResource" (click)="openSearchResourceModal()"> + <mat-icon class="fa fa-link" style="height:auto;"></mat-icon> +</button> diff --git a/src/frontend/app/linkedResource/linked-resource-list.component.scss b/src/frontend/app/linkedResource/linked-resource-list.component.scss index ce72680c5b5..9971bbcc135 100644 --- a/src/frontend/app/linkedResource/linked-resource-list.component.scss +++ b/src/frontend/app/linkedResource/linked-resource-list.component.scss @@ -7,4 +7,30 @@ bottom: 10px; margin-left: 10px; margin-top: 10px; +} + +.main-info { + width:100%; +} + +.sub-info { + width: 100%; + display: block; +} + +.sub-info-data { + white-space: pre; + overflow: hidden; + text-overflow: ellipsis; + padding-left: 5px; + padding-right: 5px; +} + +.watermark { + position: absolute; + left: 50%; + transform: translateX(-50%) rotate(-20deg); + color: red; + font-weight: bold; + opacity: 0.6; } \ No newline at end of file diff --git a/src/frontend/app/linkedResource/linked-resource-list.component.ts b/src/frontend/app/linkedResource/linked-resource-list.component.ts index 1b9c8622e29..f3c12913301 100644 --- a/src/frontend/app/linkedResource/linked-resource-list.component.ts +++ b/src/frontend/app/linkedResource/linked-resource-list.component.ts @@ -6,8 +6,11 @@ import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { AppService } from '../../service/app.service'; -import { tap, catchError, finalize } from 'rxjs/operators'; +import { tap, catchError, finalize, map, filter, exhaustMap } from 'rxjs/operators'; import { of } from 'rxjs'; +import { ConfirmComponent } from '../../plugins/modal/confirm.component'; +import { MatDialog } from '@angular/material'; +import { LinkResourceModalComponent } from './linkResourceModal/link-resource-modal.component'; declare function $j(selector: any): any; @@ -24,7 +27,55 @@ export class LinkedResourceListComponent implements OnInit { linkedResources: any[] = []; dataSource: any; - displayedColumns = ['resId', 'actions']; + displayedColumns = ['resId']; + + thumbnailUrl: string = ''; + + displayedMainData: any = [ + { + 'value': 'chrono', + 'cssClasses': ['softColorData', 'align_centerData', 'chronoData'], + 'icon': '' + }, + { + 'value': 'subject', + 'cssClasses': ['longData'], + 'icon': '' + } + ]; + + displayedSubData: any = [ + { + "value": "getCategory", + "cssClasses": [], + "icon": "fa-exchange-alt", + "displayValue": "incoming" + }, + { + "value": "getAssignee", + "cssClasses": [], + "icon": "fa-sitemap", + "displayValue": "Georges GRAND (Direction Générale des Services)" + }, + { + "value": "getRecipients", + "cssClasses": [], + "icon": "fa-user", + "displayValue": ["Patricia PETIT"] + }, + { + "value": "getSenders", + "cssClasses": [], + "icon": "fa-book", + "displayValue": ["Pierre BRUNEL "] + }, + { + "value": "getCreationAndProcessLimitDates", + "cssClasses": ["align_rightData"], + "icon": "fa-calendar", + "displayValue": { "creationDate": "2020-01-27 10:45:01.012295" } + } + ]; @Input('resId') resId: number; @@ -34,7 +85,8 @@ export class LinkedResourceListComponent implements OnInit { constructor( public http: HttpClient, private notify: NotificationService, - public appService: AppService + public appService: AppService, + public dialog: MatDialog, ) { } ngOnInit(): void { @@ -43,7 +95,7 @@ export class LinkedResourceListComponent implements OnInit { } initLinkedResources() { - this.http.get('../../rest/resources/100/linkedResources').pipe( + this.http.get(`../../rest/resources/${this.resId}/linkedResources`).pipe( tap((data: any) => { this.linkedResources = data.linkedResources; setTimeout(() => { @@ -59,4 +111,43 @@ export class LinkedResourceListComponent implements OnInit { }) ).subscribe(); } + + getUsersVisaCircuit(row: any) { + return row.visaCircuit.map((item: any) => item.userLabel); + } + + unlinkResource(row: any) { + const dialogRef = this.dialog.open(ConfirmComponent, { autoFocus: false, disableClose: true, data: { title: this.lang.unlink, msg: this.lang.confirmAction } }); + + dialogRef.afterClosed().pipe( + filter((data: string) => data === 'ok'), + exhaustMap(() => this.http.delete(`../../rest/resources/${this.resId}/linkedResources/${row.resId}`)), + tap(() => { + this.linkedResources = this.linkedResources.filter(resource => resource.resId !== row.resId); + this.dataSource = new MatTableDataSource(this.linkedResources); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + this.notify.success(this.lang.resourceUnlinked); + }), + catchError((err: any) => { + this.notify.handleSoftErrors(err); + return of(false); + }) + ).subscribe(); + } + + viewThumbnail(row: any) { + //if (row.hasDocument) { + this.thumbnailUrl = '../../rest/resources/' + row.resId + '/thumbnail'; + $j('#viewThumbnail').show(); + //} + } + + closeThumbnail() { + $j('#viewThumbnail').hide(); + } + + openSearchResourceModal() { + this.dialog.open(LinkResourceModalComponent, { data: { resId: this.resId } }); + } } diff --git a/src/frontend/app/list/basket-list.component.ts b/src/frontend/app/list/basket-list.component.ts index 63e9089e694..6a0b10c1d37 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, ApplicationRef } from '@angular/core'; +import { Component, OnInit, ViewChild, EventEmitter, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../translate.component'; import { merge, Observable, of as observableOf, Subject, Subscription, of } from 'rxjs'; diff --git a/src/frontend/app/process/process.component.html b/src/frontend/app/process/process.component.html index 58510d3fc65..e9b56e286b0 100644 --- a/src/frontend/app/process/process.component.html +++ b/src/frontend/app/process/process.component.html @@ -76,7 +76,7 @@ <app-notes-list *ngIf="currentTool === 'notes' && !loading" #appNotesList [editMode]="true" [resId]="currentResourceInformations.resId"> </app-notes-list> - <app-linked-resource-list *ngIf="currentTool === 'link' && !loading" #appLinkedResourceList + <app-linked-resource-list *ngIf="currentTool === 'linkedResources' && !loading" #appLinkedResourceList [resId]="currentResourceInformations.resId"> </app-linked-resource-list> <app-diffusions-list *ngIf="currentTool === 'diffusionList' && !loading" #appDiffusionsList @@ -252,7 +252,7 @@ <app-notes-list *ngIf="modal.id === 'notes' && !loading" #appNotesList [editMode]="true" [resId]="currentResourceInformations.resId"> </app-notes-list> - <app-linked-resource-list *ngIf="modal.id === 'link' && !loading" #appLinkedResourceList + <app-linked-resource-list *ngIf="modal.id === 'linkedResources' && !loading" #appLinkedResourceList [resId]="currentResourceInformations.resId"></app-linked-resource-list> <app-diffusions-list *ngIf="modal.id === 'diffusionList' && !loading" #appDiffusionsList [adminMode]="false" [resId]="currentResourceInformations.resId" [expanded]="true"> diff --git a/src/frontend/app/process/process.component.ts b/src/frontend/app/process/process.component.ts index 0c99d62cd99..becd45d63e3 100755 --- a/src/frontend/app/process/process.component.ts +++ b/src/frontend/app/process/process.component.ts @@ -84,7 +84,7 @@ export class ProcessComponent implements OnInit { count: 0 }, { - id: 'link', + id: 'linkedResources', icon: 'fas fa-link', label: this.lang.links, count: 0 diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts index e2bbee1388d..8cf19b40c4d 100755 --- a/src/frontend/lang/lang-en.ts +++ b/src/frontend/lang/lang-en.ts @@ -1451,4 +1451,6 @@ export const LANG_EN = { "systemActions": "System action(s)", "viewAllHistory": "View all history", "viewActionsHistory": "View only actions in history", + "unlink": "Unlink this resource", + "linkResource": "Link to a new resource", }; diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts index 72c1c141fbe..5ead8df0f13 100755 --- a/src/frontend/lang/lang-fr.ts +++ b/src/frontend/lang/lang-fr.ts @@ -1491,4 +1491,6 @@ export const LANG_FR = { "systemActions": "Événement(s) système", "viewAllHistory": "Afficher tout l'historique", "viewActionsHistory": "Afficher l'historique des actions", + "unlink": "Enlever la liaison", + "linkResource": "Lier un nouveau courrier", }; diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts index 9cf76cecc56..02ada84bb9e 100755 --- a/src/frontend/lang/lang-nl.ts +++ b/src/frontend/lang/lang-nl.ts @@ -1476,4 +1476,6 @@ export const LANG_NL = { "systemActions": "System action(s)", //_TO_TRANSLATE "viewAllHistory": "View all history", //_TO_TRANSLATE "viewActionsHistory": "View only actions in history", //_TO_TRANSLATE + "unlink": "Unlink this resource", //_TO_TRANSLATE + "linkResource": "Link to a new resource", //_TO_TRANSLATE }; -- GitLab