diff --git a/src/app/home/controllers/TileController.php b/src/app/home/controllers/TileController.php index 4bdf25472703f15f9bddcfd4ea34241414eb6483..8b1bcf224e958fb265ad341d8c28ffd2cc51a0e2 100644 --- a/src/app/home/controllers/TileController.php +++ b/src/app/home/controllers/TileController.php @@ -22,7 +22,7 @@ use Slim\Http\Response; class TileController { - const TYPES = ['lastViewMails', 'basket', 'savedQuery', 'followedMails', 'folder', 'externalSignatureBook', 'shortcut']; + const TYPES = ['myLastResources', 'basket', 'searchTemplate', 'followedMail', 'folder', 'externalSignatoryBook', 'shortcut']; const VIEWS = ['list', 'resume', 'chart']; public function get(Request $request, Response $response) diff --git a/src/frontend/app/app.module.ts b/src/frontend/app/app.module.ts index 4d38dc702d35d6084130b5c92978e4a922fcfe2b..5e7002064d672c86284da8f5ef2a8c39cc0c2256 100755 --- a/src/frontend/app/app.module.ts +++ b/src/frontend/app/app.module.ts @@ -33,7 +33,7 @@ import { DashboardComponent } from './home/dashboard/dashboard.component'; import { TileViewListComponent } from './home/dashboard/tile/view/list/tile-view-list.component'; import { TileViewResumeComponent } from './home/dashboard/tile/view/resume/tile-view-resume.component'; import { TileViewChartComponent } from './home/dashboard/tile/view/chart/tile-view-chart.component'; -import { TileLastMailsViewDashboardComponent } from './home/dashboard/tile/lastMailsView/tile-last-mails-view.component'; +import { TileLastMailsViewDashboardComponent } from './home/dashboard/tile/type/lastMailsView/tile-last-mails-view.component'; import { TileCreateComponent } from './home/dashboard/tile/tile-create.component'; import { NgxChartsModule } from '@swimlane/ngx-charts'; diff --git a/src/frontend/app/home/dashboard/dashboard.component.ts b/src/frontend/app/home/dashboard/dashboard.component.ts index 193eb5c43003385ad3dacbe9cc3d21434f30aff4..00c9ff1b2d6da8475eee45badec7f1fd11f79708 100644 --- a/src/frontend/app/home/dashboard/dashboard.component.ts +++ b/src/frontend/app/home/dashboard/dashboard.component.ts @@ -4,9 +4,11 @@ import { TranslateService } from '@ngx-translate/core'; import { DashboardService } from './dashboard.service'; import { FunctionsService } from '@service/functions.service'; import { TileCreateComponent } from './tile/tile-create.component'; -import { exhaustMap, filter, tap } from 'rxjs/operators'; +import { catchError, exhaustMap, filter, tap } from 'rxjs/operators'; import { MatDialog } from '@angular/material/dialog'; import { ConfirmComponent } from '@plugins/modal/confirm.component'; +import { of } from 'rxjs'; +import { NotificationService } from '@service/notification/notification.service'; @Component({ selector: 'app-dashboard', @@ -24,6 +26,7 @@ export class DashboardComponent implements OnInit, AfterViewInit { constructor( public translate: TranslateService, public http: HttpClient, + private notify: NotificationService, private dashboardService: DashboardService, private functionsService: FunctionsService, public dialog: MatDialog, @@ -49,40 +52,27 @@ export class DashboardComponent implements OnInit, AfterViewInit { } getDashboardConfig() { - const test: any = [ - { - id: 1, - type: 'myLastResources', - view: 'resume', - sequence: 0 - }, - { - id: 1, - type: 'myLastResources', - view: 'list', - sequence: 3 - }, - { - id: 1, - type: 'myLastResources', - view: 'chart', - sequence: 5 - } - ]; - - for (let index = 0; index < 6; index++) { - const tmpTile = test.find((tile: any) => tile.sequence === index); - if (!this.functionsService.empty(tmpTile)) { - const objTile = {...this.dashboardService.getTile(tmpTile.type), ...tmpTile}; - this.tiles.push(objTile); - } else { - this.tiles.push({ - id: null, - sequence: index, - editMode: false - }); - } - } + this.http.get('../rest/tiles').pipe( + tap((data: any) => { + for (let index = 0; index < 6; index++) { + const tmpTile = data.tiles.find((tile: any) => tile.position === index); + if (!this.functionsService.empty(tmpTile)) { + const objTile = {...this.dashboardService.getTile(tmpTile.type), ...tmpTile}; + this.tiles.push(objTile); + } else { + this.tiles.push({ + id: null, + sequence: index, + editMode: false + }); + } + } + }), + catchError((err: any) => { + this.notify.handleErrors(err); + return of(false); + }) + ).subscribe(); } changeView(tile: any, view: string) { @@ -104,7 +94,7 @@ export class DashboardComponent implements OnInit, AfterViewInit { dialogRef.afterClosed().pipe( filter((data: string) => !this.functionsService.empty(data)), tap((data: any) => { - tile = {...this.dashboardService.getTile(data.type), ...data}; + this.tiles[tile.sequence] = {...this.dashboardService.getTile(data.type), ...data}; }) ).subscribe(); } @@ -116,9 +106,9 @@ export class DashboardComponent implements OnInit, AfterViewInit { delete(tile: any) { const dialogRef = this.dialog.open(ConfirmComponent, { panelClass: 'maarch-modal', autoFocus: false, disableClose: true, data: { title: this.translate.instant('lang.delete'), msg: this.translate.instant('lang.confirmAction') } }); - // TO DO: SAVE IN BACK dialogRef.afterClosed().pipe( filter((data: string) => data === 'ok'), + exhaustMap(() => this.http.delete(`../rest/tiles/${tile.id}`)), tap(() => { this.tiles[tile.sequence] = { id: null, diff --git a/src/frontend/app/home/dashboard/dashboard.service.ts b/src/frontend/app/home/dashboard/dashboard.service.ts index 53d4916273d56a6ac340a3a876c4d8b5243e7e61..23789b52809eab1b998719a00878b63434123265 100644 --- a/src/frontend/app/home/dashboard/dashboard.service.ts +++ b/src/frontend/app/home/dashboard/dashboard.service.ts @@ -2,11 +2,33 @@ import { Injectable } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { LatinisePipe } from 'ngx-pipes'; +interface Tiles { + 'myLastResources': Tile; + /*'basket': Tile; + 'searchTemplate': Tile; + 'followedMail': Tile; + 'folder': Tile; + 'externalSignatoryBook': Tile; + 'shortcut': Tile;*/ +} + +interface Tile { + 'icon': string; // icon of tile + 'menus': ('delete' | 'view')[]; // action of tile + 'views': TileView[]; // views tile +} + +interface TileView { + 'id': 'list' | 'resume' | 'chart'; // identifier + 'route': string; // router when click on tile +} + @Injectable() export class DashboardService { - tileTypes: any = { + tileTypes: Tiles = { myLastResources : { + icon: 'fa fa-history', menus : [ 'view', 'delete' @@ -26,7 +48,8 @@ export class DashboardService { } ] }, - basket : { + /*basket : { + icon: 'fa fa-inbox', menus : [ 'view', 'delete' @@ -47,6 +70,7 @@ export class DashboardService { ] }, searchTemplate : { + icon: 'fa fa-search', menus : [ 'view', 'delete' @@ -67,6 +91,7 @@ export class DashboardService { ] }, followedMail : { + icon: 'fa fa-star', menus : [ 'view', 'delete' @@ -87,6 +112,7 @@ export class DashboardService { ] }, folder : { + icon: 'fa fa-folder', menus : [ 'view', 'delete' @@ -107,6 +133,7 @@ export class DashboardService { ] }, externalSignatoryBook : { + icon: 'fas fa-pen-nib', menus : [ 'view', 'delete' @@ -127,11 +154,12 @@ export class DashboardService { ] }, shortcut : { + icon: null, menus : [ 'delete' ], views: [] - }, + },*/ }; constructor( diff --git a/src/frontend/app/home/dashboard/tile/lastMailsView/tile-last-mails-view.component.html b/src/frontend/app/home/dashboard/tile/lastMailsView/tile-last-mails-view.component.html deleted file mode 100644 index 45e40b517d4b1ad0314448e5395a093491edb8e9..0000000000000000000000000000000000000000 --- a/src/frontend/app/home/dashboard/tile/lastMailsView/tile-last-mails-view.component.html +++ /dev/null @@ -1,17 +0,0 @@ -<div class="tile-title"> - {{'lang.'+ tile.type | translate}} -</div> -<ng-container *ngIf="loading; else elseLoaded"> - <mat-progress-bar color="primary" mode="indeterminate" class="loader"> - </mat-progress-bar> - <i class="fa fa-history tile-icon" color="primary"></i> -</ng-container> -<ng-template #elseLoaded> - <app-tile-view-list *ngIf="view==='list'" [displayColumns]="['recipient','subject','creationDate']" - [resources]="resources" [icon]="'fa-history'" [route]="route" style="display: flex;flex: 1;overflow: auto;"> - </app-tile-view-list> - <app-tile-view-resume *ngIf="view==='resume'" [route]="route" [countResources]="countResources" [icon]="'fa-history'" - [resourceLabel]="'courrier(s)'" style="display: flex;flex: 1;overflow: auto;"></app-tile-view-resume> - <app-tile-view-chart *ngIf="view==='chart'" [route]="route" [resources]="resources" [icon]="'fa-history'" style="display: flex;flex: 1;overflow: auto;"> - </app-tile-view-chart> -</ng-template> \ No newline at end of file diff --git a/src/frontend/app/home/dashboard/tile/tile-create.component.ts b/src/frontend/app/home/dashboard/tile/tile-create.component.ts index a2c4fe00b68dbfdcb42ca15218cca13668d4a672..5e74add5ad234cdcf206513bb6e8644b7da918b4 100644 --- a/src/frontend/app/home/dashboard/tile/tile-create.component.ts +++ b/src/frontend/app/home/dashboard/tile/tile-create.component.ts @@ -70,7 +70,8 @@ export class TileCreateComponent implements OnInit { return { type : this.selectedTileType, view: this.selectedView, - userId: this.headerService.user.id + userId: this.headerService.user.id, + position: this.sequence }; } @@ -78,11 +79,11 @@ export class TileCreateComponent implements OnInit { const objToSend: any = this.formatData(); this.http.post('../rest/tiles', objToSend).pipe( tap((data: any) => { - objToSend.id = data; this.dialogRef.close({ - id : data, + id : data.id, type: objToSend.type, view: objToSend.view, + position: this.sequence }); }), catchError((err: any) => { diff --git a/src/frontend/app/home/dashboard/tile/type/lastMailsView/tile-last-mails-view.component.html b/src/frontend/app/home/dashboard/tile/type/lastMailsView/tile-last-mails-view.component.html new file mode 100644 index 0000000000000000000000000000000000000000..6857eec27e72e7b47be4504331d74990a826e44f --- /dev/null +++ b/src/frontend/app/home/dashboard/tile/type/lastMailsView/tile-last-mails-view.component.html @@ -0,0 +1,32 @@ +<div class="tile-title"> + {{'lang.'+ tile.type | translate}} +</div> +<ng-container *ngIf="loading; else elseLoaded"> + <mat-progress-bar color="primary" mode="indeterminate" class="loader"> + </mat-progress-bar> + <i class="fa fa-history tile-icon" color="primary"></i> +</ng-container> +<ng-template #elseLoaded> + <app-tile-view-list *ngIf="view==='list'" + [displayColumns]="['recipient','subject','creationDate']" + [resources]="resources" + [icon]="tile.icon" + [route]="route" + style="display: flex;flex: 1;overflow: auto;"> + </app-tile-view-list> + <app-tile-view-resume *ngIf="view==='resume'" + [route]="route" + [countResources]="countResources" + [icon]="tile.icon" + [extraParams]="extraParams" + [resourceLabel]="'courrier(s)'" + style="display: flex;flex: 1;overflow: auto;"> + </app-tile-view-resume> + <app-tile-view-chart *ngIf="view==='chart'" + [route]="route" + [resources]="resources" + [extraParams]="extraParams" + [icon]="tile.icon" + style="display: flex;flex: 1;overflow: auto;"> + </app-tile-view-chart> +</ng-template> \ No newline at end of file diff --git a/src/frontend/app/home/dashboard/tile/lastMailsView/tile-last-mails-view.component.scss b/src/frontend/app/home/dashboard/tile/type/lastMailsView/tile-last-mails-view.component.scss similarity index 88% rename from src/frontend/app/home/dashboard/tile/lastMailsView/tile-last-mails-view.component.scss rename to src/frontend/app/home/dashboard/tile/type/lastMailsView/tile-last-mails-view.component.scss index 46737687c47da25088770a8594212e128c2333e2..247544a8bcc1af8e1445ac1cf03c995573105924 100644 --- a/src/frontend/app/home/dashboard/tile/lastMailsView/tile-last-mails-view.component.scss +++ b/src/frontend/app/home/dashboard/tile/type/lastMailsView/tile-last-mails-view.component.scss @@ -1,4 +1,4 @@ -@import '../../../../../css/vars.scss'; +@import '../../../../../../css/vars.scss'; .tile-title { padding: 10px; diff --git a/src/frontend/app/home/dashboard/tile/lastMailsView/tile-last-mails-view.component.ts b/src/frontend/app/home/dashboard/tile/type/lastMailsView/tile-last-mails-view.component.ts similarity index 95% rename from src/frontend/app/home/dashboard/tile/lastMailsView/tile-last-mails-view.component.ts rename to src/frontend/app/home/dashboard/tile/type/lastMailsView/tile-last-mails-view.component.ts index a6465273388c18485a669896087eea62dba7c059..a9a3a6837f6f8ef37416e81e183a94c9203e34ea 100644 --- a/src/frontend/app/home/dashboard/tile/lastMailsView/tile-last-mails-view.component.ts +++ b/src/frontend/app/home/dashboard/tile/type/lastMailsView/tile-last-mails-view.component.ts @@ -26,6 +26,7 @@ export class TileLastMailsViewDashboardComponent implements OnInit, AfterViewIni label: 'Mes derniers courriers consultés'; resources: any[] = []; + extraParams: any = {}; countResources: number = 0; route: string = null; @@ -109,6 +110,10 @@ export class TileLastMailsViewDashboardComponent implements OnInit, AfterViewIni // FOR TEST setTimeout(() => { this.countResources = 23; + this.extraParams = { + userId: 20, + folderId: 1 + }; resolve(true); }, 3000); @@ -152,6 +157,10 @@ export class TileLastMailsViewDashboardComponent implements OnInit, AfterViewIni value: 2 } ]; + this.extraParams = { + userId: 20, + folderId: 1 + }; resolve(true); }, 3000); diff --git a/src/frontend/app/home/dashboard/tile/view/chart/tile-view-chart.component.html b/src/frontend/app/home/dashboard/tile/view/chart/tile-view-chart.component.html index 2e95aa2768fad5fd35dc62293b09e7a84a1ad718..ebb2e2f646e5e67a3f62bd524bc7eb8d6ada11bb 100644 --- a/src/frontend/app/home/dashboard/tile/view/chart/tile-view-chart.component.html +++ b/src/frontend/app/home/dashboard/tile/view/chart/tile-view-chart.component.html @@ -4,4 +4,4 @@ [legend]="false" [labels]="true" > </ngx-charts-pie-chart> -<i class="fa {{icon}} tile-icon" color="primary"></i> \ No newline at end of file +<i class="{{icon}} tile-icon" color="primary"></i> \ No newline at end of file diff --git a/src/frontend/app/home/dashboard/tile/view/chart/tile-view-chart.component.ts b/src/frontend/app/home/dashboard/tile/view/chart/tile-view-chart.component.ts index 975f0064b33f59e49e5fbaf4c4e478b284ce57f8..e9bedc069082c486943461024f7e049b1807e435 100644 --- a/src/frontend/app/home/dashboard/tile/view/chart/tile-view-chart.component.ts +++ b/src/frontend/app/home/dashboard/tile/view/chart/tile-view-chart.component.ts @@ -3,6 +3,7 @@ import { HttpClient } from '@angular/common/http'; import { TranslateService } from '@ngx-translate/core'; import { AppService } from '@service/app.service'; import { Router } from '@angular/router'; +import { NotificationService } from '@service/notification/notification.service'; @Component({ selector: 'app-tile-view-chart', @@ -14,12 +15,15 @@ export class TileViewChartComponent implements OnInit, AfterViewInit { @Input() icon: string = ''; @Input() resources: any[]; @Input() route: string = null; + @Input() extraParams: any = {}; + constructor( public translate: TranslateService, public http: HttpClient, public appService: AppService, private router: Router, + private notify: NotificationService ) { } ngOnInit(): void { @@ -28,10 +32,28 @@ export class TileViewChartComponent implements OnInit, AfterViewInit { ngAfterViewInit(): void { } - goTo(resource: any) { - // TO DO format route - const formatedRoute = this.route.replace(':resId', resource.resId); - console.log(formatedRoute); - // this.router.navigate([formatedRoute]); + goTo() { + const regex = /:\w*/g; + const res = this.route.match(regex); + + let formatedRoute = this.route; + const errors = []; + + if (res !== null) { + res.forEach(elem => { + const value = this.extraParams[elem.replace(':', '')]; + if (value !== undefined) { + formatedRoute = formatedRoute.replace(elem, value); + } else { + errors.push(elem); + } + }); + } + + if (errors.length === 0) { + this.router.navigate([formatedRoute]); + } else { + this.notify.error(errors + ' not found'); + } } } diff --git a/src/frontend/app/home/dashboard/tile/view/list/tile-view-list.component.html b/src/frontend/app/home/dashboard/tile/view/list/tile-view-list.component.html index 92fe2262a4012a6c9cef712fcd9b175d1715824a..15147bd5a76e8289ba55e9ebae799cfd469cf124 100644 --- a/src/frontend/app/home/dashboard/tile/view/list/tile-view-list.component.html +++ b/src/frontend/app/home/dashboard/tile/view/list/tile-view-list.component.html @@ -1,4 +1,4 @@ -<i class="fa {{icon}} tile-icon" color="primary"></i> +<i class="{{icon}} tile-icon" color="primary"></i> <mat-list role="list" style="width: 100%;overflow: auto;"> <mat-list-item class="resource" role="listitem" *ngFor="let resource of resources" (mouseenter)="resource.hovered=true" (mouseleave)="resource.hovered=false" (click)="route !== null ? goTo(resource): false"> <div class="item" *ngFor="let col of displayColumns"> diff --git a/src/frontend/app/home/dashboard/tile/view/list/tile-view-list.component.ts b/src/frontend/app/home/dashboard/tile/view/list/tile-view-list.component.ts index b8335ae3e68d22bd6834c94c436abaa7c86a3dad..354d96241881c2ddb05c381081611f403d776fb1 100644 --- a/src/frontend/app/home/dashboard/tile/view/list/tile-view-list.component.ts +++ b/src/frontend/app/home/dashboard/tile/view/list/tile-view-list.component.ts @@ -3,6 +3,7 @@ import { HttpClient } from '@angular/common/http'; import { TranslateService } from '@ngx-translate/core'; import { AppService } from '@service/app.service'; import { Router } from '@angular/router'; +import { NotificationService } from '@service/notification/notification.service'; @Component({ selector: 'app-tile-view-list', @@ -25,6 +26,7 @@ export class TileViewListComponent implements OnInit, AfterViewInit { public http: HttpClient, public appService: AppService, private router: Router, + private notify: NotificationService ) { } ngOnInit(): void { } @@ -43,9 +45,29 @@ export class TileViewListComponent implements OnInit, AfterViewInit { } goTo(resource: any) { - // TO DO format route - const formatedRoute = this.route.replace(':resId', resource.resId); - console.log(formatedRoute); - // this.router.navigate([formatedRoute]); + const regex = /:\w*/g; + const res = this.route.match(regex); + + let formatedRoute = this.route; + const errors = []; + + if (res !== null) { + res.forEach(elem => { + const value = resource[elem.replace(':', '')]; + + if (value !== undefined) { + formatedRoute = formatedRoute.replace(elem, value); + } else { + errors.push(elem); + } + }); + } + + + if (errors.length === 0) { + this.router.navigate([formatedRoute]); + } else { + this.notify.error(errors + ' not found'); + } } } diff --git a/src/frontend/app/home/dashboard/tile/view/resume/tile-view-resume.component.html b/src/frontend/app/home/dashboard/tile/view/resume/tile-view-resume.component.html index 02ec7be87740927cebb3361534509ef8683c81f6..461aaa750167acc10be669d0dec710972bf140a3 100644 --- a/src/frontend/app/home/dashboard/tile/view/resume/tile-view-resume.component.html +++ b/src/frontend/app/home/dashboard/tile/view/resume/tile-view-resume.component.html @@ -7,5 +7,5 @@ {{resourceLabel}} </span> </div> - <i class="fa {{icon}} tile-icon" color="primary"></i> + <i class="{{icon}} tile-icon" color="primary"></i> </div> \ No newline at end of file diff --git a/src/frontend/app/home/dashboard/tile/view/resume/tile-view-resume.component.ts b/src/frontend/app/home/dashboard/tile/view/resume/tile-view-resume.component.ts index 2aa3fbb9b534e71defc97f077504938f0ad3a1c0..e81d88143c7b3f1de2ae01620de8302f67d8af9c 100644 --- a/src/frontend/app/home/dashboard/tile/view/resume/tile-view-resume.component.ts +++ b/src/frontend/app/home/dashboard/tile/view/resume/tile-view-resume.component.ts @@ -2,6 +2,8 @@ import { Component, OnInit, AfterViewInit, Input } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { TranslateService } from '@ngx-translate/core'; import { AppService } from '@service/app.service'; +import { NotificationService } from '@service/notification/notification.service'; +import { Router } from '@angular/router'; @Component({ selector: 'app-tile-view-resume', @@ -14,14 +16,43 @@ export class TileViewResumeComponent implements OnInit, AfterViewInit { @Input() icon: string = ''; @Input() resourceLabel: string = ''; @Input() route: string = null; + @Input() extraParams: any = {}; constructor( public translate: TranslateService, public http: HttpClient, public appService: AppService, + private router: Router, + private notify: NotificationService ) { } ngOnInit(): void { } ngAfterViewInit(): void { } + + goTo() { + const regex = /:\w*/g; + const res = this.route.match(regex); + + let formatedRoute = this.route; + const errors = []; + + if (res !== null) { + res.forEach(elem => { + const value = this.extraParams[elem.replace(':', '')]; + + if (value !== undefined) { + formatedRoute = formatedRoute.replace(elem, value); + } else { + errors.push(elem); + } + }); + } + + if (errors.length === 0) { + this.router.navigate([formatedRoute]); + } else { + this.notify.error(errors + ' not found'); + } + } } diff --git a/src/lang/lang-fr.json b/src/lang/lang-fr.json index 6187fac320b5a00656df3908f65fdd74bc66ef59..aa3096afc655fd078848db190a8f21c3530a61dc 100644 --- a/src/lang/lang-fr.json +++ b/src/lang/lang-fr.json @@ -2233,7 +2233,7 @@ "rgs_2stars_timestamped": "Clé RGS** + horodatage", "stamp": "Griffe", "errorUserSignType": "Les signataires sans certificat doivent être présent avant les signataires avec certificat.", - "copyRootEntityAddress": "Copier l'adresse existante de l'entité racine", + "copyRootEntityAddress": "Copier la première adresse parente disponible", "noAddressFound": "Aucune adresse trouvée", "searchTemplate": "Modèle de recherche", "chart": "Graphique",