diff --git a/package.json b/package.json index 22b6aa23f9679ea7297b5373ee588e20bb9a3e3d..04dfe60686a2158f72d28c06f9c142e4ece2ea88 100755 --- a/package.json +++ b/package.json @@ -17,22 +17,23 @@ "license": "GPL-3.0", "dependencies": { "@fortawesome/fontawesome-free": "^5.11.2", + "@swimlane/ngx-charts": "^13.0.2", "@tinymce/tinymce-angular": "^3.4.0", "bootstrap": "^3.4.1", "chart.js": "1.1.1", "chosen-js": "^1.8.7", "core-js": "^2.6.9", + "jquery": "^3.4.1", "jquery-typeahead": "^2.11.0", "jquery.nicescroll": "~3.6.8", - "jquery": "^3.4.1", "jstree-bootstrap-theme": "^1.0.1", "ng2-pdf-viewer": "^5.3.4", "ngx-cookie-service": "^2.4.0", "ngx-pipes": "^2.7.3", "pdfjs-dist": "2.2.228", "photoswipe": "^4.1.3", - "tinymce-i18n": "^19.9.17", "tinymce": "^5.1.6", + "tinymce-i18n": "^19.9.17", "tooltipster": "^4.2.7", "uglify-es": "3.2.2", "uglifyjs-webpack-plugin": "2.1.1", diff --git a/src/frontend/app/administration/action/action-administration.component.html b/src/frontend/app/administration/action/action-administration.component.html index 3e74eb6343bac2470226af2bbcb31d335cadbb5d..8f26ea4480ca298598fb011a1b8c184aa00a608a 100755 --- a/src/frontend/app/administration/action/action-administration.component.html +++ b/src/frontend/app/administration/action/action-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> diff --git a/src/frontend/app/administration/action/action-administration.component.ts b/src/frontend/app/administration/action/action-administration.component.ts index 1ae8994fa5044d251bd926abe99705fee7afe07b..66999a208d0c9e39edfdc910d1d2d4b81cfd9a82 100755 --- a/src/frontend/app/administration/action/action-administration.component.ts +++ b/src/frontend/app/administration/action/action-administration.component.ts @@ -4,7 +4,7 @@ import { Router, ActivatedRoute } from '@angular/router'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { MatSidenav } from '@angular/material/sidenav'; -import { HeaderService } from '../../../service/header.service'; +import { HeaderService } from '../../../service/header.service'; import { AppService } from '../../../service/app.service'; import { tap, catchError } from 'rxjs/operators'; import { of } from 'rxjs'; @@ -19,9 +19,7 @@ declare function $j(selector: any): any; }) export class ActionAdministrationComponent implements OnInit { - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; lang: any = LANG; creationMode: boolean; @@ -43,10 +41,10 @@ export class ActionAdministrationComponent implements OnInit { selectStatusId = new FormControl(); constructor( - public http: HttpClient, - private route: ActivatedRoute, - private router: Router, - private notify: NotificationService, + public http: HttpClient, + private route: ActivatedRoute, + private router: Router, + private notify: NotificationService, private headerService: HeaderService, public appService: AppService, public functions: FunctionsService) { } @@ -55,10 +53,9 @@ export class ActionAdministrationComponent implements OnInit { this.loading = true; this.route.params.subscribe(params => { - this.headerService.sideNavLeft = this.sidenavLeft; if (typeof params['id'] == "undefined") { - + this.creationMode = true; this.http.get('../../rest/initAction') @@ -69,7 +66,7 @@ export class ActionAdministrationComponent implements OnInit { this.categoriesList = data.categoriesList; this.statuses = data.statuses.map((status: any) => { return { - id : status.id, + id: status.id, label: status.label_status } }); @@ -81,7 +78,7 @@ export class ActionAdministrationComponent implements OnInit { }); } else { - + this.creationMode = false; this.http.get('../../rest/actions/' + params['id']) @@ -92,7 +89,7 @@ export class ActionAdministrationComponent implements OnInit { this.categoriesList = data.categoriesList; this.statuses = data.statuses.map((status: any) => { return { - id : status.id, + id: status.id, label: status.label_status } }); @@ -101,7 +98,7 @@ export class ActionAdministrationComponent implements OnInit { this.headerService.setHeader(this.lang.actionCreation, data.action.label_action); await this.getCustomFields(); this.loading = false; - if (this.action.actionPageId=='close_mail') { + if (this.action.actionPageId == 'close_mail') { this.customFieldsFormControl = new FormControl({ value: this.action.parameters.requiredFields, disabled: false }); this.selectedFieldsId = this.action.parameters.requiredFields; this.selectedFieldsId.forEach((element: any) => { @@ -111,7 +108,7 @@ export class ActionAdministrationComponent implements OnInit { } }); }); - } else if (this.action.actionPageId=='create_acknowledgement_receipt') { + } else if (this.action.actionPageId == 'create_acknowledgement_receipt') { this.arMode = this.action.parameters.mode; } }); @@ -122,11 +119,11 @@ export class ActionAdministrationComponent implements OnInit { getCustomFields() { this.action.actionPageId = this.selectActionPageId.value; return new Promise((resolve, reject) => { - if (this.action.actionPageId=='close_mail' && this.functions.empty(this.availableCustomFields)) { + if (this.action.actionPageId == 'close_mail' && this.functions.empty(this.availableCustomFields)) { this.http.get('../../rest/customFields').pipe( tap((data: any) => { this.availableCustomFields = data.customFields.map((info: any) => { - info.id = 'indexingCustomField_' + info.id; + info.id = 'indexingCustomField_' + info.id; return info; }); return resolve(true); @@ -161,10 +158,10 @@ export class ActionAdministrationComponent implements OnInit { } onSubmit() { - if (this.action.actionPageId=='close_mail') { - this.action.parameters = { requiredFields: this.selectedFieldsId}; - } else if (this.action.actionPageId=='create_acknowledgement_receipt') { - this.action.parameters = { mode: this.arMode}; + if (this.action.actionPageId == 'close_mail') { + this.action.parameters = { requiredFields: this.selectedFieldsId }; + } else if (this.action.actionPageId == 'create_acknowledgement_receipt') { + this.action.parameters = { mode: this.arMode }; } if (this.creationMode) { this.http.post('../../rest/actions', this.action) diff --git a/src/frontend/app/administration/action/actions-administration.component.html b/src/frontend/app/administration/action/actions-administration.component.html index 4c902e006dd355032505ac2d67bfbb10ad343ffc..c9604ddd0c9b6327db9e7d8a288dee369e70f245 100755 --- a/src/frontend/app/administration/action/actions-administration.component.html +++ b/src/frontend/app/administration/action/actions-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/actions/new"> @@ -13,13 +9,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -37,7 +32,8 @@ <div class="row"> <div class="col-md-6 col-xs-6"> <mat-form-field> - <input matInput (keyup)="applyFilter($event.target.value)" placeholder="{{lang.filterBy}}"> + <input matInput (keyup)="applyFilter($event.target.value)" + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> @@ -47,15 +43,19 @@ </div> <mat-table #table [dataSource]="dataSource" matSort matSortActive="id" matSortDirection="asc"> <ng-container matColumnDef="id"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()">{{lang.id}}</mat-header-cell> - <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()"> {{element.id}} </mat-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()">{{lang.id}}</mat-header-cell> + <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()"> + {{element.id}} </mat-cell> </ng-container> <ng-container matColumnDef="label_action"> <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.actionName}}</mat-header-cell> <mat-cell *matCellDef="let element"> {{element.label_action}} </mat-cell> </ng-container> <ng-container matColumnDef="history"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()">{{lang.actionHistory}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()">{{lang.actionHistory}} + </mat-header-cell> <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()"> <span *ngIf="element.history == 'N'"> {{lang.no}} </span> <span *ngIf="element.history == 'Y'"> {{lang.yes}} </span> @@ -64,17 +64,23 @@ <ng-container matColumnDef="actions"> <mat-header-cell *matHeaderCellDef></mat-header-cell> <mat-cell *matCellDef="let element" style="justify-content: flex-end;"> - <button mat-icon-button color="warn" [disabled]="element.is_system == 'Y'" matTooltip="{{lang.delete}}" (click)="$event.stopPropagation();deleteAction(element)"> + <button mat-icon-button color="warn" [disabled]="element.is_system == 'Y'" + matTooltip="{{lang.delete}}" + (click)="$event.stopPropagation();deleteAction(element)"> <mat-icon class="fa fa-trash-alt fa-2x" aria-hidden="true"></mat-icon> </button> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;" routerLink="/administration/actions/{{row.id}}" style="cursor:pointer;" matTooltip="{{lang.view}}"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumns;" + routerLink="/administration/actions/{{row.id}}" style="cursor:pointer;" + matTooltip="{{lang.view}}"></mat-row> </mat-table> - <div class="mat-paginator" style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">{{actions.length}} {{lang.actions}}</div> + <div class="mat-paginator" + style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> + {{actions.length}} {{lang.actions}}</div> </mat-card> </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/action/actions-administration.component.ts b/src/frontend/app/administration/action/actions-administration.component.ts index 9ab487a0881d297dbaf8ec259becab3a36c51d3d..2fa9945773bcc7674e9eac3276c4c5214b121f9c 100755 --- a/src/frontend/app/administration/action/actions-administration.component.ts +++ b/src/frontend/app/administration/action/actions-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, OnInit } from '@angular/core'; +import { Component, ViewChild, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; @@ -14,13 +14,13 @@ declare function $j(selector: any): any; @Component({ templateUrl: "actions-administration.component.html", - providers: [NotificationService, AppService] + providers: [AppService] }) export class ActionsAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; search: string = null; @@ -42,20 +42,21 @@ export class ActionsAdministrationComponent implements OnInit { return this.functions.filterUnSensitive(template, filter, ['id', 'label_action']); }; } + constructor( public http: HttpClient, private notify: NotificationService, private headerService: HeaderService, public appService: AppService, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } ngOnInit(): void { - - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/administration.module.ts b/src/frontend/app/administration/administration.module.ts index 6f2cfef518bddbcf08c679caddb123fd4d0902bf..db2e7ef2efdf58b9c0a292a5a665911c9e310c95 100755 --- a/src/frontend/app/administration/administration.module.ts +++ b/src/frontend/app/administration/administration.module.ts @@ -3,6 +3,7 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../app-common.module'; import { AdministrationRoutingModule } from './administration-routing.module'; +import { NgxChartsModule } from '@swimlane/ngx-charts'; import { AdministrationComponent } from './home/administration.component'; import { UsersAdministrationComponent, UsersAdministrationRedirectModalComponent } from './user/users-administration.component'; @@ -56,6 +57,7 @@ import { TagAdministrationComponent } from './tag/tag-administratio @NgModule({ imports: [ SharedModule, + NgxChartsModule, AdministrationRoutingModule ], declarations: [ diff --git a/src/frontend/app/administration/basket/basket-administration.component.html b/src/frontend/app/administration/basket/basket-administration.component.html index d0f585e5d8b7a4691ff2b6e439be01913b89e809..9cfcbca983ece0298182874144746a893c5265c8 100755 --- a/src/frontend/app/administration/basket/basket-administration.component.html +++ b/src/frontend/app/administration/basket/basket-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list *ngIf="!creationMode"> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item (click)="linkGroup()"> @@ -15,28 +11,31 @@ <mat-divider></mat-divider> <a mat-list-item disableRipple="true" matTooltip="{{lang.isSearchBasketInfo}}"> <mat-icon color="primary" mat-list-icon> - <mat-slide-toggle [checked]="basket.isSearchBasket" color="primary" (change)="toggleIsSearchBasket(basket);false"></mat-slide-toggle> + <mat-slide-toggle [checked]="basket.isSearchBasket" color="primary" + (change)="toggleIsSearchBasket(basket);false"></mat-slide-toggle> </mat-icon> - <p mat-line [ngStyle]="{'opacity': basket.isSearchBasket ? '' : '0.3'}" (click)="toggleIsSearchBasket(basket);false"> + <p mat-line [ngStyle]="{'opacity': basket.isSearchBasket ? '' : '0.3'}" + (click)="toggleIsSearchBasket(basket);false"> {{lang.isSearchBasket}} </p> </a> <a mat-list-item disableRipple="true" matTooltip="{{lang.basketNotification}}"> <mat-icon color="primary" mat-list-icon> - <mat-slide-toggle [checked]="basket.flagNotif" color="primary" (change)="toggleFlagNotif(basket);false"></mat-slide-toggle> + <mat-slide-toggle [checked]="basket.flagNotif" color="primary" + (change)="toggleFlagNotif(basket);false"></mat-slide-toggle> </mat-icon> - <p mat-line [ngStyle]="{'opacity': basket.flagNotif ? '' : '0.3'}" (click)="toggleFlagNotif(basket);false"> + <p mat-line [ngStyle]="{'opacity': basket.flagNotif ? '' : '0.3'}" + (click)="toggleFlagNotif(basket);false"> {{lang.activateNotification}} </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -56,97 +55,112 @@ <form class="form-horizontal" (ngSubmit)="onSubmit()" #basketForm="ngForm"> <mat-form-field> <input matInput *ngIf="creationMode" name="identifier" placeholder="{{lang.id}}" - [(ngModel)]="basket.id" (blur)="isAvailable()" maxlength="32" pattern="^[\w.-]*$" - required> - <input matInput *ngIf="!creationMode" name="identifier" placeholder="{{lang.id}}" title="{{lang.id}}" - [(ngModel)]="basket.id" required disabled> + [(ngModel)]="basket.id" (blur)="isAvailable()" maxlength="32" + pattern="^[\w.-]*$" required> + <input matInput *ngIf="!creationMode" name="identifier" placeholder="{{lang.id}}" + title="{{lang.id}}" [(ngModel)]="basket.id" required disabled> </mat-form-field> <div class="row"> <div class="col-md-11 col-xs-10"> <mat-form-field> - <input matInput name="label" title="{{lang.label}}" placeholder="{{lang.label}}" - [(ngModel)]="basket.basket_name" maxlength="255" [ngStyle]="{'color': basket.color}" - required> + <input matInput name="label" title="{{lang.label}}" + placeholder="{{lang.label}}" [(ngModel)]="basket.basket_name" + maxlength="255" [ngStyle]="{'color': basket.color}" required> </mat-form-field> </div> <div class="col-md-1 col-xs-2"> <mat-form-field> <input matInput type="color" name="color" matTooltip="{{lang.chooseColor}}" - [(ngModel)]="basket.color"> + [(ngModel)]="basket.color"> </mat-form-field> </div> </div> <mat-form-field> - <input matInput name="description" title="{{lang.description}}" placeholder="{{lang.description}}" - [(ngModel)]="basket.basket_desc" maxlength="255" required> + <input matInput name="description" title="{{lang.description}}" + placeholder="{{lang.description}}" [(ngModel)]="basket.basket_desc" + maxlength="255" required> </mat-form-field> <mat-form-field> - <textarea matInput name="clause" title="{{lang.clause}}" placeholder="{{lang.clause}}" - [(ngModel)]="basket.clause" matTextareaAutosize matAutosizeMinRows="1" required></textarea> - <mat-icon style="cursor:pointer;" color="primary" matSuffix class="fa fa-info-circle" - matTooltip="{{lang.keywordHelper}}" (click)="snav2.toggle()"></mat-icon> + <textarea matInput name="clause" title="{{lang.clause}}" + placeholder="{{lang.clause}}" [(ngModel)]="basket.clause" matTextareaAutosize + matAutosizeMinRows="1" required></textarea> + <mat-icon style="cursor:pointer;" color="primary" matSuffix + class="fa fa-info-circle" matTooltip="{{lang.keywordHelper}}" + (click)="snav2.toggle()"></mat-icon> </mat-form-field> <div id="listOrder"> <div class="row" *ngFor="let columnOrder of orderColumnsSelected;let i = index"> <div class="col-md-5 col-xs-5 text-center"> <mat-form-field> - <mat-select placeholder="{{lang.defaultSort}} {{i+1}}" [(ngModel)]="orderColumnsSelected[i].column" - name="basket_res_order{{i}}" required> - <mat-option *ngFor="let column of orderColumns" [value]="column">{{langVarName[orderColumns.indexOf(column)]}}</mat-option> + <mat-select placeholder="{{lang.defaultSort}} {{i+1}}" + [(ngModel)]="orderColumnsSelected[i].column" + name="basket_res_order{{i}}" required> + <mat-option *ngFor="let column of orderColumns" [value]="column"> + {{langVarName[orderColumns.indexOf(column)]}}</mat-option> </mat-select> </mat-form-field> </div> <div class="col-md-5 col-xs-5 text-center"> <mat-form-field> - <mat-select placeholder="{{lang.orderBy}}" [(ngModel)]="columnOrder.order" - name="order_by_select{{i}}" required> - <mat-option *ngFor="let order of orderByColumns" [value]="order">{{langOrderName[orderByColumns.indexOf(order)]}}</mat-option> + <mat-select placeholder="{{lang.orderBy}}" + [(ngModel)]="columnOrder.order" name="order_by_select{{i}}" + required> + <mat-option *ngFor="let order of orderByColumns" [value]="order"> + {{langOrderName[orderByColumns.indexOf(order)]}}</mat-option> </mat-select> </mat-form-field> </div> <div class="col-md-2 col-xs-2 text-left"> <button [disabled]="orderColumnsSelected.length==1" color="warn" - mat-icon-button type="button" (click)="removeLine(i)"> + mat-icon-button type="button" (click)="removeLine(i)"> <mat-icon class='fa fa-minus-square fa-2x'></mat-icon> </button> - <button *ngIf="orderColumnsSelected.length==(i+1)" [disabled]="orderColumnsSelected.length==2" - color="primary" mat-icon-button type="button" (click)="addLine()"> + <button *ngIf="orderColumnsSelected.length==(i+1)" + [disabled]="orderColumnsSelected.length==2" color="primary" + mat-icon-button type="button" (click)="addLine()"> <mat-icon class='fa fa-plus-square fa-2x'></mat-icon> </button> </div> </div> </div> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button [disabled]="!basketForm.form.valid || orderColumnsSelected.length == 0" - color="primary">{{lang.save}}</button> + <button mat-raised-button + [disabled]="!basketForm.form.valid || orderColumnsSelected.length == 0" + color="primary">{{lang.save}}</button> </div> </form> </mat-tab> <mat-tab *ngFor="let group of basketGroups;let i = index" label="{{group.group_desc}}"> <ng-template mat-tab-label> <span>{{group.group_desc}}</span> - <mat-icon color="warn" class="fa fa-times" matTooltip="{{lang.unlinkGroup}}" (click)="unlinkGroup(i)"></mat-icon> + <mat-icon color="warn" class="fa fa-times" matTooltip="{{lang.unlinkGroup}}" + (click)="unlinkGroup(i)"></mat-icon> </ng-template> <mat-tab-group *ngIf="selectedIndex > 0"> <mat-tab label="{{lang.actions}}"> <div class="col-md-6"> <h5>{{lang.actionChosen}}</h5> <mat-chip-list #chipList class="mat-chip-list-stacked"> - <span *ngFor="let action of group.groupActions | sortBy: 'label_action'" style="width:100%;"> - <mat-chip color="primary" (click)="openSettings(group,action)" matTooltip="id : {{action.id}}" - [ngStyle]="{'font-weight': action.default_action_list == true ? 'bold' : ''}" - style="cursor:pointer;margin:5px;border-radius:0px;display:flex;" *ngIf="action.checked == true" - selectable="true" removable="true" (removed)="unlinkAction(group,action)"> - - <span>{{action.label_action}}</span> - <small *ngIf="action.default_action_list == true">({{lang.default}})</small> - <span style="flex: 1 1 auto;"></span> - <button mat-raised-button [disabled]="action.default_action_list" + <span *ngFor="let action of group.groupActions | sortBy: 'label_action'" + style="width:100%;"> + <mat-chip color="primary" (click)="openSettings(group,action)" + matTooltip="id : {{action.id}}" + [ngStyle]="{'font-weight': action.default_action_list == true ? 'bold' : ''}" + style="cursor:pointer;margin:5px;border-radius:0px;display:flex;" + *ngIf="action.checked == true" selectable="true" removable="true" + (removed)="unlinkAction(group,action)"> + + <span>{{action.label_action}}</span> + <small + *ngIf="action.default_action_list == true">({{lang.default}})</small> + <span style="flex: 1 1 auto;"></span> + <button mat-raised-button [disabled]="action.default_action_list" (click)="$event.stopPropagation();setDefaultAction(group,action)">{{lang.setByDefault}}</button> - <mat-icon matTooltip="{{lang.delete}}" matChipRemove color="warn" *ngIf="action.default_action_list != true" - class="fa fa-times" (click)="$event.stopPropagation();"></mat-icon> - </mat-chip> - </span> + <mat-icon matTooltip="{{lang.delete}}" matChipRemove color="warn" + *ngIf="action.default_action_list != true" class="fa fa-times" + (click)="$event.stopPropagation();"></mat-icon> + </mat-chip> + </span> </mat-chip-list> </div> <div class="col-md-6"> @@ -160,38 +174,45 @@ <div> <mat-form-field> <input matInput (keyup)="applyFilter($event.target.value)" - placeholder="{{lang.filterBy}}"> + placeholder="{{lang.filterBy}}"> </mat-form-field> <mat-table #table [dataSource]="dataSource"> <ng-container matColumnDef="label_action"> <mat-header-cell *matHeaderCellDef></mat-header-cell> - <mat-cell *matCellDef="let element" style="flex:6;" matTooltip="id : {{element.id}}"> - <mat-checkbox color="primary" [disabled]="element.default_action_list==true" - (change)="addAction(group)" [(ngModel)]="element.checked"><span>{{element.label_action}}</span></mat-checkbox> + <mat-cell *matCellDef="let element" style="flex:6;" + matTooltip="id : {{element.id}}"> + <mat-checkbox color="primary" + [disabled]="element.default_action_list==true" + (change)="addAction(group)" + [(ngModel)]="element.checked"> + <span>{{element.label_action}}</span></mat-checkbox> </mat-cell> </ng-container> <ng-container matColumnDef="actions"> <mat-header-cell *matHeaderCellDef></mat-header-cell> <mat-cell *matCellDef="let element" style="text-align:right" - matTooltip="id : {{element.id}}"> + matTooltip="id : {{element.id}}"> <button mat-icon-button [matMenuTriggerFor]="menu" - [disabled]="!element.checked"> + [disabled]="!element.checked"> <mat-icon class="fa fa-bars"></mat-icon> </button> <mat-menu #menu="matMenu"> - <button mat-menu-item [disabled]="element.default_action_list==true" - (click)="setDefaultAction(group,element)"> + <button mat-menu-item + [disabled]="element.default_action_list==true" + (click)="setDefaultAction(group,element)"> <mat-icon class="fa fa-check-circle"></mat-icon> <span>{{lang.defaultAction}}</span> </button> - <button mat-menu-item (click)="openSettings(group,element)"> + <button mat-menu-item + (click)="openSettings(group,element)"> <mat-icon class="fa fa-cogs"></mat-icon> <span>{{lang.moreOptions}}</span> </button> </mat-menu> </mat-cell> </ng-container> - <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumns;"> + </mat-row> </mat-table> </div> </mat-expansion-panel> @@ -210,7 +231,7 @@ </mat-sidenav-content> <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - fixedTopGap="56" position='end' [opened]="appService.getViewMode() ? false : false"> + fixedTopGap="56" position='end' [opened]="appService.getViewMode() ? false : false"> <mat-nav-list> <h3 mat-subheader>{{lang.keywordHelp}}</h3> @@ -246,4 +267,4 @@ </mat-list> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/basket/basket-administration.component.ts b/src/frontend/app/administration/basket/basket-administration.component.ts index 9330a3ea9260afe58423e38330616ec928c17533..53ebc9e8b9b3460903674cabbf24bd0837171cb9 100755 --- a/src/frontend/app/administration/basket/basket-administration.component.ts +++ b/src/frontend/app/administration/basket/basket-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Inject, ViewChild, ElementRef } from '@angular/core'; +import { Component, OnInit, Inject, ViewChild, ElementRef, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Router, ActivatedRoute } from '@angular/router'; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; @@ -9,7 +9,6 @@ import { MatTableDataSource } from '@angular/material/table'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { HeaderService } from '../../../service/header.service'; -import { FormControl } from '@angular/forms'; import { AppService } from '../../../service/app.service'; declare function $j(selector: any): any; @@ -17,12 +16,12 @@ declare function $j(selector: any): any; @Component({ templateUrl: "basket-administration.component.html", styleUrls: ['basket-administration.component.scss'], - providers: [NotificationService, AppService] + providers: [AppService] }) export class BasketAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; dialogRef: MatDialogRef<any>; @@ -66,14 +65,14 @@ export class BasketAdministrationComponent implements OnInit { private notify: NotificationService, public dialog: MatDialog, private headerService: HeaderService, - public appService: AppService) { + public appService: AppService, + private viewContainerRef: ViewContainerRef) { $j("link[href='merged_css.php']").remove(); } ngOnInit(): void { - this.loading = true; - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.route.params.subscribe((params: any) => { if (typeof params['id'] == "undefined") { diff --git a/src/frontend/app/administration/basket/baskets-administration.component.html b/src/frontend/app/administration/basket/baskets-administration.component.html index 30274a75ac5b4d72d38767c0a1632ac61824cdc4..d8df5fccf05fc5f58f3ebef713d714558bc5492d 100755 --- a/src/frontend/app/administration/basket/baskets-administration.component.html +++ b/src/frontend/app/administration/basket/baskets-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/baskets/new"> @@ -19,13 +15,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -43,7 +38,8 @@ <div class="row"> <div class="col-md-6 col-xs-6"> <mat-form-field> - <input matInput (keyup)="applyFilter($event.target.value)" placeholder="{{lang.filterBy}}"> + <input matInput (keyup)="applyFilter($event.target.value)" + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> @@ -51,47 +47,58 @@ </mat-paginator> </div> </div> - <mat-table #table [dataSource]="dataSource" matSort matSortActive="basket_id" matSortDirection="asc"> + <mat-table #table [dataSource]="dataSource" matSort matSortActive="basket_id" + matSortDirection="asc"> <ng-container matColumnDef="basket_id"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()">{{lang.id}}</mat-header-cell> - <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()"> {{element.basket_id}} </mat-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()">{{lang.id}}</mat-header-cell> + <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()"> + {{element.basket_id}} </mat-cell> </ng-container> <ng-container matColumnDef="basket_name"> <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.label}}</mat-header-cell> <mat-cell *matCellDef="let element"> {{element.basket_name}} </mat-cell> </ng-container> <ng-container matColumnDef="basket_desc"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()">{{lang.description}}</mat-header-cell> - <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()"> {{element.basket_desc}} </mat-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()">{{lang.description}} + </mat-header-cell> + <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()"> + {{element.basket_desc}} </mat-cell> </ng-container> <ng-container matColumnDef="actions"> <mat-header-cell *matHeaderCellDef></mat-header-cell> <mat-cell *matCellDef="let element" style="justify-content: flex-end;"> - <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" (click)="$event.stopPropagation();delete(element)"> + <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" + (click)="$event.stopPropagation();delete(element)"> <mat-icon class="fa fa-trash-alt fa-2x" aria-hidden="true"></mat-icon> </button> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;" routerLink="/administration/baskets/{{row.basket_id}}" style="cursor:pointer;" matTooltip="{{lang.view}}"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumns;" + routerLink="/administration/baskets/{{row.basket_id}}" style="cursor:pointer;" + matTooltip="{{lang.view}}"></mat-row> </mat-table> - <div class="mat-paginator" style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">{{baskets.length}} {{lang.baskets}}</div> + <div class="mat-paginator" + style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> + {{baskets.length}} {{lang.baskets}}</div> </mat-card> </div> </div> </mat-sidenav-content> - <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" fixedTopGap="56" - position='end' [opened]="appService.getViewMode() ? false : false"> + <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" + fixedTopGap="56" position='end' [opened]="appService.getViewMode() ? false : false"> <p style="font-size:15px;padding:10px"> {{lang.basketHelpDesc}} </p> <mat-list> - <span dnd-sortable-container [dropZones]="['boxers-zone']" [sortableData]="basketsOrder"> - <mat-list-item disableRipple="true" *ngFor="let basket of basketsOrder;let i = index" title="{{lang.move}}" dnd-sortable - [sortableIndex]="i" (onDropSuccess)="updateBasketOrder(basket)"> - <mat-icon color="primary" mat-list-icon class="fa fa-inbox"></mat-icon> - <p mat-line>{{i+1}} - {{basket.basket_name}}</p> - </mat-list-item> - </span> + <span dnd-sortable-container [dropZones]="['boxers-zone']" [sortableData]="basketsOrder"> + <mat-list-item disableRipple="true" *ngFor="let basket of basketsOrder;let i = index" + title="{{lang.move}}" dnd-sortable [sortableIndex]="i" (onDropSuccess)="updateBasketOrder(basket)"> + <mat-icon color="primary" mat-list-icon class="fa fa-inbox"></mat-icon> + <p mat-line>{{i+1}} - {{basket.basket_name}}</p> + </mat-list-item> + </span> </mat-list> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/basket/baskets-administration.component.ts b/src/frontend/app/administration/basket/baskets-administration.component.ts index dc42ffa1c68fb9db5f9fabfbbaf9896e79c0948e..070b78a42c4b515091caaa2e1df1c871746d4e04 100755 --- a/src/frontend/app/administration/basket/baskets-administration.component.ts +++ b/src/frontend/app/administration/basket/baskets-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ViewContainerRef, TemplateRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { MatPaginator } from '@angular/material/paginator'; @@ -6,29 +6,29 @@ import { MatSidenav } from '@angular/material/sidenav'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { NotificationService } from '../../notification.service'; -import { HeaderService } from '../../../service/header.service'; +import { HeaderService } from '../../../service/header.service'; import { AppService } from '../../../service/app.service'; -import {FunctionsService} from "../../../service/functions.service"; +import { FunctionsService } from "../../../service/functions.service"; declare function $j(selector: any): any; @Component({ templateUrl: "baskets-administration.component.html", - providers: [NotificationService, AppService] + providers: [AppService] }) export class BasketsAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; - lang : any = LANG; - loading : boolean = false; + lang: any = LANG; + loading: boolean = false; - baskets : any[] = []; - basketsOrder : any[] = []; + baskets: any[] = []; + basketsOrder: any[] = []; - displayedColumns = ['basket_id', 'basket_name', 'basket_desc', 'actions']; - dataSource : any; + displayedColumns = ['basket_id', 'basket_name', 'basket_desc', 'actions']; + dataSource: any; @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator; @ViewChild(MatSort, { static: false }) sort: MatSort; @@ -42,18 +42,19 @@ export class BasketsAdministrationComponent implements OnInit { } constructor( - public http: HttpClient, - private notify: NotificationService, + public http: HttpClient, + private notify: NotificationService, private headerService: HeaderService, public appService: AppService, - public functions: FunctionsService - ) { - $j("link[href='merged_css.php']").remove(); + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef + ) { + $j("link[href='merged_css.php']").remove(); } ngOnInit(): void { + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.headerService.setHeader(this.lang.administration + ' ' + this.lang.baskets); - this.headerService.sideNavLeft = this.sidenavLeft; this.loading = true; diff --git a/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.html b/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.html index 74a6b510758d79a5d83972f362ae7d87a06807cd..f06f0147eb0dc985d96e06ddbc9fe4eed41b10af 100644 --- a/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.html +++ b/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <a mat-list-item *ngFor="let menu of subMenus" [class.active]="menu.current" [routerLink]="menu.route"> <mat-icon color="primary" mat-list-icon [class]="menu.icon"></mat-icon> @@ -12,13 +8,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -171,4 +166,4 @@ </mat-tab> </mat-tab-group> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.ts b/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.ts index 8ccb92eac4774936a75d2796240910a7630b2099..bfa96464114224b858dd766453a03a2770ee1f52 100644 --- a/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.ts +++ b/src/frontend/app/administration/contact/customField/contacts-custom-fields-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../../translate.component'; import { NotificationService } from '../../../notification.service'; @@ -22,8 +22,8 @@ import { SortPipe } from '../../../../plugins/sorting.pipe'; export class ContactsCustomFieldsAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; @@ -98,7 +98,8 @@ export class ContactsCustomFieldsAdministrationComponent implements OnInit { public dialog: MatDialog, private headerService: HeaderService, public appService: AppService, - private sortPipe: SortPipe + private sortPipe: SortPipe, + private viewContainerRef: ViewContainerRef ) { } @@ -106,7 +107,7 @@ export class ContactsCustomFieldsAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.customFields + ' ' + this.lang.contacts); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.http.get("../../rest/contactsCustomFields").pipe( // TO FIX DATA BINDING SIMPLE ARRAY VALUES diff --git a/src/frontend/app/administration/contact/group/contacts-group-administration.component.html b/src/frontend/app/administration/contact/group/contacts-group-administration.component.html index 33535f2196acbb54cea7b08e75b132439221d5c3..6c36cff0d9c32d0ead6670097ab3f9690aeb4cd5 100644 --- a/src/frontend/app/administration/contact/group/contacts-group-administration.component.html +++ b/src/frontend/app/administration/contact/group/contacts-group-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <a mat-list-item *ngFor="let menu of subMenus" [class.active]="menu.current" [routerLink]="menu.route"> <mat-icon color="primary" mat-list-icon [class]="menu.icon"></mat-icon> @@ -12,13 +8,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -40,8 +35,8 @@ <div class="col-sm-12"> <mat-form-field> <input matInput [(ngModel)]="contactsGroup.label" required name="label" - id="label" title="{{lang.label}}" type="text" placeholder="{{lang.label}}" - maxlength="32"> + id="label" title="{{lang.label}}" type="text" + placeholder="{{lang.label}}" maxlength="32"> </mat-form-field> </div> </div> @@ -49,8 +44,8 @@ <div class="col-sm-12"> <mat-form-field> <input matInput [(ngModel)]="contactsGroup.description" required - name="description" id="description" title="{{lang.description}}" type="text" - placeholder="{{lang.description}}" maxlength="255"> + name="description" id="description" title="{{lang.description}}" + type="text" placeholder="{{lang.description}}" maxlength="255"> </mat-form-field> </div> </div> @@ -86,7 +81,8 @@ [innerHTML]="lang.limitDataReached_1000"></div> </div> <div class="col-md-6 col-xs-6"> - <mat-paginator #paginatorContactList [length]="0" [hidePageSize]="true" [pageSize]="10"> + <mat-paginator #paginatorContactList [length]="0" [hidePageSize]="true" + [pageSize]="10"> </mat-paginator> </div> </div> @@ -108,11 +104,13 @@ </mat-cell> </ng-container> <ng-container matColumnDef="contact"> - <mat-header-cell *matHeaderCellDef style="flex:3;">{{lang.contact}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef style="flex:3;">{{lang.contact}} + </mat-header-cell> <mat-cell *matCellDef="let element" style="flex:3;"> {{element.contact}} </mat-cell> </ng-container> <ng-container matColumnDef="address"> - <mat-header-cell *matHeaderCellDef style="flex:3;">{{lang.address}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef style="flex:3;">{{lang.address}} + </mat-header-cell> <mat-cell *matCellDef="let element" style="flex:3;"> {{element.address}} </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> @@ -135,7 +133,8 @@ </div> </mat-sidenav-content> <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - position='end' [opened]="appService.getViewMode() || creationMode ? false : true" style="overflow-x:hidden;width:40%;"> + position='end' [opened]="appService.getViewMode() || creationMode ? false : true" + style="overflow-x:hidden;width:40%;"> <mat-list> <h3 mat-subheader>{{nbContact}} {{lang.relatedContacts}} : </h3> </mat-list> @@ -175,4 +174,4 @@ <mat-row *matRowDef="let element; columns: displayedColumnsAdded;"></mat-row> </mat-table> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/contact/group/contacts-group-administration.component.ts b/src/frontend/app/administration/contact/group/contacts-group-administration.component.ts index 3f99967472cc29fed637cf6ae42eea22cf6419e9..2a5bbc615c6931d406617cf2bb10954232b50bac 100644 --- a/src/frontend/app/administration/contact/group/contacts-group-administration.component.ts +++ b/src/frontend/app/administration/contact/group/contacts-group-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Router, ActivatedRoute } from '@angular/router'; import { LANG } from '../../../translate.component'; @@ -24,8 +24,8 @@ declare function $j(selector: any): any; }) export class ContactsGroupAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; @@ -102,7 +102,8 @@ export class ContactsGroupAdministrationComponent implements OnInit { private router: Router, private notify: NotificationService, private headerService: HeaderService, - public appService: AppService + public appService: AppService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); @@ -123,7 +124,7 @@ export class ContactsGroupAdministrationComponent implements OnInit { this.loading = true; this.route.params.subscribe(params => { - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); if (typeof params['id'] == "undefined") { this.headerService.setHeader(this.lang.contactGroupCreation); diff --git a/src/frontend/app/administration/contact/group/contacts-groups-administration.component.html b/src/frontend/app/administration/contact/group/contacts-groups-administration.component.html index 78077e51756c9e32aeebcae894bace75624b4fb7..2e2207f94e8040c2e5a29b8fcc54f8213766f715 100644 --- a/src/frontend/app/administration/contact/group/contacts-groups-administration.component.html +++ b/src/frontend/app/administration/contact/group/contacts-groups-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/contacts/contacts-groups/new"> @@ -22,13 +18,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -117,4 +112,4 @@ <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" position='end'> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/contact/group/contacts-groups-administration.component.ts b/src/frontend/app/administration/contact/group/contacts-groups-administration.component.ts index 1ebc50784de3ed673d762e98e990b7eb5ba4b95a..217190edab6c21b2e225c1ddbab2cf4eb31c76b9 100644 --- a/src/frontend/app/administration/contact/group/contacts-groups-administration.component.ts +++ b/src/frontend/app/administration/contact/group/contacts-groups-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, OnInit } from '@angular/core'; +import { Component, ViewChild, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../../translate.component'; import { NotificationService } from '../../../notification.service'; @@ -22,8 +22,8 @@ declare function $j(selector: any): any; export class ContactsGroupsAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; search: string = null; @@ -78,14 +78,15 @@ export class ContactsGroupsAdministrationComponent implements OnInit { private notify: NotificationService, private headerService: HeaderService, public appService: AppService, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.contactsGroups); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/contact/list/contacts-list-administration.component.html b/src/frontend/app/administration/contact/list/contacts-list-administration.component.html index 832319c4dedaf624f1616e4b22e4907c0fea25ed..79a9dfbb13b93d362e9faeb8e8cdf83cac8edc80 100644 --- a/src/frontend/app/administration/contact/list/contacts-list-administration.component.html +++ b/src/frontend/app/administration/contact/list/contacts-list-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/contacts/list/new"> @@ -22,13 +18,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -50,8 +45,8 @@ </mat-form-field> </div> <div class="table-head-tool"> - <mat-paginator #paginatorContactList [length]="resultsLength" [hidePageSize]="true" [pageSize]="10" - class="paginatorResultList"></mat-paginator> + <mat-paginator #paginatorContactList [length]="resultsLength" [hidePageSize]="true" + [pageSize]="10" class="paginatorResultList"></mat-paginator> </div> </div> <div style="height:90%;overflow:auto;position:absolute;width:100%;"> @@ -61,8 +56,10 @@ <mat-header-cell *matHeaderCellDef style="flex: initial;width: 60px;" [class.hide-for-mobile]="appService.getViewMode()"> </mat-header-cell> - <mat-cell mat-cell *matCellDef="let element" style="flex: initial;width: 60px;" [class.hide-for-mobile]="appService.getViewMode()"> - <i class="fas fa-circle threshold_{{element.filling.thresholdLevel}}" [title]="lang.contactFilledTo + ' ' + element.filling.rate + '%'"></i> + <mat-cell mat-cell *matCellDef="let element" style="flex: initial;width: 60px;" + [class.hide-for-mobile]="appService.getViewMode()"> + <i class="fas fa-circle threshold_{{element.filling.thresholdLevel}}" + [title]="lang.contactFilledTo + ' ' + element.filling.rate + '%'"></i> </mat-cell> </ng-container> <ng-container matColumnDef="firstname"> @@ -82,9 +79,11 @@ {{element.company}} </mat-cell> </ng-container> <ng-container matColumnDef="formatedAddress"> - <mat-header-cell *matHeaderCellDef style="flex: 2;" [class.hide-for-mobile]="appService.getViewMode()"> + <mat-header-cell *matHeaderCellDef style="flex: 2;" + [class.hide-for-mobile]="appService.getViewMode()"> {{lang.address}}</mat-header-cell> - <mat-cell *matCellDef="let element" style="flex: 2;" [class.hide-for-mobile]="appService.getViewMode()"> + <mat-cell *matCellDef="let element" style="flex: 2;" + [class.hide-for-mobile]="appService.getViewMode()"> {{element.formatedAddress}} </mat-cell> </ng-container> <ng-container matColumnDef="actions"> @@ -120,4 +119,4 @@ </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts b/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts index e465f80f897c767a0c54f81c27c74f1b8a24a7fd..db1f0918d95ba14a353426e556925b93b1f4addb 100644 --- a/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts +++ b/src/frontend/app/administration/contact/list/contacts-list-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, EventEmitter, Inject } from '@angular/core'; +import { Component, OnInit, ViewChild, EventEmitter, Inject, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../../translate.component'; import { NotificationService } from '../../../notification.service'; @@ -20,8 +20,8 @@ import { FunctionsService } from '../../../../service/functions.service'; }) export class ContactsListAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; loading: boolean = false; @@ -79,10 +79,12 @@ export class ContactsListAdministrationComponent implements OnInit { private headerService: HeaderService, public appService: AppService, public dialog: MatDialog, - public functions: FunctionsService) { } + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef) { } + ngOnInit(): void { - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; this.initContactList(); this.initAutocompleteContacts(); diff --git a/src/frontend/app/administration/contact/page/contacts-page-administration.component.html b/src/frontend/app/administration/contact/page/contacts-page-administration.component.html index 8469a6804621f0736fa871954dd8354a4c2e49d5..9ac2a34db787fd9eb8b8fc07c1facd2de7836bb3 100644 --- a/src/frontend/app/administration/contact/page/contacts-page-administration.component.html +++ b/src/frontend/app/administration/contact/page/contacts-page-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <a mat-list-item *ngFor="let menu of subMenus" [class.active]="menu.current" [routerLink]="menu.route"> <mat-icon color="primary" mat-list-icon [class]="menu.icon"></mat-icon> @@ -12,12 +8,12 @@ </p> </a> </mat-nav-list> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> diff --git a/src/frontend/app/administration/contact/page/contacts-page-administration.component.ts b/src/frontend/app/administration/contact/page/contacts-page-administration.component.ts index 78cf757945f81f1295375ecb9b9ddcefa47d3ebe..311c9e4e7a7921e9a590766f97b8015571ba7503 100644 --- a/src/frontend/app/administration/contact/page/contacts-page-administration.component.ts +++ b/src/frontend/app/administration/contact/page/contacts-page-administration.component.ts @@ -1,8 +1,7 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../../translate.component'; import { HeaderService } from '../../../../service/header.service'; -import { MatSidenav } from '@angular/material/sidenav'; import { AppService } from '../../../../service/app.service'; import { MatDialog } from '@angular/material'; import { ActivatedRoute, Router } from '@angular/router'; @@ -14,8 +13,7 @@ import { ActivatedRoute, Router } from '@angular/router'; }) export class ContactsPageAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; loading: boolean = false; @@ -57,7 +55,8 @@ export class ContactsPageAdministrationComponent implements OnInit { private router: Router, private headerService: HeaderService, public appService: AppService, - public dialog: MatDialog) { } + public dialog: MatDialog, + private viewContainerRef: ViewContainerRef) { } ngOnInit(): void { @@ -65,7 +64,7 @@ export class ContactsPageAdministrationComponent implements OnInit { this.route.params.subscribe((params: any) => { - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); if (typeof params['id'] == "undefined") { this.headerService.setHeader(this.lang.contactCreation); diff --git a/src/frontend/app/administration/contact/page/form/contacts-form.component.ts b/src/frontend/app/administration/contact/page/form/contacts-form.component.ts index 5a9bb7396c61bebc0cc0c05ea6d1a10d59d1591f..620b7ed4f4dd3b84e4b74b332889f67e58e78f5d 100644 --- a/src/frontend/app/administration/contact/page/form/contacts-form.component.ts +++ b/src/frontend/app/administration/contact/page/form/contacts-form.component.ts @@ -40,7 +40,6 @@ declare var angularGlobals: any; }) export class ContactsFormComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; diff --git a/src/frontend/app/administration/contact/parameter/contacts-parameters-administration.component.html b/src/frontend/app/administration/contact/parameter/contacts-parameters-administration.component.html index d0ac8a4fc3efcd29c0e31122240548ce428f1d70..ae3c03c155bb948aace2a393df7c7ad674be85f2 100644 --- a/src/frontend/app/administration/contact/parameter/contacts-parameters-administration.component.html +++ b/src/frontend/app/administration/contact/parameter/contacts-parameters-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item disableRipple="true"> @@ -27,13 +23,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -156,4 +151,4 @@ </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/contact/parameter/contacts-parameters-administration.component.ts b/src/frontend/app/administration/contact/parameter/contacts-parameters-administration.component.ts index 0aa3e9aad5328e657ecbb245856d3900e2a2eed5..f85fbc0edf8c5453877c7d4b7c6a208eb725a165 100644 --- a/src/frontend/app/administration/contact/parameter/contacts-parameters-administration.component.ts +++ b/src/frontend/app/administration/contact/parameter/contacts-parameters-administration.component.ts @@ -1,9 +1,8 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../../translate.component'; import { NotificationService } from '../../../notification.service'; import { HeaderService } from '../../../../service/header.service'; -import { MatSidenav } from '@angular/material/sidenav'; import { AppService } from '../../../../service/app.service'; import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material'; @@ -16,8 +15,7 @@ declare function $j(selector: any): any; }) export class ContactsParametersAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; @@ -75,7 +73,8 @@ export class ContactsParametersAdministrationComponent implements OnInit { public http: HttpClient, private notify: NotificationService, private headerService: HeaderService, - public appService: AppService) { + public appService: AppService, + private viewContainerRef: ViewContainerRef) { $j("link[href='merged_css.php']").remove(); } @@ -84,7 +83,7 @@ export class ContactsParametersAdministrationComponent implements OnInit { this.loading = true; this.headerService.setHeader(this.lang.contactsParameters); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.http.get('../../rest/contactsParameters') .subscribe((data: any) => { diff --git a/src/frontend/app/administration/customField/custom-fields-administration.component.html b/src/frontend/app/administration/customField/custom-fields-administration.component.html index 522f7b262d2b056a29e091690b884d1174d45f35..55d5903e342ab3480a1e1ac02ee524e28046cd83 100644 --- a/src/frontend/app/administration/customField/custom-fields-administration.component.html +++ b/src/frontend/app/administration/customField/custom-fields-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> diff --git a/src/frontend/app/administration/customField/custom-fields-administration.component.ts b/src/frontend/app/administration/customField/custom-fields-administration.component.ts index 5b822f9f0a877ec708da99c97418af3572642bae..37c6666e31c8c907bc7a8c90068696f00b75ffab 100644 --- a/src/frontend/app/administration/customField/custom-fields-administration.component.ts +++ b/src/frontend/app/administration/customField/custom-fields-administration.component.ts @@ -24,7 +24,6 @@ declare function $j(selector: any): any; export class CustomFieldsAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; lang: any = LANG; @@ -85,8 +84,6 @@ export class CustomFieldsAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.customFields); - this.headerService.sideNavLeft = this.sidenavLeft; - this.http.get("../../rest/customFields").pipe( // TO FIX DATA BINDING SIMPLE ARRAY VALUES map((data: any) => { diff --git a/src/frontend/app/administration/diffusionModel/diffusionModel-administration.component.html b/src/frontend/app/administration/diffusionModel/diffusionModel-administration.component.html index 048316533f78bca3728f27ffd46872fee28f668f..5ec064f8b82ab5b96bf4fb485eac59fd2d5213c5 100755 --- a/src/frontend/app/administration/diffusionModel/diffusionModel-administration.component.html +++ b/src/frontend/app/administration/diffusionModel/diffusionModel-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -29,7 +23,7 @@ <form (ngSubmit)="onSubmit()" #diffusionModelForm="ngForm"> <mat-form-field> <mat-select id="type" name="type" placeholder="{{lang.diffusionType}}" - [(ngModel)]="diffusionModel.type" [disabled]="!creationMode"> + [(ngModel)]="diffusionModel.type" [disabled]="!creationMode"> <mat-option *ngFor="let itemType of this.itemTypeList" [value]="itemType.id"> {{ itemType.label }} </mat-option> @@ -37,18 +31,19 @@ </mat-form-field> <mat-form-field> <input matInput name="title" title="{{lang.label}}" placeholder="{{lang.label}}" - [(ngModel)]="diffusionModel.title" maxlength="255" required> + [(ngModel)]="diffusionModel.title" maxlength="255" required> </mat-form-field> <mat-form-field> - <textarea matInput name="description" title="{{lang.description}}" - placeholder="{{lang.description}}" [(ngModel)]="diffusionModel.description" - matTextareaAutosize matAutosizeMinRows="1" matAutosizeMaxRows="5" - maxlength="255"></textarea> + <textarea matInput name="description" title="{{lang.description}}" + placeholder="{{lang.description}}" [(ngModel)]="diffusionModel.description" + matTextareaAutosize matAutosizeMinRows="1" matAutosizeMaxRows="5" + maxlength="255"></textarea> </mat-form-field> <div class="col-md-12 text-center" style="padding:10px;"> <button mat-raised-button [disabled]="!isValidForm()" - color="primary">{{lang.save}}</button> - <button mat-raised-button *ngIf="!creationMode" type="button" color="default" (click)="cancelModification()">{{lang.cancel}}</button> + color="primary">{{lang.save}}</button> + <button mat-raised-button *ngIf="!creationMode" type="button" color="default" + (click)="cancelModification()">{{lang.cancel}}</button> </div> </form> </mat-tab> @@ -57,22 +52,17 @@ </div> </div> </mat-sidenav-content> - - <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" - [fixedInViewport]="appService.getViewMode()" fixedTopGap="56" position='end' - [opened]="!appService.getViewMode()" class="col-md-4 col-xs-11"> - + <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" + fixedTopGap="56" position='end' [opened]="!appService.getViewMode()" class="col-md-4 col-xs-11"> <mat-nav-list> <mat-tab-group> <mat-tab label="{{lang[diffusionModel.type]}}"> - <app-visa-workflow *ngIf="diffusionModel.type === 'visaCircuit'" [showListModels]="false" [showComment]="false" [adminMode]="true" - #appVisaWorkflow></app-visa-workflow> - <app-avis-workflow *ngIf="diffusionModel.type === 'opinionCircuit'" [showListModels]="false" [adminMode]="true" - #appAvisWorkflow></app-avis-workflow> + <app-visa-workflow *ngIf="diffusionModel.type === 'visaCircuit'" [showListModels]="false" + [showComment]="false" [adminMode]="true" #appVisaWorkflow></app-visa-workflow> + <app-avis-workflow *ngIf="diffusionModel.type === 'opinionCircuit'" [showListModels]="false" + [adminMode]="true" #appAvisWorkflow></app-avis-workflow> </mat-tab> </mat-tab-group> </mat-nav-list> </mat-sidenav> - -</mat-sidenav-container> - +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/diffusionModel/diffusionModel-administration.component.ts b/src/frontend/app/administration/diffusionModel/diffusionModel-administration.component.ts index a40b1344afb45306bac15504d7f1cc9c52919288..e8131e281551d244de35d5dce85b508d83a582e7 100755 --- a/src/frontend/app/administration/diffusionModel/diffusionModel-administration.component.ts +++ b/src/frontend/app/administration/diffusionModel/diffusionModel-administration.component.ts @@ -18,7 +18,6 @@ import { AvisWorkflowComponent } from '../../avis/avis-workflow.component'; }) export class DiffusionModelAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; lang: any = LANG; @@ -62,8 +61,6 @@ export class DiffusionModelAdministrationComponent implements OnInit { this.loading = true; this.route.params.subscribe(async params => { - - this.headerService.sideNavLeft = this.sidenavLeft; if (typeof params['id'] == "undefined") { this.headerService.setHeader(this.lang.diffusionModelCreation); diff --git a/src/frontend/app/administration/diffusionModel/diffusionModels-administration.component.html b/src/frontend/app/administration/diffusionModel/diffusionModels-administration.component.html index 029f4c2ba77d4d34a86dbe6ece3265bdadbe92fb..5773fff0d3973a73abcc06670d19a2a896d9abc4 100755 --- a/src/frontend/app/administration/diffusionModel/diffusionModels-administration.component.html +++ b/src/frontend/app/administration/diffusionModel/diffusionModels-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/diffusionModels/new"> @@ -13,13 +9,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> diff --git a/src/frontend/app/administration/diffusionModel/diffusionModels-administration.component.ts b/src/frontend/app/administration/diffusionModel/diffusionModels-administration.component.ts index 43398eef0ce4eefdcbb768c8d489953871ebdfee..7383779cac778d8b6f467aabc030660bcac2f4e7 100755 --- a/src/frontend/app/administration/diffusionModel/diffusionModels-administration.component.ts +++ b/src/frontend/app/administration/diffusionModel/diffusionModels-administration.component.ts @@ -1,11 +1,10 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { HeaderService } from '../../../service/header.service'; -import { MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { MatDialog } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; -import { MatSidenav } from '@angular/material/sidenav'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { AppService } from '../../../service/app.service'; @@ -22,8 +21,7 @@ import {LatinisePipe} from "ngx-pipes"; }) export class DiffusionModelsAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; loading: boolean = false; @@ -62,13 +60,14 @@ export class DiffusionModelsAdministrationComponent implements OnInit { private headerService: HeaderService, public appService: AppService, public functions: FunctionsService, - private latinisePipe: LatinisePipe + private latinisePipe: LatinisePipe, + private viewContainerRef: ViewContainerRef ) { } async ngOnInit(): Promise<void> { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.diffusionModels); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/docserver/docserver-administration.component.html b/src/frontend/app/administration/docserver/docserver-administration.component.html index 1be28d74043a370923b9b8b62c42032ef442ebe6..9c2891936189a65c70d81581a3feec5734ecc1ab 100755 --- a/src/frontend/app/administration/docserver/docserver-administration.component.html +++ b/src/frontend/app/administration/docserver/docserver-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -28,23 +22,28 @@ <div class="row" style="margin-top: 10px;"> <div class="col-md-12"> <mat-form-field> - <mat-select required name="docserver_type" id="docserver_type" title="{{lang.docserverType}}" placeholder="{{lang.docserverType}}" - [(ngModel)]="docserver.docserver_type_id"> - <mat-option *ngFor="let docserverType of this.docserversTypes" [value]="docserverType.docserver_type_id"> + <mat-select required name="docserver_type" id="docserver_type" + title="{{lang.docserverType}}" placeholder="{{lang.docserverType}}" + [(ngModel)]="docserver.docserver_type_id"> + <mat-option *ngFor="let docserverType of this.docserversTypes" + [value]="docserverType.docserver_type_id"> {{docserverType.docserver_type_label}} </mat-option> </mat-select> </mat-form-field> <mat-form-field> - <input matInput required name="identifier" id="identifier" title="{{lang.id}}" type="text" placeholder="{{lang.id}}" [(ngModel)]="docserver.docserver_id" - maxlength="32" pattern="^[\w.-]*$"> + <input matInput required name="identifier" id="identifier" title="{{lang.id}}" + type="text" placeholder="{{lang.id}}" [(ngModel)]="docserver.docserver_id" + maxlength="32" pattern="^[\w.-]*$"> </mat-form-field> <mat-form-field> - <input matInput required name="label" id="label" title="{{lang.label}}" type="text" placeholder="{{lang.label}}" - [(ngModel)]="docserver.device_label" maxlength="255"> + <input matInput required name="label" id="label" title="{{lang.label}}" type="text" + placeholder="{{lang.label}}" [(ngModel)]="docserver.device_label" + maxlength="255"> </mat-form-field> <mat-form-field> - <mat-select required name="collection" id="collection" title="{{lang.collection}}" placeholder="{{lang.collection}}" [(ngModel)]="docserver.coll_id"> + <mat-select required name="collection" id="collection" title="{{lang.collection}}" + placeholder="{{lang.collection}}" [(ngModel)]="docserver.coll_id"> <mat-option value="letterbox_coll" selected> letterbox_coll </mat-option> @@ -57,17 +56,21 @@ </mat-select> </mat-form-field> <mat-form-field> - <input matInput required name="max_size" id="max_size" title="{{lang.maxSize}}" type="number" placeholder="{{lang.maxSize}}" - [(ngModel)]="docserver.limitSizeFormatted" [disabled]="docserver.is_readonly" pattern="^\d+$"> + <input matInput required name="max_size" id="max_size" title="{{lang.maxSize}}" + type="number" placeholder="{{lang.maxSize}}" + [(ngModel)]="docserver.limitSizeFormatted" [disabled]="docserver.is_readonly" + pattern="^\d+$"> <span matSuffix> Go</span> </mat-form-field> <mat-form-field> - <input matInput required name="path" id="path" title="{{lang.path}}" type="text" placeholder="{{lang.path}}" [(ngModel)]="docserver.path_template" - [disabled]="docserver.is_readonly"> + <input matInput required name="path" id="path" title="{{lang.path}}" type="text" + placeholder="{{lang.path}}" [(ngModel)]="docserver.path_template" + [disabled]="docserver.is_readonly"> </mat-form-field> </div> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button color="primary" type="submit" [disabled]="!docserverForm.form.valid">{{lang.add}}</button> + <button mat-raised-button color="primary" type="submit" + [disabled]="!docserverForm.form.valid">{{lang.add}}</button> </div> </div> </form> @@ -75,4 +78,4 @@ </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/docserver/docserver-administration.component.ts b/src/frontend/app/administration/docserver/docserver-administration.component.ts index 732978e5bb95b5f41d6b93b57593eac02b5227d7..1f9d7e0e7ef64373de24b9e9a387e8f1641c2537 100755 --- a/src/frontend/app/administration/docserver/docserver-administration.component.ts +++ b/src/frontend/app/administration/docserver/docserver-administration.component.ts @@ -4,7 +4,6 @@ import { Router } from '@angular/router'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { MatPaginator } from '@angular/material/paginator'; -import { MatSidenav } from '@angular/material/sidenav'; import { MatSort } from '@angular/material/sort'; import { HeaderService } from '../../../service/header.service'; import { AppService } from '../../../service/app.service'; @@ -17,9 +16,6 @@ declare function $j(selector: any): any; }) export class DocserverAdministrationComponent implements OnInit { - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; lang : any = LANG; loading : boolean = false; @@ -44,8 +40,6 @@ export class DocserverAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.docserverCreation); - this.headerService.sideNavLeft = this.sidenavLeft; - this.loading = true; this.http.get('../../rest/docserverTypes') diff --git a/src/frontend/app/administration/docserver/docservers-administration.component.html b/src/frontend/app/administration/docserver/docservers-administration.component.html index c9688108fc90fedcd1e70c33e25ec11088a5e73a..ebc67a88652ab2e2766b115934f295b27711909a 100755 --- a/src/frontend/app/administration/docserver/docservers-administration.component.html +++ b/src/frontend/app/administration/docserver/docservers-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/docservers/new"> @@ -13,13 +9,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -45,46 +40,68 @@ </mat-panel-description> </mat-expansion-panel-header> <div class="row"> - <div class="col-md-4" *ngFor="let docserver of this.docservers[docserverType.docserver_type_id];let i=index"> + <div class="col-md-4" + *ngFor="let docserver of this.docservers[docserverType.docserver_type_id];let i=index"> <mat-card> - <form class="form-horizontal" (ngSubmit)="onSubmit(docserver,i)" #docserverFormUp="ngForm"> - <button *ngIf="!docserver.is_readonly" mat-icon-button color="accent" (click)="toggleDocserver(docserver)" style="position: absolute;top: 5px;right:10px;" - matTooltip="{{lang.lockDocserver}}"> + <form class="form-horizontal" (ngSubmit)="onSubmit(docserver,i)" + #docserverFormUp="ngForm"> + <button *ngIf="!docserver.is_readonly" mat-icon-button color="accent" + (click)="toggleDocserver(docserver)" + style="position: absolute;top: 5px;right:10px;" + matTooltip="{{lang.lockDocserver}}"> <mat-icon class="fa fa-lock-open"></mat-icon> </button> - <button *ngIf="docserver.is_readonly" mat-icon-button color="warn" (click)="toggleDocserver(docserver)" style="position: absolute;top: 5px;right:10px;" - matTooltip="{{lang.unlockDocserver}}"> + <button *ngIf="docserver.is_readonly" mat-icon-button color="warn" + (click)="toggleDocserver(docserver)" + style="position: absolute;top: 5px;right:10px;" + matTooltip="{{lang.unlockDocserver}}"> <mat-icon class="fa fa-lock"></mat-icon> </button> <div class="row" style="margin-top: 10px;"> <div class="col-md-12"> <mat-form-field> - <input matInput required name="label" id="label" title="{{lang.label}}" type="text" placeholder="{{lang.label}}" maxlength="255" - [(ngModel)]="docserver.device_label" [disabled]="docserver.is_readonly"> + <input matInput required name="label" id="label" + title="{{lang.label}}" type="text" + placeholder="{{lang.label}}" maxlength="255" + [(ngModel)]="docserver.device_label" + [disabled]="docserver.is_readonly"> </mat-form-field> </div> <div class="col-md-4"> - <mat-progress-spinner *ngIf="docserver.percentage < 60" name="percent_val" id="percent_val" color="primary" mode="determinate" - [value]="docserver.percentage" style="margin:auto;"> + <mat-progress-spinner *ngIf="docserver.percentage < 60" + name="percent_val" id="percent_val" color="primary" + mode="determinate" [value]="docserver.percentage" + style="margin:auto;"> </mat-progress-spinner> - <mat-progress-spinner *ngIf="docserver.percentage >= 60" name="percent_val" id="percent_val" color="warn" mode="determinate" - [value]="docserver.percentage" style="margin:auto;"> + <mat-progress-spinner *ngIf="docserver.percentage >= 60" + name="percent_val" id="percent_val" color="warn" + mode="determinate" [value]="docserver.percentage" + style="margin:auto;"> </mat-progress-spinner> - <span style="position: absolute;font-weight: bold;left: 50%;transform: translateX(-50%);top: 40%;font-weight: bold;" title="{{docserver.actualSizeFormatted}}">{{docserver.percentage}}%</span> + <span + style="position: absolute;font-weight: bold;left: 50%;transform: translateX(-50%);top: 40%;font-weight: bold;" + title="{{docserver.actualSizeFormatted}}">{{docserver.percentage}}%</span> </div> <div class="col-md-8"> <mat-form-field> - <input matInput required name="collection" id="collection" title="{{lang.collection}}" type="text" placeholder="{{lang.collection}}" [(ngModel)]="docserver.coll_id" disabled> + <input matInput required name="collection" id="collection" + title="{{lang.collection}}" type="text" + placeholder="{{lang.collection}}" + [(ngModel)]="docserver.coll_id" disabled> </mat-form-field> <mat-form-field> - <input matInput required name="identifier" id="identifier" title="{{lang.id}}" type="text" placeholder="{{lang.id}}" [(ngModel)]="docserver.docserver_id" - disabled> + <input matInput required name="identifier" id="identifier" + title="{{lang.id}}" type="text" placeholder="{{lang.id}}" + [(ngModel)]="docserver.docserver_id" disabled> </mat-form-field> </div> <div class="col-md-4"> <mat-form-field> - <input matInput required name="max_size" id="max_size" title="{{lang.maxSize}}" type="number" placeholder="{{lang.maxSize}}" - [(ngModel)]="docserver.limitSizeFormatted" [disabled]="docserver.is_readonly"> + <input matInput required name="max_size" id="max_size" + title="{{lang.maxSize}}" type="number" + placeholder="{{lang.maxSize}}" + [(ngModel)]="docserver.limitSizeFormatted" + [disabled]="docserver.is_readonly"> <span matSuffix> Go</span> </mat-form-field> </div> @@ -93,14 +110,21 @@ </div> <div class="col-md-12"> <mat-form-field> - <input matInput required name="path" id="path" title="{{lang.path}}" type="text" placeholder="{{lang.path}}" [(ngModel)]="docserver.path_template" - [disabled]="docserver.is_readonly"> + <input matInput required name="path" id="path" + title="{{lang.path}}" type="text" + placeholder="{{lang.path}}" + [(ngModel)]="docserver.path_template" + [disabled]="docserver.is_readonly"> </mat-form-field> </div> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button color="primary" type="submit" [disabled]="checkModif(docserver,this.docserversClone[docserverType.docserver_type_id][i])">{{lang.update}}</button> - <button mat-raised-button color="default" [disabled]="checkModif(docserver,this.docserversClone[docserverType.docserver_type_id][i])" (click)="cancelModification(docserverType.docserver_type_id,i)">{{lang.cancel}}</button> - <button mat-raised-button type="button" color="warn" (click)="delete(docserver,i)">{{lang.delete}}</button> + <button mat-raised-button color="primary" type="submit" + [disabled]="checkModif(docserver,this.docserversClone[docserverType.docserver_type_id][i])">{{lang.update}}</button> + <button mat-raised-button color="default" + [disabled]="checkModif(docserver,this.docserversClone[docserverType.docserver_type_id][i])" + (click)="cancelModification(docserverType.docserver_type_id,i)">{{lang.cancel}}</button> + <button mat-raised-button type="button" color="warn" + (click)="delete(docserver,i)">{{lang.delete}}</button> </div> </div> </form> @@ -113,4 +137,4 @@ </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/docserver/docservers-administration.component.ts b/src/frontend/app/administration/docserver/docservers-administration.component.ts index fb90bc8b3c51e2761c6c70fb155776c90d2032f1..04e4f998af23d153f0b3c5b70ef940469bc05a35 100755 --- a/src/frontend/app/administration/docserver/docservers-administration.component.ts +++ b/src/frontend/app/administration/docserver/docservers-administration.component.ts @@ -1,9 +1,8 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { MatPaginator } from '@angular/material/paginator'; -import { MatSidenav } from '@angular/material/sidenav'; import { MatSort } from '@angular/material/sort'; import { HeaderService } from '../../../service/header.service'; import { AppService } from '../../../service/app.service'; @@ -12,13 +11,12 @@ declare function $j(selector: any): any; @Component({ templateUrl : "docservers-administration.component.html", - providers : [NotificationService, AppService] + providers : [AppService] }) export class DocserversAdministrationComponent implements OnInit { - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang : any = LANG; loading : boolean = false; @@ -35,7 +33,8 @@ export class DocserversAdministrationComponent implements OnInit { public http: HttpClient, private notify: NotificationService, private headerService: HeaderService, - public appService: AppService + public appService: AppService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -43,7 +42,7 @@ export class DocserversAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.docservers); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/doctype/doctypes-administration.component.html b/src/frontend/app/administration/doctype/doctypes-administration.component.html index 023db94a3166e66baf2c0c0ac2e6566dd73f1a02..421a5b4b8cc6e5f8466a8f3651bdff03a224c09b 100755 --- a/src/frontend/app/administration/doctype/doctypes-administration.component.html +++ b/src/frontend/app/administration/doctype/doctypes-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item (click)="prepareDoctypeAdd('firstLevel')"> @@ -34,12 +30,12 @@ </p> </a> </mat-nav-list> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -56,17 +52,19 @@ <mat-card *ngIf="!loading" class="card-app-content"> <mat-form-field> - <input matInput id="jstree_search" name="jstree_search" type="text" placeholder="{{lang.search}}"> + <input matInput id="jstree_search" name="jstree_search" type="text" + placeholder="{{lang.search}}"> </mat-form-field> <div id="jstree"></div> - <div class="mat-paginator" style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">{{doctypes.length}} {{lang.documentTypesAlt}}</div> + <div class="mat-paginator" + style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> + {{doctypes.length}} {{lang.documentTypesAlt}}</div> </mat-card> </div> </div> </mat-sidenav-content> - - <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" fixedTopGap="56" - position='end' [opened]="false" class="col-md-4 col-sm-12"> + <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" + fixedTopGap="56" position='end' [opened]="false" class="col-md-4 col-sm-12"> <mat-nav-list> <mat-tab-group> @@ -75,25 +73,30 @@ <div class="form-group" *ngIf="!creationMode"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentFirstLevel.doctypes_first_level_id" required name="doctypes_first_level_id" id="doctypes_first_level_id" title="{{lang.id}}" type="text" - placeholder="{{lang.id}}" maxlength="255" [disabled]="!creationMode"> + <input matInput [(ngModel)]="currentFirstLevel.doctypes_first_level_id" required + name="doctypes_first_level_id" id="doctypes_first_level_id" title="{{lang.id}}" + type="text" placeholder="{{lang.id}}" maxlength="255" + [disabled]="!creationMode"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentFirstLevel.doctypes_first_level_label" required name="doctypes_first_level_label" id="doctypes_first_level_label" title="{{lang.label}}" - type="text" placeholder="{{lang.label}}" maxlength="255"> + <input matInput [(ngModel)]="currentFirstLevel.doctypes_first_level_label" required + name="doctypes_first_level_label" id="doctypes_first_level_label" + title="{{lang.label}}" type="text" placeholder="{{lang.label}}" maxlength="255"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <mat-select id="foldertypeList" name="foldertypeList" title="{{lang.folderTypeList}}" placeholder="{{lang.folderTypeList}}" - [(ngModel)]="currentFirstLevel.foldertype_id" multiple required> - <mat-option *ngFor="let folderType of folderTypes" [value]="folderType.foldertype_id"> + <mat-select id="foldertypeList" name="foldertypeList" + title="{{lang.folderTypeList}}" placeholder="{{lang.folderTypeList}}" + [(ngModel)]="currentFirstLevel.foldertype_id" multiple required> + <mat-option *ngFor="let folderType of folderTypes" + [value]="folderType.foldertype_id"> {{folderType.foldertype_label}} </mat-option> </mat-select> @@ -102,10 +105,13 @@ </div> <div class="form-group"> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button [disabled]="!firstLevelForm.form.valid" color="primary" (click)="saveFirstLevel()">{{lang.save}}</button> - <button type="button" mat-raised-button *ngIf="!creationMode" [disabled]="!firstLevelForm.form.valid || currentFirstLevel.hasChildren" - color="warn" (click)="removeFirstLevel()">{{lang.delete}}</button> - <button type="button" mat-raised-button *ngIf="creationMode" color="default" (click)="readMode()">{{lang.cancel}}</button> + <button mat-raised-button [disabled]="!firstLevelForm.form.valid" color="primary" + (click)="saveFirstLevel()">{{lang.save}}</button> + <button type="button" mat-raised-button *ngIf="!creationMode" + [disabled]="!firstLevelForm.form.valid || currentFirstLevel.hasChildren" + color="warn" (click)="removeFirstLevel()">{{lang.delete}}</button> + <button type="button" mat-raised-button *ngIf="creationMode" color="default" + (click)="readMode()">{{lang.cancel}}</button> </div> </div> </form> @@ -115,16 +121,19 @@ <div class="form-group" *ngIf="!creationMode"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentSecondLevel.doctypes_second_level_id" required name="doctypes_second_level_id" id="doctypes_second_level_id" title="{{lang.id}}" type="text" - placeholder="{{lang.id}}" maxlength="255" [disabled]="!creationMode"> + <input matInput [(ngModel)]="currentSecondLevel.doctypes_second_level_id" required + name="doctypes_second_level_id" id="doctypes_second_level_id" + title="{{lang.id}}" type="text" placeholder="{{lang.id}}" maxlength="255" + [disabled]="!creationMode"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentSecondLevel.doctypes_second_level_label" required name="doctypes_second_level_label" id="doctypes_second_level_label" title="{{lang.label}}" type="text" - placeholder="{{lang.label}}" maxlength="255"> + <input matInput [(ngModel)]="currentSecondLevel.doctypes_second_level_label" + required name="doctypes_second_level_label" id="doctypes_second_level_label" + title="{{lang.label}}" type="text" placeholder="{{lang.label}}" maxlength="255"> </mat-form-field> </div> <!-- <div class="col-sm-2"> @@ -136,9 +145,11 @@ <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <mat-select id="doctypes_first_level_id" name="doctypes_first_level_id" title="{{lang.firstLevelAttached}}" placeholder="{{lang.firstLevelAttached}}" - [(ngModel)]="currentSecondLevel.doctypes_first_level_id" required> - <mat-option *ngFor="let firstLevel of firstLevels" [value]="firstLevel.doctypes_first_level_id"> + <mat-select id="doctypes_first_level_id" name="doctypes_first_level_id" + title="{{lang.firstLevelAttached}}" placeholder="{{lang.firstLevelAttached}}" + [(ngModel)]="currentSecondLevel.doctypes_first_level_id" required> + <mat-option *ngFor="let firstLevel of firstLevels" + [value]="firstLevel.doctypes_first_level_id"> {{firstLevel.doctypes_first_level_label}} </mat-option> </mat-select> @@ -147,10 +158,13 @@ </div> <div class="form-group"> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button [disabled]="!secondLevelForm.form.valid" color="primary" (click)="saveSecondLevel()">{{lang.save}}</button> - <button mat-raised-button *ngIf="!creationMode" [disabled]="!secondLevelForm.form.valid || currentSecondLevel.hasChildren" - color="warn" (click)="removeSecondLevel()">{{lang.delete}}</button> - <button mat-raised-button *ngIf="creationMode" color="default" (click)="readMode()">{{lang.cancel}}</button> + <button mat-raised-button [disabled]="!secondLevelForm.form.valid" color="primary" + (click)="saveSecondLevel()">{{lang.save}}</button> + <button mat-raised-button *ngIf="!creationMode" + [disabled]="!secondLevelForm.form.valid || currentSecondLevel.hasChildren" + color="warn" (click)="removeSecondLevel()">{{lang.delete}}</button> + <button mat-raised-button *ngIf="creationMode" color="default" + (click)="readMode()">{{lang.cancel}}</button> </div> </div> </form> @@ -161,25 +175,29 @@ <div class="form-group" *ngIf="!creationMode"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentType.type_id" required name="type_id" id="type_id" title="{{lang.id}}" type="text" - placeholder="{{lang.id}}" maxlength="255" [disabled]="!creationMode"> + <input matInput [(ngModel)]="currentType.type_id" required name="type_id" + id="type_id" title="{{lang.id}}" type="text" placeholder="{{lang.id}}" + maxlength="255" [disabled]="!creationMode"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentType.description" required name="description" id="description" title="{{lang.label}}" - type="text" placeholder="{{lang.label}}" maxlength="255"> + <input matInput [(ngModel)]="currentType.description" required name="description" + id="description" title="{{lang.label}}" type="text" placeholder="{{lang.label}}" + maxlength="255"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <mat-select id="doctypes_second_level_id" name="doctypes_second_level_id" title="{{lang.secondLevelAttached}}" placeholder="{{lang.secondLevelAttached}}" - [(ngModel)]="currentType.doctypes_second_level_id" required> - <mat-option *ngFor="let secondLevel of secondLevels" [value]="secondLevel.doctypes_second_level_id"> + <mat-select id="doctypes_second_level_id" name="doctypes_second_level_id" + title="{{lang.secondLevelAttached}}" placeholder="{{lang.secondLevelAttached}}" + [(ngModel)]="currentType.doctypes_second_level_id" required> + <mat-option *ngFor="let secondLevel of secondLevels" + [value]="secondLevel.doctypes_second_level_id"> {{secondLevel.doctypes_second_level_label}} </mat-option> </mat-select> @@ -189,31 +207,36 @@ <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentType.process_delay" required name="process_delay" id="process_delay" title="{{lang.processDelayDay}}" - type="number" placeholder="{{lang.processDelayDay}}" pattern="^[0-9]*$"> + <input matInput [(ngModel)]="currentType.process_delay" required + name="process_delay" id="process_delay" title="{{lang.processDelayDay}}" + type="number" placeholder="{{lang.processDelayDay}}" pattern="^[0-9]*$"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentType.delay1" required name="delay1" id="delay1" title="{{lang.delay1}}" - type="number" placeholder="{{lang.delay1}}" pattern="^[0-9]*$"> + <input matInput [(ngModel)]="currentType.delay1" required name="delay1" id="delay1" + title="{{lang.delay1}}" type="number" placeholder="{{lang.delay1}}" + pattern="^[0-9]*$"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentType.delay2" required name="delay2" id="delay2" title="{{lang.delay2}}" - type="number" placeholder="{{lang.delay2}}" maxlength="255" pattern="^[0-9]*$"> + <input matInput [(ngModel)]="currentType.delay2" required name="delay2" id="delay2" + title="{{lang.delay2}}" type="number" placeholder="{{lang.delay2}}" + maxlength="255" pattern="^[0-9]*$"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <mat-select id="process_mode" name="process_mode" title="{{lang.processMode}}" placeholder="{{lang.processMode}}" [(ngModel)]="currentType.process_mode" required> + <mat-select id="process_mode" name="process_mode" title="{{lang.processMode}}" + placeholder="{{lang.processMode}}" [(ngModel)]="currentType.process_mode" + required> <mat-option *ngFor="let process of processModes" [value]="process"> {{process}} </mat-option> @@ -231,7 +254,11 @@ <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <mat-select id="retention_final_disposition" name="retention_final_disposition" title="{{lang.retentionFinalDisposition}}" placeholder="{{lang.retentionFinalDisposition}}" [(ngModel)]="currentType.retention_final_disposition"> + <mat-select id="retention_final_disposition" + name="retention_final_disposition" + title="{{lang.retentionFinalDisposition}}" + placeholder="{{lang.retentionFinalDisposition}}" + [(ngModel)]="currentType.retention_final_disposition"> <mat-option value="destruction">{{lang.destruction}}</mat-option> <mat-option value="conservation">{{lang.conservation}}</mat-option> </mat-select> @@ -241,14 +268,17 @@ <div class="form-group"> <div class="col-sm-6"> <mat-form-field> - <input matInput [(ngModel)]="currentType.retention_rule" name="retention_rule" id="retention_rule" title="{{lang.retentionRule}}" - type="text" placeholder="{{lang.retentionRule}}" maxlength="15"> + <input matInput [(ngModel)]="currentType.retention_rule" + name="retention_rule" id="retention_rule" title="{{lang.retentionRule}}" + type="text" placeholder="{{lang.retentionRule}}" maxlength="15"> </mat-form-field> </div> <div class="col-sm-6"> <mat-form-field> - <input matInput [(ngModel)]="currentType.duration_current_use" name="duration_current_use" id="duration_current_use" title="{{lang.durationCurrentUse}}" - type="text" placeholder="{{lang.durationCurrentUse}}" pattern="^[0-9]*$"> + <input matInput [(ngModel)]="currentType.duration_current_use" + name="duration_current_use" id="duration_current_use" + title="{{lang.durationCurrentUse}}" type="text" + placeholder="{{lang.durationCurrentUse}}" pattern="^[0-9]*$"> <!-- pattern without required attribute must be type text --> </mat-form-field> </div> @@ -258,10 +288,13 @@ <div class="form-group"> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button [disabled]="!typeForm.form.valid" color="primary" (click)="saveType()">{{lang.save}}</button> + <button mat-raised-button [disabled]="!typeForm.form.valid" color="primary" + (click)="saveType()">{{lang.save}}</button> <button mat-raised-button *ngIf="!creationMode" [disabled]="!typeForm.form.valid" - color="warn" (click)="removeType()" matTooltip="{{lang.toolTipDeleteDoctype}}">{{lang.delete}}</button> - <button mat-raised-button *ngIf="creationMode" color="default" (click)="readMode()">{{lang.cancel}}</button> + color="warn" (click)="removeType()" + matTooltip="{{lang.toolTipDeleteDoctype}}">{{lang.delete}}</button> + <button mat-raised-button *ngIf="creationMode" color="default" + (click)="readMode()">{{lang.cancel}}</button> </div> </div> </form> @@ -269,4 +302,4 @@ </mat-tab-group> </mat-nav-list> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/doctype/doctypes-administration.component.ts b/src/frontend/app/administration/doctype/doctypes-administration.component.ts index 8ee2097d0529c2a227070f32ff0e3d4555abe641..26daa8c0798301606702ab08cd04c6f7bf4773f6 100755 --- a/src/frontend/app/administration/doctype/doctypes-administration.component.ts +++ b/src/frontend/app/administration/doctype/doctypes-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, Inject } from '@angular/core'; +import { Component, OnInit, ViewChild, Inject, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; @@ -18,8 +18,8 @@ declare function $j(selector: any): any; export class DoctypesAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; dialogRef: MatDialogRef<any>; config: any = {}; @@ -49,7 +49,8 @@ export class DoctypesAdministrationComponent implements OnInit { private notify: NotificationService, public dialog: MatDialog, private headerService: HeaderService, - public appService: AppService + public appService: AppService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -57,7 +58,7 @@ export class DoctypesAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.documentTypes); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/entity/entities-administration.component.html b/src/frontend/app/administration/entity/entities-administration.component.html index 78702024e56516c34d9ce5bd88292390735559ad..7f2131ed747976bb2c57af49193334dd0476a29e 100755 --- a/src/frontend/app/administration/entity/entities-administration.component.html +++ b/src/frontend/app/administration/entity/entities-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item (click)="snav2.open();prepareEntityAdd()" *ngIf="!creationMode"> @@ -19,7 +15,8 @@ <ng-container *ngFor="let role of listTemplateRoles"> <a mat-list-item disableRipple="true" *ngIf="role.id != 'dest' && role.id != 'cc'"> <mat-icon color="primary" mat-list-icon> - <mat-slide-toggle [checked]="role.available" color="primary" (click)="toggleRole(role);false"></mat-slide-toggle> + <mat-slide-toggle [checked]="role.available" color="primary" (click)="toggleRole(role);false"> + </mat-slide-toggle> </mat-icon> <p mat-line [ngStyle]="{'opacity': role.available ? '' : '0.5'}" (click)="toggleRole(role);false"> {{role.label}} @@ -27,13 +24,12 @@ </a> </ng-container> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -50,19 +46,22 @@ <mat-card *ngIf="!loading" class="card-app-content"> <mat-form-field> - <input matInput id="jstree_search" name="jstree_search" type="text" placeholder="{{lang.searchEntities}}"> + <input matInput id="jstree_search" name="jstree_search" type="text" + placeholder="{{lang.searchEntities}}"> <mat-hint *ngIf="!creationMode">{{lang.entityTreeInfo}}</mat-hint> <mat-hint *ngIf="creationMode">{{lang.entityTreeInfoCreation}}</mat-hint> </mat-form-field> <div id="jstree"></div> - <div class="mat-paginator" style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">{{entities.length}} {{lang.entities}}</div> + <div class="mat-paginator" + style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> + {{entities.length}} {{lang.entities}}</div> </mat-card> </div> </div> </mat-sidenav-content> - <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" fixedTopGap="56" - position='end' [opened]="false" class="col-md-5 col-xs-11"> + <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" + fixedTopGap="56" position='end' [opened]="false" class="col-md-5 col-xs-11"> <mat-nav-list> <mat-tab-group> <mat-tab [label]="creationMode ? lang.createNewEntity : lang.informations"> @@ -70,21 +69,25 @@ <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <mat-select id="parent_entity_id" name="parent_entity_id" title="{{lang.isLinkedTo}}" placeholder="{{lang.isLinkedTo}}" [(ngModel)]="currentEntity.parent_entity_id" - (selectionChange)="selectParentEntity(currentEntity.parent_entity_id)"> + <mat-select id="parent_entity_id" name="parent_entity_id" + title="{{lang.isLinkedTo}}" placeholder="{{lang.isLinkedTo}}" + [(ngModel)]="currentEntity.parent_entity_id" + (selectionChange)="selectParentEntity(currentEntity.parent_entity_id)"> <mat-option value=""> <i style="opacity:0.5;text-align:center;">- {{lang.noEntity}} -</i> </mat-option> <ng-container *ngFor="let entity of entities | sortBy : 'entity_label'"> - <mat-option [value]="entity.entity_id" *ngIf="(!entity.state.disabled && entity.entity_id != currentEntity.entity_id) || currentEntity.parent_entity_id == entity.entity_id"> + <mat-option [value]="entity.entity_id" + *ngIf="(!entity.state.disabled && entity.entity_id != currentEntity.entity_id) || currentEntity.parent_entity_id == entity.entity_id"> {{entity.entity_label}} </mat-option> </ng-container> </mat-select> </mat-form-field> <mat-form-field> - <mat-select id="entity_type" name="entity_type" title="{{lang.entityType}}" placeholder="{{lang.entityType}}" [(ngModel)]="currentEntity.entity_type" - maxlength="32" required> + <mat-select id="entity_type" name="entity_type" title="{{lang.entityType}}" + placeholder="{{lang.entityType}}" [(ngModel)]="currentEntity.entity_type" + maxlength="32" required> <mat-option *ngFor="let entity_type of entityTypeList" [value]="entity_type.id"> {{entity_type.label}} </mat-option> @@ -95,40 +98,45 @@ <div class="form-group" *ngIf="!creationMode"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.id" name="id" id="id" title="{{lang.technicalId}}" type="text" - placeholder="{{lang.technicalId}}" disabled> + <input matInput [(ngModel)]="currentEntity.id" name="id" id="id" + title="{{lang.technicalId}}" type="text" placeholder="{{lang.technicalId}}" + disabled> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.entity_id" required name="entity_id" id="entity_id" title="{{lang.id}}" type="text" - placeholder="{{lang.id}}" [disabled]="!creationMode" maxlength="32" pattern="^[\w-]*$"> + <input matInput [(ngModel)]="currentEntity.entity_id" required name="entity_id" + id="entity_id" title="{{lang.id}}" type="text" placeholder="{{lang.id}}" + [disabled]="!creationMode" maxlength="32" pattern="^[\w-]*$"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.entity_label" required name="entity_label" id="entity_label" title="{{lang.label}}" - type="text" placeholder="{{lang.label}}" maxlength="255"> + <input matInput [(ngModel)]="currentEntity.entity_label" required + name="entity_label" id="entity_label" title="{{lang.label}}" type="text" + placeholder="{{lang.label}}" maxlength="255"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.short_label" required name="short_label" id="short_label" title="{{lang.shortLabel}}" - type="text" placeholder="{{lang.shortLabel}}" maxlength="50"> + <input matInput [(ngModel)]="currentEntity.short_label" required name="short_label" + id="short_label" title="{{lang.shortLabel}}" type="text" + placeholder="{{lang.shortLabel}}" maxlength="50"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.email" name="email" id="email" title="{{lang.email}}" type="text" placeholder="{{lang.email}}" - maxlength="255" pattern="(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"> + <input matInput [(ngModel)]="currentEntity.email" name="email" id="email" + title="{{lang.email}}" type="text" placeholder="{{lang.email}}" maxlength="255" + pattern="(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"> </mat-form-field> </div> </div> @@ -142,61 +150,74 @@ <div class="form-group"> <div class="col-sm-4"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.adrs_1" name="adrs_1" id="adrs_1" title="{{lang.address}}1" type="text" placeholder="{{lang.address}}1" - maxlength="255"> + <input matInput [(ngModel)]="currentEntity.adrs_1" name="adrs_1" id="adrs_1" + title="{{lang.address}}1" type="text" placeholder="{{lang.address}}1" + maxlength="255"> </mat-form-field> </div> <div class="col-sm-4"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.adrs_2" name="adrs_2" id="adrs_2" title="{{lang.address}}2" type="text" placeholder="{{lang.address}}2" - maxlength="255"> + <input matInput [(ngModel)]="currentEntity.adrs_2" name="adrs_2" id="adrs_2" + title="{{lang.address}}2" type="text" placeholder="{{lang.address}}2" + maxlength="255"> </mat-form-field> </div> <div class="col-sm-4"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.adrs_3" name="adrs_3" id="adrs_3" title="{{lang.address}}3" type="text" placeholder="{{lang.address}}3" - maxlength="255"> + <input matInput [(ngModel)]="currentEntity.adrs_3" name="adrs_3" id="adrs_3" + title="{{lang.address}}3" type="text" placeholder="{{lang.address}}3" + maxlength="255"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-4"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.zipcode" name="zipcode" id="zipcode" title="{{lang.zipcode}}" type="text" placeholder="{{lang.zipcode}}" - maxlength="32"> + <input matInput [(ngModel)]="currentEntity.zipcode" name="zipcode" + id="zipcode" title="{{lang.zipcode}}" type="text" + placeholder="{{lang.zipcode}}" maxlength="32"> </mat-form-field> </div> <div class="col-sm-4"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.city" name="city" id="city" title="{{lang.city}}" type="text" placeholder="{{lang.city}}" - maxlength="255"> + <input matInput [(ngModel)]="currentEntity.city" name="city" id="city" + title="{{lang.city}}" type="text" placeholder="{{lang.city}}" + maxlength="255"> </mat-form-field> </div> <div class="col-sm-4"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.country" name="country" id="country" title="{{lang.country}}" type="text" placeholder="{{lang.country}}" - maxlength="255"> + <input matInput [(ngModel)]="currentEntity.country" name="country" + id="country" title="{{lang.country}}" type="text" + placeholder="{{lang.country}}" maxlength="255"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <textarea matInput [(ngModel)]="currentEntity.entity_full_name" name="entity_full_name" id="entity_full_name" placeholder="{{lang.entityFullName}}" - title="{{lang.entityFullName}}" matTextareaAutosize matAutosizeMinRows="1" - matAutosizeMaxRows="5"></textarea> + <textarea matInput [(ngModel)]="currentEntity.entity_full_name" + name="entity_full_name" id="entity_full_name" + placeholder="{{lang.entityFullName}}" title="{{lang.entityFullName}}" + matTextareaAutosize matAutosizeMinRows="1" + matAutosizeMaxRows="5"></textarea> </mat-form-field> </div> </div> <div class="form-group" *ngIf="!creationMode"> <div class="col-sm-12"> <mat-form-field> - <input *ngIf="!currentEntity.canSynchronizeSiret" matInput value="Paramètre SIRET manquant" title="{{lang.siretCode}}" type="text" - placeholder="{{lang.siretCode}}" maxlength="255" disabled> - <input *ngIf="currentEntity.canSynchronizeSiret" matInput [(ngModel)]="currentEntity.business_id" name="business_id" id="business_id" title="{{lang.siretCode}}" type="text" - placeholder="{{lang.siretCode}}" maxlength="255" disabled> - <button *ngIf="currentEntity.canSynchronizeSiret" color="primary" mat-icon-button matSuffix title="Générer un numéro SIRET" (click)="addEntityToAnnuary()"> + <input *ngIf="!currentEntity.canSynchronizeSiret" matInput + value="Paramètre SIRET manquant" title="{{lang.siretCode}}" type="text" + placeholder="{{lang.siretCode}}" maxlength="255" disabled> + <input *ngIf="currentEntity.canSynchronizeSiret" matInput + [(ngModel)]="currentEntity.business_id" name="business_id" + id="business_id" title="{{lang.siretCode}}" type="text" + placeholder="{{lang.siretCode}}" maxlength="255" disabled> + <button *ngIf="currentEntity.canSynchronizeSiret" color="primary" + mat-icon-button matSuffix title="Générer un numéro SIRET" + (click)="addEntityToAnnuary()"> <mat-icon class="fas fa-compress-arrows-alt"></mat-icon> </button> </mat-form-field> @@ -205,14 +226,18 @@ <div class="form-group"> <div class="col-sm-6"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.archival_agency" name="archival_agency" id="archival_agency" title="{{lang.archivalAgency}}" - type="text" placeholder="{{lang.archivalAgency}}" maxlength="255"> + <input matInput [(ngModel)]="currentEntity.archival_agency" + name="archival_agency" id="archival_agency" + title="{{lang.archivalAgency}}" type="text" + placeholder="{{lang.archivalAgency}}" maxlength="255"> </mat-form-field> </div> <div class="col-sm-6"> <mat-form-field> - <input matInput [(ngModel)]="currentEntity.archival_agreement" name="archival_agreement" id="archival_agreement" title="{{lang.archivalAgreement}}" - type="text" placeholder="{{lang.archivalAgreement}}" maxlength="255"> + <input matInput [(ngModel)]="currentEntity.archival_agreement" + name="archival_agreement" id="archival_agreement" + title="{{lang.archivalAgreement}}" type="text" + placeholder="{{lang.archivalAgreement}}" maxlength="255"> </mat-form-field> </div> </div> @@ -220,10 +245,13 @@ </mat-accordion> <div class="form-group"> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button [disabled]="!entityForm.form.valid" color="primary" (click)="saveEntity()">{{lang.save}}</button> - <button mat-raised-button *ngIf="!creationMode" [disabled]="!entityForm.form.valid || this.currentEntity.hasChildren" color="warn" - (click)="removeEntity()">{{lang.delete}}</button> - <button mat-raised-button *ngIf="creationMode" color="default" (click)="readMode()">{{lang.cancel}}</button> + <button mat-raised-button [disabled]="!entityForm.form.valid" color="primary" + (click)="saveEntity()">{{lang.save}}</button> + <button mat-raised-button *ngIf="!creationMode" + [disabled]="!entityForm.form.valid || this.currentEntity.hasChildren" color="warn" + (click)="removeEntity()">{{lang.delete}}</button> + <button mat-raised-button *ngIf="creationMode" color="default" + (click)="readMode()">{{lang.cancel}}</button> </div> </div> </form> @@ -231,13 +259,18 @@ <mat-tab label="{{lang.diffusionList}}" *ngIf="!creationMode"> <div class="row" style="margin:0px;"> <div class="col-md-12"> - <app-diffusions-list #appDiffusionsList [adminMode]="true" [target]="'redirect'"></app-diffusions-list> + <app-diffusions-list #appDiffusionsList [adminMode]="true" [target]="'redirect'"> + </app-diffusions-list> </div> <div class="form-group" *ngIf="currentEntity.entity_id"> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button color="primary" (click)="saveDiffList()" [disabled]="appDiffusionsList.hasEmptyDest() || !appDiffusionsList.isModified()">{{lang.save}}</button> - <button mat-raised-button color="default" (click)="appDiffusionsList.loadListModel(currentEntity.id)" [disabled]="!appDiffusionsList.isModified()">{{lang.cancel}}</button> - <button *ngIf="!appDiffusionsList.isEmptyList() && currentEntity.listTemplate.id" mat-raised-button color="warn" (click)="deleteDiffList()">{{lang.delete}}</button> + <button mat-raised-button color="primary" (click)="saveDiffList()" + [disabled]="appDiffusionsList.hasEmptyDest() || !appDiffusionsList.isModified()">{{lang.save}}</button> + <button mat-raised-button color="default" + (click)="appDiffusionsList.loadListModel(currentEntity.id)" + [disabled]="!appDiffusionsList.isModified()">{{lang.cancel}}</button> + <button *ngIf="!appDiffusionsList.isEmptyList() && currentEntity.listTemplate.id" + mat-raised-button color="warn" (click)="deleteDiffList()">{{lang.delete}}</button> </div> </div> </div> @@ -245,12 +278,16 @@ <mat-tab label="{{lang.visaWorkflow}}" *ngIf="!creationMode"> <div class="row" style="margin:0px;" id="visaCircuitContent"> <div class="col-md-12"> - <app-visa-workflow [adminMode]="true" [showListModels]="false" [showComment]="false" #appVisaWorkflow></app-visa-workflow> + <app-visa-workflow [adminMode]="true" [showListModels]="false" [showComment]="false" + #appVisaWorkflow></app-visa-workflow> </div> <div class="form-group" *ngIf="currentEntity.entity_id"> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button color="primary" (click)="saveDiffListVisa()" [disabled]="!appVisaWorkflow.isModified()">{{lang.save}}</button> - <button mat-raised-button color="default" (click)="appVisaWorkflow.loadListModel(currentEntity.id)" [disabled]="!appVisaWorkflow.isModified()">{{lang.cancel}}</button> + <button mat-raised-button color="primary" (click)="saveDiffListVisa()" + [disabled]="!appVisaWorkflow.isModified()">{{lang.save}}</button> + <button mat-raised-button color="default" + (click)="appVisaWorkflow.loadListModel(currentEntity.id)" + [disabled]="!appVisaWorkflow.isModified()">{{lang.cancel}}</button> </div> </div> </div> @@ -258,12 +295,16 @@ <mat-tab label="{{lang.avis}}" *ngIf="!creationMode"> <div class="row" style="margin:0px;" id="opinionCircuitContent"> <div class="col-md-12"> - <app-avis-workflow [adminMode]="true" [showListModels]="false" #appAvisWorkflow></app-avis-workflow> + <app-avis-workflow [adminMode]="true" [showListModels]="false" #appAvisWorkflow> + </app-avis-workflow> </div> <div class="form-group" *ngIf="currentEntity.entity_id"> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button color="primary" (click)="saveDiffListOpinion()" [disabled]="!appAvisWorkflow.isModified()">{{lang.save}}</button> - <button mat-raised-button color="default" (click)="appAvisWorkflow.loadListModel(currentEntity.id)" [disabled]="!appAvisWorkflow.isModified()">{{lang.cancel}}</button> + <button mat-raised-button color="primary" (click)="saveDiffListOpinion()" + [disabled]="!appAvisWorkflow.isModified()">{{lang.save}}</button> + <button mat-raised-button color="default" + (click)="appAvisWorkflow.loadListModel(currentEntity.id)" + [disabled]="!appAvisWorkflow.isModified()">{{lang.cancel}}</button> </div> </div> </div> @@ -271,12 +312,16 @@ <mat-tab label="{{lang.users}}" *ngIf="!creationMode"> <div class="row" style="margin:0px;"> <div class="col-md-12" *ngIf="currentEntity.canAdminUsers" style="padding:5px;"> - <plugin-autocomplete [labelPlaceholder]="lang.linkUser" [labelList]="lang.availableUsers" [routeDatas]="['/rest/autocomplete/users/administration']" [targetSearchKey]="'idToDisplay'" [subInfoKey]="'descriptionToDisplay'" (triggerEvent)="linkUser($event)"></plugin-autocomplete> - <hr/> + <plugin-autocomplete [labelPlaceholder]="lang.linkUser" [labelList]="lang.availableUsers" + [routeDatas]="['/rest/autocomplete/users/administration']" + [targetSearchKey]="'idToDisplay'" [subInfoKey]="'descriptionToDisplay'" + (triggerEvent)="linkUser($event)"></plugin-autocomplete> + <hr /> </div> <div class="col-md-6 col-xs-6"> <mat-form-field> - <input matInput (keyup)="applyFilterUsers($event.target.value)" placeholder="{{lang.filterBy}}"> + <input matInput (keyup)="applyFilterUsers($event.target.value)" + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> @@ -284,7 +329,8 @@ </mat-paginator> </div> </div> - <mat-table #tableUsers="matSort" [dataSource]="dataSourceUsers" matSort matSortActive="lastname" matSortDirection="asc"> + <mat-table #tableUsers="matSort" [dataSource]="dataSourceUsers" matSort matSortActive="lastname" + matSortDirection="asc"> <ng-container matColumnDef="firstname"> <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.firstname}}</mat-header-cell> <mat-cell *matCellDef="let element"> {{element.firstname}} </mat-cell> @@ -294,15 +340,17 @@ <mat-cell *matCellDef="let element"> {{element.lastname}} </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumnsUsers"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumnsUsers;" routerLink="/administration/users/{{row.id}}" matTooltip="{{lang.view}}" - style="cursor:pointer;"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumnsUsers;" + routerLink="/administration/users/{{row.id}}" matTooltip="{{lang.view}}" + style="cursor:pointer;"></mat-row> </mat-table> </mat-tab> <mat-tab label="{{lang.templates}}" *ngIf="!creationMode"> <div class="row" style="margin:0px;"> <div class="col-md-6 col-xs-6"> <mat-form-field> - <input matInput (keyup)="applyFilterTemplates($event.target.value)" placeholder="{{lang.filterBy}}"> + <input matInput (keyup)="applyFilterTemplates($event.target.value)" + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> @@ -310,20 +358,27 @@ </mat-paginator> </div> </div> - <mat-table #tableTemplates="matSort" [dataSource]="dataSourceTemplates" matSort matSortActive="template_label" matSortDirection="asc"> + <mat-table #tableTemplates="matSort" [dataSource]="dataSourceTemplates" matSort + matSortActive="template_label" matSortDirection="asc"> <ng-container matColumnDef="template_label"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.templateName}}</mat-header-cell> - <mat-cell *matCellDef="let element" style="flex:2;" matTooltip="{{element.template_comment}}" > {{element.template_label}} </mat-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.templateName}} + </mat-header-cell> + <mat-cell *matCellDef="let element" style="flex:2;" + matTooltip="{{element.template_comment}}"> {{element.template_label}} </mat-cell> </ng-container> <ng-container matColumnDef="template_target"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:1;">{{lang.templateTarget}}</mat-header-cell> - <mat-cell *matCellDef="let element" style="flex:1;"> {{lang[element.template_target]}} </mat-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:1;">{{lang.templateTarget}} + </mat-header-cell> + <mat-cell *matCellDef="let element" style="flex:1;"> {{lang[element.template_target]}} + </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumnsTemplates"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumnsTemplates;" (click)="showTemplate(row.template_id);" [ngStyle]="{'cursor': !currentEntity.canAdminTemplates ? 'position' : 'pointer'}"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumnsTemplates;" + (click)="showTemplate(row.template_id);" + [ngStyle]="{'cursor': !currentEntity.canAdminTemplates ? 'position' : 'pointer'}"></mat-row> </mat-table> </mat-tab> </mat-tab-group> </mat-nav-list> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/entity/entities-administration.component.ts b/src/frontend/app/administration/entity/entities-administration.component.ts index 566e084ff7793935e29c7700c485d74fb3f73e45..28b3307f614f498cef348fa17aa99d63fc78ac5b 100755 --- a/src/frontend/app/administration/entity/entities-administration.component.ts +++ b/src/frontend/app/administration/entity/entities-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, Inject } from '@angular/core'; +import { Component, OnInit, ViewChild, Inject, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; @@ -28,8 +28,8 @@ declare function $j(selector: any): any; export class EntitiesAdministrationComponent implements OnInit { /*HEADER*/ titleHeader: string; - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; dialogRef: MatDialogRef<any>; @@ -81,13 +81,14 @@ export class EntitiesAdministrationComponent implements OnInit { private headerService: HeaderService, private router: Router, public appService: AppService, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { } async ngOnInit(): Promise<void> { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.entities); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/group/group-administration.component.html b/src/frontend/app/administration/group/group-administration.component.html index af8a2790bf1ecc3c1046bf390c04ac2beacb658d..a3b65fd8430bc8a6c029fb5815ff97c594b7a7dc 100755 --- a/src/frontend/app/administration/group/group-administration.component.html +++ b/src/frontend/app/administration/group/group-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> diff --git a/src/frontend/app/administration/group/group-administration.component.ts b/src/frontend/app/administration/group/group-administration.component.ts index ca231648e70aa3d08cb956cd7e95014208011c08..26c4cd55f450e27a89c8f334bd291d0d5924da58 100755 --- a/src/frontend/app/administration/group/group-administration.component.ts +++ b/src/frontend/app/administration/group/group-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { ActivatedRoute, Router } from '@angular/router'; import { LANG } from '../../translate.component'; @@ -12,7 +12,6 @@ import { AppService } from '../../../service/app.service'; import { PrivilegeService } from '../../../service/privileges.service'; import { tap, catchError, exhaustMap, map, finalize, filter } from 'rxjs/operators'; import { of } from 'rxjs'; -import { MenuShortcutComponent } from '../../menu/menu-shortcut.component'; import { MatDialog } from '@angular/material'; import { ConfirmComponent } from '../../../plugins/modal/confirm.component'; @@ -24,8 +23,7 @@ declare function $j(selector: any): any; providers: [AppService] }) export class GroupAdministrationComponent implements OnInit { - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; + @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; lang: any = LANG; @@ -84,7 +82,6 @@ export class GroupAdministrationComponent implements OnInit { this.loading = true; this.route.params.subscribe(params => { - this.headerService.sideNavLeft = this.sidenavLeft; if (typeof params['id'] == "undefined") { this.headerService.setHeader(this.lang.groupCreation); diff --git a/src/frontend/app/administration/group/groups-administration.component.html b/src/frontend/app/administration/group/groups-administration.component.html index 0d7c0b4f0295beff75e9cc7949a70313d3a92d2e..404d66429e2d7bdf8925b131786955faf8f6e3fa 100755 --- a/src/frontend/app/administration/group/groups-administration.component.html +++ b/src/frontend/app/administration/group/groups-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/groups/new"> @@ -13,13 +9,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -37,7 +32,8 @@ <div class="row" style="margin:0px;"> <div class="col-md-6 col-xs-6"> <mat-form-field> - <input matInput (keyup)="applyFilter($event.target.value)" placeholder="{{lang.filterBy}}"> + <input matInput (keyup)="applyFilter($event.target.value)" + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> @@ -45,33 +41,39 @@ </mat-paginator> </div> </div> - <mat-table #table [dataSource]="dataSource" matSort matSortActive="group_desc" matSortDirection="asc"> + <mat-table #table [dataSource]="dataSource" matSort matSortActive="group_desc" + matSortDirection="asc"> <ng-container matColumnDef="group_id"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()">{{lang.id}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()">{{lang.id}}</mat-header-cell> <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()"> {{element.group_id}} </mat-cell> </ng-container> <ng-container matColumnDef="group_desc"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.description}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.description}} + </mat-header-cell> <mat-cell *matCellDef="let element" style="flex:2;"> {{element.group_desc}} </mat-cell> </ng-container> <ng-container matColumnDef="actions"> <mat-header-cell *matHeaderCellDef style="flex:1;"></mat-header-cell> <mat-cell *matCellDef="let element" style="justify-content: flex-end;flex:1;"> - <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" (click)="$event.stopPropagation();preDelete(element)"> + <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" + (click)="$event.stopPropagation();preDelete(element)"> <mat-icon class="fa fa-trash-alt fa-2x" aria-hidden="true"></mat-icon> </button> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;" routerLink="/administration/groups/{{row.id}}" style="cursor:pointer;" - matTooltip="{{lang.view}}"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumns;" + routerLink="/administration/groups/{{row.id}}" style="cursor:pointer;" + matTooltip="{{lang.view}}"></mat-row> </mat-table> - <div class="mat-paginator" style="min-height:48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">{{groups.length}} {{lang.groups}}</div> + <div class="mat-paginator" + style="min-height:48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> + {{groups.length}} {{lang.groups}}</div> </mat-card> </div> </div> </mat-sidenav-content> -</mat-sidenav-container> - +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/group/groups-administration.component.ts b/src/frontend/app/administration/group/groups-administration.component.ts index abf21251be697f825a3d146467ada1ec76e52f50..85853790a3c79db7b3ce0ff7fd50a5d3e319d1ac 100755 --- a/src/frontend/app/administration/group/groups-administration.component.ts +++ b/src/frontend/app/administration/group/groups-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, Inject } from '@angular/core'; +import { Component, OnInit, ViewChild, Inject, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; @@ -18,9 +18,9 @@ declare function $j(selector: any): any; providers: [AppService] }) export class GroupsAdministrationComponent implements OnInit { - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; + @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; dialogRef : MatDialogRef<any>; @@ -53,7 +53,8 @@ export class GroupsAdministrationComponent implements OnInit { public dialog: MatDialog, private headerService: HeaderService, public appService: AppService, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -61,7 +62,7 @@ export class GroupsAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.groups); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/history/batch/history-batch-administration.component.html b/src/frontend/app/administration/history/batch/history-batch-administration.component.html index eb0528a7575907f1d53247da05cbd9285935fa98..387f8a5becd1e8389acc3cc48babefd5039c03d5 100644 --- a/src/frontend/app/administration/history/batch/history-batch-administration.component.html +++ b/src/frontend/app/administration/history/batch/history-batch-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <a mat-list-item *ngFor="let menu of subMenus" [class.active]="menu.current" [routerLink]="menu.route"> <mat-icon color="primary" mat-list-icon [class]="menu.icon"></mat-icon> @@ -12,13 +8,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -130,7 +125,8 @@ <ng-container matColumnDef="total_errors"> <mat-header-cell *matHeaderCellDef mat-sort-header>{{lang.totalErrors}} </mat-header-cell> - <mat-cell *matCellDef="let element" [class.empty]="element.total_errors === 0" [class.error]="element.total_errors > 0"> + <mat-cell *matCellDef="let element" [class.empty]="element.total_errors === 0" + [class.error]="element.total_errors > 0"> {{element.total_errors}} </mat-cell> </ng-container> <ng-container matColumnDef="info"> @@ -158,4 +154,4 @@ </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/history/batch/history-batch-administration.component.ts b/src/frontend/app/administration/history/batch/history-batch-administration.component.ts index 395a604f333f5739e245d268cbfacf3da11b571c..9a8582b82dd1a1d4fc5268171a2d57e238f37eb5 100644 --- a/src/frontend/app/administration/history/batch/history-batch-administration.component.ts +++ b/src/frontend/app/administration/history/batch/history-batch-administration.component.ts @@ -1,9 +1,8 @@ -import { Component, OnInit, ViewChild, EventEmitter, ElementRef } from '@angular/core'; +import { Component, OnInit, ViewChild, EventEmitter, ElementRef, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../../translate.component'; import { NotificationService } from '../../../notification.service'; import { HeaderService } from '../../../../service/header.service'; -import { MatSidenav } from '@angular/material/sidenav'; import { AppService } from '../../../../service/app.service'; import { Observable, merge, Subject, of as observableOf, of } from 'rxjs'; import { MatPaginator, MatSort, MatDialog } from '@angular/material'; @@ -20,8 +19,7 @@ import { PrivilegeService } from '../../../../service/privileges.service'; }) export class HistoryBatchAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; loading: boolean = false; @@ -70,10 +68,11 @@ export class HistoryBatchAdministrationComponent implements OnInit { public dialog: MatDialog, public functions: FunctionsService, private latinisePipe: LatinisePipe, - private privilegeService: PrivilegeService) { } + private privilegeService: PrivilegeService, + private viewContainerRef: ViewContainerRef) { } ngOnInit(): void { - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); if (this.privilegeService.hasCurrentUserPrivilege('view_history')) { this.subMenus = [ @@ -140,7 +139,7 @@ export class HistoryBatchAdministrationComponent implements OnInit { data.history = data.history.map((item: any) => { return { ...item, - total_errors : item.total_errors === null ? 0 : item.total_errors + total_errors: item.total_errors === null ? 0 : item.total_errors } }) return data; @@ -160,13 +159,13 @@ export class HistoryBatchAdministrationComponent implements OnInit { this.http.get("../../rest/batchHistory/availableFilters").pipe( map((data: any) => { - let returnData = {modules: [{}], totalErrors: [{}]}; + let returnData = { modules: [{}], totalErrors: [{}] }; returnData.modules = data.modules; returnData.totalErrors = [ { - id : 'errorElement', - label : this.lang.totalErrors + id: 'errorElement', + label: this.lang.totalErrors } ]; diff --git a/src/frontend/app/administration/history/history-administration.component.html b/src/frontend/app/administration/history/history-administration.component.html index 0e88be44467cd5163ada811f14d45d1a75ef0f80..e48ec0b6736e22f55928b3a11d62b017ee4f8cd6 100755 --- a/src/frontend/app/administration/history/history-administration.component.html +++ b/src/frontend/app/administration/history/history-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <a mat-list-item *ngFor="let menu of subMenus" [class.active]="menu.current" [routerLink]="menu.route"> <mat-icon color="primary" mat-list-icon [class]="menu.icon"></mat-icon> @@ -12,13 +8,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -30,14 +25,15 @@ <mat-label style="color:white;">{{lang.since}} </mat-label> <input [(ngModel)]="appHistoryList.startDateFilter" matInput [matDatepicker]="startPicker" - [placeholder]="lang.since" [max]="appHistoryList.endDateFilter" readonly style="cursor:pointer;" - (dateChange)="appHistoryList.filterStartDate()"> + [placeholder]="lang.since" [max]="appHistoryList.endDateFilter" readonly + style="cursor:pointer;" (dateChange)="appHistoryList.filterStartDate()"> <mat-datepicker-toggle matSuffix [for]="startPicker" *ngIf="!appHistoryList.startDateFilter"> </mat-datepicker-toggle> <mat-datepicker [touchUi]="appService.getViewMode()" #startPicker> </mat-datepicker> <button mat-button color="warn" matSuffix mat-icon-button *ngIf="appHistoryList.startDateFilter" - (click)="$event.stopPropagation();appHistoryList.startDateFilter = '';appHistoryList.filterStartDate()" [title]="lang.eraseValue"> + (click)="$event.stopPropagation();appHistoryList.startDateFilter = '';appHistoryList.filterStartDate()" + [title]="lang.eraseValue"> <mat-icon color="warn" class="fa fa-calendar-times"> </mat-icon> </button> @@ -46,14 +42,15 @@ <mat-label style="color:white;">{{lang.until}} </mat-label> <input [(ngModel)]="appHistoryList.endDateFilter" matInput [matDatepicker]="endPicker" - [placeholder]="lang.until" [min]="appHistoryList.startDateFilter" readonly style="cursor:pointer;" - (dateChange)="appHistoryList.filterEndDate()"> + [placeholder]="lang.until" [min]="appHistoryList.startDateFilter" readonly + style="cursor:pointer;" (dateChange)="appHistoryList.filterEndDate()"> <mat-datepicker-toggle matSuffix [for]="endPicker" *ngIf="!appHistoryList.endDateFilter"> </mat-datepicker-toggle> <mat-datepicker [touchUi]="appService.getViewMode()" #endPicker> </mat-datepicker> <button mat-button color="warn" matSuffix mat-icon-button *ngIf="appHistoryList.endDateFilter" - (click)="$event.stopPropagation();appHistoryList.endDateFilter = '';appHistoryList.filterEndDate()" [title]="lang.eraseValue"> + (click)="$event.stopPropagation();appHistoryList.endDateFilter = '';appHistoryList.filterEndDate()" + [title]="lang.eraseValue"> <mat-icon color="warn" class="fa fa-calendar-times"> </mat-icon> </button> @@ -67,4 +64,4 @@ </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/history/history-administration.component.ts b/src/frontend/app/administration/history/history-administration.component.ts index 14f189120bd6ed4162d7e27792553b89f8023fd1..46a565207a559326cebbc762447e498477964162 100755 --- a/src/frontend/app/administration/history/history-administration.component.ts +++ b/src/frontend/app/administration/history/history-administration.component.ts @@ -1,7 +1,6 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; -import { MatSidenav } from '@angular/material/sidenav'; import { AppService } from '../../../service/app.service'; import { FunctionsService } from '../../../service/functions.service'; import { HistoryComponent } from '../../history/history.component'; @@ -9,15 +8,14 @@ import { PrivilegeService } from '../../../service/privileges.service'; import { HeaderService } from '../../../service/header.service'; @Component({ - selector: 'contact-list', + selector: 'admin-history', templateUrl: "history-administration.component.html", styleUrls: ['history-administration.component.scss'], providers: [AppService] }) export class HistoryAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; @@ -46,12 +44,13 @@ export class HistoryAdministrationComponent implements OnInit { public appService: AppService, public functions: FunctionsService, private privilegeService: PrivilegeService, - private headerService: HeaderService) { } + private headerService: HeaderService, + private viewContainerRef: ViewContainerRef) { } ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.history.toLowerCase(), '', ''); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); if (this.privilegeService.hasCurrentUserPrivilege('view_history_batch')) { this.subMenus = [ diff --git a/src/frontend/app/administration/home/administration.component.html b/src/frontend/app/administration/home/administration.component.html index 7fa9df6d118afee825de57797536e1642eee6c45..65057f9f6570b3a56074656d9d3cfea62013d9c4 100644 --- a/src/frontend/app/administration/home/administration.component.html +++ b/src/frontend/app/administration/home/administration.component.html @@ -1,17 +1,9 @@ <mat-sidenav-container class="maarch-container"> - <mat-sidenav #snavLeft class="panel-left" #snav [mode]="appService.getViewMode() ? 'over' : 'side'" - [fixedInViewport]="appService.getViewMode()" [opened]="appService.getViewMode() ? false : true" autoFocus="false" style="overflow-x:hidden;" - [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - <mat-divider></mat-divider> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -21,11 +13,66 @@ </div> </div> <div class="container" [class.fullContainer]="appService.getViewMode()"> - <div class="container-content"> + <div class="container-content" style="display: flex;flex-direction: column;"> <div class="loading" *ngIf="loading"> <mat-spinner style="margin:auto;"></mat-spinner> </div> - <div *ngIf="!loading" class="row adminArea"> + <div style="display: grid;grid-template-columns: repeat(3, 1fr);gap: 20px;padding:20px;"> + <mat-card class="countCard" matRipple> + <div mat-card-avatar class="fa fa-user avatarCount"> + </div> + <span style="font-size: 40px;">45</span> + Utlisateurs + </mat-card> + <mat-card class="countCard" matRipple> + <div mat-card-avatar class="fa fa-users avatarCount"> + </div> + <span style="font-size: 40px;">8</span> + Groupes + </mat-card> + <mat-card class="countCard" matRipple> + <div mat-card-avatar class="fa fa-sitemap avatarCount"> + </div> + <span style="font-size: 40px;">21</span> + Entités + </mat-card> + </div> + <mat-divider></mat-divider> + <mat-form-field style="padding:10px;font-size: 10px;width: 250px !important;"> + <input matInput #searchServiceInput [formControl]="searchService" [placeholder]="lang.filterBy"> + </mat-form-field> + <!--<mat-list role="list" style="display: grid;grid-template-columns: repeat(3, 1fr);gap: 20px;"> + <mat-list-item role="listitem" *ngFor="let administration of administrations | sortBy : 'label'"> + <mat-icon mat-list-icon class="{{administration.style}}" style="font-size: 30px;"></mat-icon> + <p matLine style="font-size: 24px;">{{administration.label}}</p> + </mat-list-item> + </mat-list>--> + + <div style="margin: 20px;display: grid;grid-template-columns: repeat(4, 1fr);gap: 20px;padding:20px;padding-top:0px;margin-top:0px;"> + <button mat-button *ngFor="let administration of filteredAdministrations | async | sortBy : 'label'" [title]="administration.comment" style="font-size:20px;height:80px;" (click)="goToSpecifiedAdministration(administration)"> + <div style="display: flex;align-items: center;gap: 10px;"> + <i class="{{administration.style}} fa-4x avatarCount2"></i> + <span class="countLabel" style="white-space: initial;text-align: left;"> + {{administration.label}} + </span> + </div> + </button> + </div> + + + <!--<button mat-button *ngFor="let administration of administrations"> + <div style="display: flex;flex-direction: column;"> + <i class="{{administration.style}} fa-4x"></i> + <span> + {{administration.label}} + </span> + <span> + {{administration.comment}} + </span> + </div> + + </button>--> + <!--<div *ngIf="!loading" class="row adminArea"> <div class="col-md-6 col-sm-12 col-xs-12 adminArea_1" *ngIf="organisationServices"> <div class="adminArea-label">{{lang.organization}}</div> <button class="col-md-4 col-xs-6 adminArea-button" @@ -61,12 +108,13 @@ <br />{{modService.label}}</button> </ng-container> </div> - </div> + </div>--> </div> </div> </mat-sidenav-content> - <mat-sidenav #snav2 [fixedInViewport]="appService.getViewMode()" position='end' [opened]="appService.getViewMode() ? false : false" - [mode]="appService.getViewMode() ? 'over' : 'side'" class="panel-right" style="overflow-x:hidden;" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '30%'}" + <mat-sidenav #snav2 [fixedInViewport]="appService.getViewMode()" position='end' + [opened]="appService.getViewMode() ? false : false" [mode]="appService.getViewMode() ? 'over' : 'side'" + class="panel-right" style="overflow-x:hidden;" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '30%'}" autoFocus="false"> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/home/administration.component.scss b/src/frontend/app/administration/home/administration.component.scss index d9b6c7cf5fa68fb67c6ee1cf4259eaf63f6ceed3..caf69389079af8a173c03fa728436114118e66c4 100644 --- a/src/frontend/app/administration/home/administration.component.scss +++ b/src/frontend/app/administration/home/administration.component.scss @@ -1,43 +1,93 @@ +@import '../../../css/vars.scss'; + .adminArea { - display: flex; - flex-flow: row wrap; - } - - .adminArea_1{ - flex: 1; - overflow: hidden; - padding:20px; - } - - .adminArea_2{ - overflow: hidden; - padding:20px; - } - - .adminArea_3{ - overflow: hidden; - padding:20px; - } - - .adminArea_4{ - overflow: hidden; - padding:20px; - } + display: flex; + flex-flow: row wrap; +} + +.adminArea_1 { + flex: 1; + overflow: hidden; + padding: 20px; +} + +.adminArea_2 { + overflow: hidden; + padding: 20px; +} + +.adminArea_3 { + overflow: hidden; + padding: 20px; +} + +.adminArea_4 { + overflow: hidden; + padding: 20px; +} .loading { - display:flex; - height:100%; + display: flex; + height: 100%; } .adminArea-label { - font-size: 20px; - font-weight: bolder; - opacity: 0.2; - text-align: center + font-size: 20px; + font-weight: bolder; + opacity: 0.2; + text-align: center } .adminArea-button { - white-space:inherit; - height: 100px; - line-height:20px; + white-space: inherit; + height: 100px; + line-height: 20px; +} + +::ng-deep.autocompleteServices { + .mat-optgroup-label { + position: sticky; + top: 0px; + background: + white; + z-index: 1; + } +} + +.countCard { + display: flex; + align-items: center; + gap: 10px; + height: 100px; + color: white; + background: $primary; + cursor: pointer; +} + +.avatarCount { + color: $primary; + align-items: center; + display: flex; + justify-content: center; + font-size: 20px; + background: white; + border-radius: 40px; + padding: 10px; +} + +.avatarCount2 { + color: white; + align-items: center; + display: flex; + justify-content: center; + font-size: 20px; + background: $primary; + border-radius: 40px; + padding: 10px; + width: 45px !important; + height: 45px !important; +} + +.countLabel { + color: $primary; } \ No newline at end of file diff --git a/src/frontend/app/administration/home/administration.component.ts b/src/frontend/app/administration/home/administration.component.ts index e5368cdb5c139029363ca0357189a7a238dab430..75010136327c946fa2352bfc96e66a5c2d6c1074 100644 --- a/src/frontend/app/administration/home/administration.component.ts +++ b/src/frontend/app/administration/home/administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Router } from '@angular/router'; import { LANG } from '../../translate.component'; @@ -6,6 +6,10 @@ import { MatSidenav } from '@angular/material/sidenav'; import { HeaderService } from "../../../service/header.service"; import { AppService } from '../../../service/app.service'; import { PrivilegeService } from '../../../service/privileges.service'; +import { Observable } from 'rxjs'; +import { FormControl } from '@angular/forms'; +import { startWith, map } from 'rxjs/operators'; +import { LatinisePipe } from 'ngx-pipes'; @Component({ templateUrl: "administration.component.html", @@ -14,44 +18,69 @@ import { PrivilegeService } from '../../../service/privileges.service'; }) export class AdministrationComponent implements OnInit { - lang : any = LANG; - loading : boolean = false; + lang: any = LANG; + loading: boolean = false; - organisationServices : any[] = []; - productionServices : any[] = []; - classementServices : any[] = []; - supervisionServices : any[] = []; + organisationServices: any[] = []; + productionServices: any[] = []; + classementServices: any[] = []; + supervisionServices: any[] = []; + + searchService = new FormControl(); + + administrations: any[] = []; + filteredAdministrations: Observable<string[]>; - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('searchServiceInput', { static: true }) searchServiceInput: ElementRef; constructor( - public http: HttpClient, - private router: Router, - private headerService: HeaderService, + public http: HttpClient, + private router: Router, + private headerService: HeaderService, public appService: AppService, - private privilegeService: PrivilegeService) { } + private privilegeService: PrivilegeService, + private latinisePipe: LatinisePipe) { } ngOnInit(): void { this.headerService.setHeader(this.lang.administration); - this.headerService.sideNavLeft = this.sidenavLeft; - - this.loading = true; + //this.loading = true; this.organisationServices = this.privilegeService.getCurrentUserAdministrationsByUnit('organisation'); this.productionServices = this.privilegeService.getCurrentUserAdministrationsByUnit('production'); this.classementServices = this.privilegeService.getCurrentUserAdministrationsByUnit('classement'); this.supervisionServices = this.privilegeService.getCurrentUserAdministrationsByUnit('supervision'); + this.administrations = this.organisationServices.concat(this.productionServices).concat(this.classementServices).concat(this.supervisionServices); + + this.filteredAdministrations = this.searchService.valueChanges + .pipe( + startWith(''), + map(value => this._filter(value, 'administrations')) + ); + this.loading = false; + + setTimeout(() => { + this.searchServiceInput.nativeElement.focus(); + }, 0); } goToSpecifiedAdministration(service: any): void { if (service.angular === true) { - this.router.navigate([service.route]); + this.router.navigate([service.route]); } else { window.location.assign(service.route); } } + + private _filter(value: string, type: string): string[] { + if (typeof value === 'string') { + const filterValue = this.latinisePipe.transform(value.toLowerCase()); + return this[type].filter((option: any) => this.latinisePipe.transform(option['label'].toLowerCase()).includes(filterValue)); + } else { + return this[type]; + } + } } diff --git a/src/frontend/app/administration/indexingModel/indexing-model-administration.component.html b/src/frontend/app/administration/indexingModel/indexing-model-administration.component.html index 9f2508f3e1148ebe69de771ed8f8cd4f2e43208e..89c307de5383c3789c01eee106424256c2baff74 100644 --- a/src/frontend/app/administration/indexingModel/indexing-model-administration.component.html +++ b/src/frontend/app/administration/indexingModel/indexing-model-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -27,8 +21,8 @@ <div style="display: flex;"> <mat-form-field> <mat-label>{{lang.category_id}}</mat-label> - <mat-select name="category" [(ngModel)]="indexingModel.category" [placeholder]="lang.category_id" - required (selectionChange)="changeCategory($event)"> + <mat-select name="category" [(ngModel)]="indexingModel.category" + [placeholder]="lang.category_id" required (selectionChange)="changeCategory($event)"> <mat-option *ngFor="let category of categoriesList;let i=index" [value]="category.id"> {{category.label}} </mat-option> @@ -54,7 +48,7 @@ </app-indexing-form> <div class="col-md-12 text-center"> <button mat-raised-button color="primary" (click)="onSubmit()" - [disabled]="(!indexingForm.isModified() && !isModified()) || indexingModel.label === ''">{{creationMode ? lang.save : lang.update}}</button> + [disabled]="(!indexingForm.isModified() && !isModified()) || indexingModel.label === ''">{{creationMode ? lang.save : lang.update}}</button> </div> </mat-tab> </mat-tab-group> @@ -62,10 +56,8 @@ </div> </div> </mat-sidenav-content> - - <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" - [fixedInViewport]="appService.getViewMode()" fixedTopGap="56" position='end' opened - class="col-md-4 col-sm-12"> + <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" + fixedTopGap="56" position='end' opened class="col-md-4 col-sm-12"> <mat-tab-group> <mat-tab [label]="lang.availableFields"> <app-field-list *ngIf="indexingForm !== undefined" [dataFields]="indexingForm.getAvailableFields()"> @@ -73,8 +65,8 @@ </mat-tab> <mat-tab [label]="lang.availableCustomFields"> <app-field-list *ngIf="indexingForm !== undefined" - [dataCustomFields]="indexingForm.getAvailableCustomFields()"></app-field-list> + [dataCustomFields]="indexingForm.getAvailableCustomFields()"></app-field-list> </mat-tab> </mat-tab-group> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/indexingModel/indexing-model-administration.component.ts b/src/frontend/app/administration/indexingModel/indexing-model-administration.component.ts index ca7906ee0a6f3357381d241ceb4f8665382142e8..b028033b70c2620c0b57d8077b65c1ecb7312667 100644 --- a/src/frontend/app/administration/indexingModel/indexing-model-administration.component.ts +++ b/src/frontend/app/administration/indexingModel/indexing-model-administration.component.ts @@ -25,7 +25,6 @@ declare function $j(selector: any): any; export class IndexingModelAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; @ViewChild('indexingForm', { static: false }) indexingForm: IndexingFormComponent; @@ -64,9 +63,6 @@ export class IndexingModelAdministrationComponent implements OnInit { } ngOnInit(): void { - - this.headerService.sideNavLeft = this.sidenavLeft; - this.route.params.subscribe((params) => { if (typeof params['id'] == "undefined") { this.creationMode = true; diff --git a/src/frontend/app/administration/indexingModel/indexing-models-administration.component.html b/src/frontend/app/administration/indexingModel/indexing-models-administration.component.html index 868d4dd66a31c5e5aa7f57ba4e1a57ec84efb058..a702e6eca96d4277da95d0d708eac25f9acc468d 100644 --- a/src/frontend/app/administration/indexingModel/indexing-models-administration.component.html +++ b/src/frontend/app/administration/indexingModel/indexing-models-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/indexingModels/new"> @@ -13,13 +9,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> diff --git a/src/frontend/app/administration/indexingModel/indexing-models-administration.component.ts b/src/frontend/app/administration/indexingModel/indexing-models-administration.component.ts index 048c2da72e2bf2b3fafa7bf3a46365a3426290eb..df4541278d9fce5648d9661a93dcef6d59eff326 100644 --- a/src/frontend/app/administration/indexingModel/indexing-models-administration.component.ts +++ b/src/frontend/app/administration/indexingModel/indexing-models-administration.component.ts @@ -1,9 +1,8 @@ -import { Component, ViewChild, OnInit } from '@angular/core'; +import { Component, ViewChild, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { MatPaginator } from '@angular/material/paginator'; -import { MatSidenav } from '@angular/material/sidenav'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { HeaderService } from '../../../service/header.service'; @@ -25,8 +24,7 @@ declare function $j(selector: any): any; export class IndexingModelsAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; search: string = null; @@ -59,12 +57,13 @@ export class IndexingModelsAdministrationComponent implements OnInit { private headerService: HeaderService, public appService: AppService, private dialog: MatDialog, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { } ngOnInit(): void { - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/notification/notification-administration.component.html b/src/frontend/app/administration/notification/notification-administration.component.html index 64e29e595a18365992f6abccef23913f4477f762..7b26201338e344ee0e381cf8cbb718948f7e216c 100755 --- a/src/frontend/app/administration/notification/notification-administration.component.html +++ b/src/frontend/app/administration/notification/notification-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item (click)="createScript()" *ngIf="!creationMode && !loading && !notification.scriptcreated"> @@ -12,26 +8,27 @@ {{lang.createScriptNotification}} </p> </a> - <a mat-list-item *ngIf="!creationMode && !loading && notification.is_enabled == 'N'" (click)="toggleNotif()"> + <a mat-list-item *ngIf="!creationMode && !loading && notification.is_enabled == 'N'" + (click)="toggleNotif()"> <mat-icon color="accent" mat-list-icon class="fa fa-play"></mat-icon> <p mat-line> {{lang.activateNotification}} </p> </a> - <a mat-list-item *ngIf="!creationMode && !loading && notification.is_enabled == 'Y'" (click)="toggleNotif()"> + <a mat-list-item *ngIf="!creationMode && !loading && notification.is_enabled == 'Y'" + (click)="toggleNotif()"> <mat-icon color="warn" mat-list-icon class="fa fa-pause"></mat-icon> <p mat-line> {{lang.suspendNotification}} </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -46,40 +43,48 @@ <mat-spinner style="margin:auto;"></mat-spinner> </div> <mat-card *ngIf="!loading" class="card-app-content"> - <div *ngIf="notification.is_enabled == 'N'" class="text-warning" style="position: absolute;opacity: 0.1;font-size: 120px;transform: rotate(324deg);-webkit-transform: rotate(324deg);margin-left: 25%;margin-top: 90px;">{{lang.suspended}}</div> + <div *ngIf="notification.is_enabled == 'N'" class="text-warning" + style="position: absolute;opacity: 0.1;font-size: 120px;transform: rotate(324deg);-webkit-transform: rotate(324deg);margin-left: 25%;margin-top: 90px;"> + {{lang.suspended}}</div> <form class="form-horizontal" (ngSubmit)="onSubmit()" #notificationsFormUp="ngForm"> <div class="form-group"> <div class="col-md-12"> <mat-form-field> - <input matInput [(ngModel)]="notification.notification_id" required name="notification_id" id="notification_id" title="{{lang.id}}" - type="text" pattern="^[\w.-]*$" placeholder="{{lang.id}}" maxlength="50" [disabled]="!creationMode"> + <input matInput [(ngModel)]="notification.notification_id" required + name="notification_id" id="notification_id" title="{{lang.id}}" type="text" + pattern="^[\w.-]*$" placeholder="{{lang.id}}" maxlength="50" + [disabled]="!creationMode"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-md-12"> <mat-form-field> - <input matInput [(ngModel)]="notification.description" required name="description" id="description" title="{{lang.description}}" - type="text" placeholder="{{lang.description}}" maxlength="255"> + <input matInput [(ngModel)]="notification.description" required name="description" + id="description" title="{{lang.description}}" type="text" + placeholder="{{lang.description}}" maxlength="255"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-md-12"> <mat-form-field> - <mat-select id="event_id" name="event_id" title="{{lang.NotificationEvent}}" placeholder="{{lang.NotificationEvent}}" [(ngModel)]="notification.event_id" - required> + <mat-select id="event_id" name="event_id" title="{{lang.NotificationEvent}}" + placeholder="{{lang.NotificationEvent}}" [(ngModel)]="notification.event_id" + required> <mat-optgroup label="{{lang.triggerSystem}} :"> <ng-container *ngFor="let event of notification.data.event"> <mat-option *ngIf="!isNumber(event.id)" [value]="event.id"> - <mat-icon class="fa fa-cog" color="primary" style="height:auto;"></mat-icon> {{event.label_action}} + <mat-icon class="fa fa-cog" color="primary" style="height:auto;"> + </mat-icon> {{event.label_action}} </mat-option> </ng-container> </mat-optgroup> <mat-optgroup label="{{lang.triggerAction}} :"> <ng-container *ngFor="let event of notification.data.event"> <mat-option *ngIf="isNumber(event.id)" [value]="event.id"> - <mat-icon class="fa fa-exchange-alt" color="primary" style="height:auto;"></mat-icon> {{event.label_action}} + <mat-icon class="fa fa-exchange-alt" color="primary" + style="height:auto;"></mat-icon> {{event.label_action}} </mat-option> </ng-container> </mat-optgroup> @@ -91,9 +96,11 @@ <div class="form-group"> <div class="col-md-8"> <mat-form-field> - <mat-select id="template_id" name="template_id" title="{{lang.notificationModel}}" placeholder="{{lang.notificationModel}}" - [(ngModel)]="notification.template_id" required> - <mat-option *ngFor="let template of notification.data.template" [value]="template.template_id"> + <mat-select id="template_id" name="template_id" title="{{lang.notificationModel}}" + placeholder="{{lang.notificationModel}}" [(ngModel)]="notification.template_id" + required> + <mat-option *ngFor="let template of notification.data.template" + [value]="template.template_id"> {{template.template_label}} </mat-option> </mat-select> @@ -101,7 +108,8 @@ </div> <div class="col-md-4"> <mat-form-field> - <mat-select id="attachfor_type" name="attachfor_type" title="{{lang.attachment}}" placeholder="{{lang.attachment}}" [(ngModel)]="notification.attachfor_type"> + <mat-select id="attachfor_type" name="attachfor_type" title="{{lang.attachment}}" + placeholder="{{lang.attachment}}" [(ngModel)]="notification.attachfor_type"> <mat-option value=""> {{lang.noAttachment}} </mat-option> @@ -115,27 +123,36 @@ <div class="form-group"> <div class="col-md-4"> <mat-form-field> - <mat-select id="diffusion_type" name="diffusion_type" title="{{lang.sendTo}}" placeholder="{{lang.sendTo}}" - [(ngModel)]="notification.diffusion_type" required> - <mat-optgroup label="{{lang.memberUserDest}} :" *ngIf="notification.event_id != 'baskets'"> + <mat-select id="diffusion_type" name="diffusion_type" title="{{lang.sendTo}}" + placeholder="{{lang.sendTo}}" [(ngModel)]="notification.diffusion_type" + required> + <mat-optgroup label="{{lang.memberUserDest}} :" + *ngIf="notification.event_id != 'baskets'"> <ng-container *ngFor="let diffusionType of notification.data.diffusionType"> - <mat-option *ngIf="diffusionType.id == 'dest_user'" [value]="diffusionType.id">{{diffusionType.label}}</mat-option> + <mat-option *ngIf="diffusionType.id == 'dest_user'" + [value]="diffusionType.id">{{diffusionType.label}}</mat-option> </ng-container> </mat-optgroup> - <mat-optgroup label="{{lang.memberUsersCopy}} :" *ngIf="notification.event_id != 'baskets'"> + <mat-optgroup label="{{lang.memberUsersCopy}} :" + *ngIf="notification.event_id != 'baskets'"> <ng-container *ngFor="let diffusionType of notification.data.diffusionType"> - <mat-option *ngIf="diffusionType.id == 'copy_list'" [value]="diffusionType.id">{{diffusionType.label}}</mat-option> + <mat-option *ngIf="diffusionType.id == 'copy_list'" + [value]="diffusionType.id">{{diffusionType.label}}</mat-option> </ng-container> </mat-optgroup> <mat-optgroup label="{{lang.memberAllUsers}} :"> <ng-container *ngFor="let diffusionType of notification.data.diffusionType"> - <mat-option *ngIf="diffusionType.id == 'group' || (diffusionType.id == 'entity' && notification.event_id != 'baskets') || (diffusionType.id == 'user' && notification.event_id != 'baskets')" [value]="diffusionType.id">{{diffusionType.label}}</mat-option> + <mat-option + *ngIf="diffusionType.id == 'group' || (diffusionType.id == 'entity' && notification.event_id != 'baskets') || (diffusionType.id == 'user' && notification.event_id != 'baskets')" + [value]="diffusionType.id">{{diffusionType.label}}</mat-option> </ng-container> </mat-optgroup> - <mat-optgroup label="{{lang.others}} :" *ngIf="notification.event_id != 'baskets'"> + <mat-optgroup label="{{lang.others}} :" + *ngIf="notification.event_id != 'baskets'"> <ng-container *ngFor="let diffusionType of notification.data.diffusionType"> - <mat-option *ngIf="diffusionType.id != 'group' && diffusionType.id != 'entity' && diffusionType.id != 'user' && diffusionType.id != 'copy_list' && diffusionType.id != 'group' && diffusionType.id != 'dest_user'" - [value]="diffusionType.id">{{diffusionType.label}}</mat-option> + <mat-option + *ngIf="diffusionType.id != 'group' && diffusionType.id != 'entity' && diffusionType.id != 'user' && diffusionType.id != 'copy_list' && diffusionType.id != 'group' && diffusionType.id != 'dest_user'" + [value]="diffusionType.id">{{diffusionType.label}}</mat-option> </ng-container> </mat-optgroup> </mat-select> @@ -143,32 +160,40 @@ </div> <div class="col-md-8"> <mat-form-field *ngIf="notification.diffusion_type == 'group'"> - <mat-select id="diffusion_properties" name="diffusion_properties" title="{{lang.memberDiffTypeUsers}}" placeholder="{{lang.memberDiffTypeUsers}}" - required multiple [(ngModel)]="notification.diffusion_properties"> - <mat-option *ngFor="let group of notification.data.groups" [value]="group.group_id"> + <mat-select id="diffusion_properties" name="diffusion_properties" + title="{{lang.memberDiffTypeUsers}}" placeholder="{{lang.memberDiffTypeUsers}}" + required multiple [(ngModel)]="notification.diffusion_properties"> + <mat-option *ngFor="let group of notification.data.groups" + [value]="group.group_id"> {{group.group_desc}} </mat-option> </mat-select> </mat-form-field> <mat-form-field *ngIf="notification.diffusion_type == 'user'"> - <mat-select id="diffusion_properties" name="diffusion_properties" title="{{lang.memberDiffTypeUsers}}" placeholder="{{lang.memberDiffTypeUsers}}" - required multiple [(ngModel)]="notification.diffusion_properties"> + <mat-select id="diffusion_properties" name="diffusion_properties" + title="{{lang.memberDiffTypeUsers}}" placeholder="{{lang.memberDiffTypeUsers}}" + required multiple [(ngModel)]="notification.diffusion_properties"> <mat-option *ngFor="let user of notification.data.users" [value]="user.id"> {{user.label}} </mat-option> </mat-select> </mat-form-field> <mat-form-field *ngIf="notification.diffusion_type == 'entity'"> - <mat-select id="diffusion_properties" name="diffusion_properties" title="{{lang.memberDiffTypeUsers}}" placeholder="{{lang.memberDiffTypeUsers}}" - required multiple [(ngModel)]="notification.diffusion_properties"> - <mat-option *ngFor="let entity of notification.data.entities" [value]="entity.entity_id"> + <mat-select id="diffusion_properties" name="diffusion_properties" + title="{{lang.memberDiffTypeUsers}}" placeholder="{{lang.memberDiffTypeUsers}}" + required multiple [(ngModel)]="notification.diffusion_properties"> + <mat-option *ngFor="let entity of notification.data.entities" + [value]="entity.entity_id"> {{entity.entity_label}} </mat-option> </mat-select> </mat-form-field> - <mat-form-field *ngIf="notification.diffusion_type == 'dest_user' || notification.diffusion_type == 'copy_list' || notification.diffusion_type == 'dest_entity' || notification.diffusion_type == 'dest_user_visa' || notification.diffusion_type == 'dest_user_sign'"> - <mat-select id="diffusion_properties" name="diffusion_properties" title="{{lang.selectedDocumentStatus}} (optionnel)" placeholder="{{lang.selectedDocumentStatus}} ({{lang.optional}})" - multiple [(ngModel)]="notification.diffusion_properties"> + <mat-form-field + *ngIf="notification.diffusion_type == 'dest_user' || notification.diffusion_type == 'copy_list' || notification.diffusion_type == 'dest_entity' || notification.diffusion_type == 'dest_user_visa' || notification.diffusion_type == 'dest_user_sign'"> + <mat-select id="diffusion_properties" name="diffusion_properties" + title="{{lang.selectedDocumentStatus}} (optionnel)" + placeholder="{{lang.selectedDocumentStatus}} ({{lang.optional}})" multiple + [(ngModel)]="notification.diffusion_properties"> <mat-option *ngFor="let status of notification.data.status" [value]="status.id"> {{status.label_status}} </mat-option> @@ -178,7 +203,8 @@ </div> <div class="form-group"> <div class="col-sm-12" style="text-align:center;"> - <button mat-raised-button color="primary" type="submit" [disabled]="!notificationsFormUp.form.valid">{{lang.save}}</button> + <button mat-raised-button color="primary" type="submit" + [disabled]="!notificationsFormUp.form.valid">{{lang.save}}</button> </div> </div> </form> @@ -186,4 +212,4 @@ </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/notification/notification-administration.component.ts b/src/frontend/app/administration/notification/notification-administration.component.ts index 35c4d4be79b60e9296ae5674a3fc50066c8ff02e..c5d0c6d557d9d6f1661eca2d66fcd0126eedb7d5 100755 --- a/src/frontend/app/administration/notification/notification-administration.component.ts +++ b/src/frontend/app/administration/notification/notification-administration.component.ts @@ -1,7 +1,6 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Router, ActivatedRoute } from '@angular/router'; -import { MatSidenav } from '@angular/material/sidenav'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { HeaderService } from '../../../service/header.service'; @@ -15,8 +14,7 @@ declare var $j: any; }) export class NotificationAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; creationMode: boolean; notification: any = { @@ -31,7 +29,8 @@ export class NotificationAdministrationComponent implements OnInit { private router: Router, private notify: NotificationService, private headerService: HeaderService, - public appService: AppService + public appService: AppService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -41,7 +40,7 @@ export class NotificationAdministrationComponent implements OnInit { this.route.params.subscribe((params: any) => { - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); if (typeof params['identifier'] == "undefined") { this.headerService.setHeader(this.lang.notificationCreation); diff --git a/src/frontend/app/administration/notification/notifications-administration.component.html b/src/frontend/app/administration/notification/notifications-administration.component.html index b77540ecea81d5a2e5f20b890701a5a0e992d90e..3656fa70d3a861d016df990fe6b3c6a5c477eb1d 100755 --- a/src/frontend/app/administration/notification/notifications-administration.component.html +++ b/src/frontend/app/administration/notification/notifications-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/notifications/new"> @@ -19,13 +15,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -43,7 +38,8 @@ <div class="row"> <div class="col-md-6 col-xs-6"> <mat-form-field> - <input matInput (keyup)="applyFilter($event.target.value)" placeholder="{{lang.filterBy}}"> + <input matInput (keyup)="applyFilter($event.target.value)" + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> @@ -51,124 +47,146 @@ </mat-paginator> </div> </div> - <mat-table #table [dataSource]="dataSource" matSort matSortActive="notification_id" matSortDirection="asc"> + <mat-table #table [dataSource]="dataSource" matSort matSortActive="notification_id" + matSortDirection="asc"> <ng-container matColumnDef="notification_id"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:1;" [class.hide-for-mobile]="appService.getViewMode()">{{lang.id}}</mat-header-cell> - <mat-cell *matCellDef="let element" style="flex:1;" [class.hide-for-mobile]="appService.getViewMode()"> {{element.notification_id}} </mat-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:1;" + [class.hide-for-mobile]="appService.getViewMode()">{{lang.id}}</mat-header-cell> + <mat-cell *matCellDef="let element" style="flex:1;" + [class.hide-for-mobile]="appService.getViewMode()"> {{element.notification_id}} + </mat-cell> </ng-container> <ng-container matColumnDef="description"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.description}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.description}} + </mat-header-cell> <mat-cell *matCellDef="let element" style="flex:2;"> {{element.description}} </mat-cell> </ng-container> <ng-container matColumnDef="is_enabled"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:1;" [class.hide-for-mobile]="appService.getViewMode()">{{lang.status}}</mat-header-cell> - <mat-cell *matCellDef="let element" matTooltip="{{lang.view}}" style="flex:1;" [class.hide-for-mobile]="appService.getViewMode()"> - <span *ngIf="element.is_enabled == 'Y'" color="primary" class="label">{{lang.active}}</span> - <span *ngIf="element.is_enabled == 'N'" color="warn" class="label">{{lang.suspended}}</span> + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:1;" + [class.hide-for-mobile]="appService.getViewMode()">{{lang.status}}</mat-header-cell> + <mat-cell *matCellDef="let element" matTooltip="{{lang.view}}" style="flex:1;" + [class.hide-for-mobile]="appService.getViewMode()"> + <span *ngIf="element.is_enabled == 'Y'" color="primary" + class="label">{{lang.active}}</span> + <span *ngIf="element.is_enabled == 'N'" color="warn" + class="label">{{lang.suspended}}</span> </mat-cell> </ng-container> <ng-container matColumnDef="notifications"> <mat-header-cell *matHeaderCellDef style="flex:1;"></mat-header-cell> <mat-cell *matCellDef="let element" style="justify-content: flex-end;flex:1;"> - <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" (click)="$event.stopPropagation();deleteNotification(element)"> + <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" + (click)="$event.stopPropagation();deleteNotification(element)"> <mat-icon class="fa fa-trash-alt fa-2x" aria-hidden="true"></mat-icon> </button> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;" routerLink="/administration/notifications/{{row.notification_sid}}" - style="cursor:pointer;" matTooltip="{{lang.view}}"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumns;" + routerLink="/administration/notifications/{{row.notification_sid}}" style="cursor:pointer;" + matTooltip="{{lang.view}}"></mat-row> </mat-table> - <div class="mat-paginator" style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">{{notifications.length}} {{lang.notifications}}</div> + <div class="mat-paginator" + style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> + {{notifications.length}} {{lang.notifications}}</div> </mat-card> </div> </div> </mat-sidenav-content> - <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" fixedTopGap="56" - position='end' [opened]="appService.getViewMode() ? false : false"> - <mat-list> - <h3 mat-subheader>{{lang.notificationSchedule}}</h3> - <form class="form-horizontal" #notifForm="ngForm" style="overflow:hidden;"> - <div class="form-group" style="padding-left:15px;padding-right:15px;"> - <div class="col-sm-4"> - <mat-form-field> - <mat-select name="hour" id="hour" title="{{lang.hour}}" placeholder="{{lang.hour}}" [(ngModel)]="newCron.h" required> - <mat-option *ngFor="let hour of hours" [value]="hour.value"> - {{hour.label}} - </mat-option> - </mat-select> - </mat-form-field> - </div> - <div class="col-sm-4"> - <mat-form-field> - <mat-select name="minute" id="minute" title="{{lang.minute}}" placeholder="{{lang.minute}}" [(ngModel)]="newCron.m" required> - <mat-option *ngFor="let minute of minutes" [value]="minute.value"> - {{minute.label}} - </mat-option> - </mat-select> - </mat-form-field> - </div> - <div class="col-sm-4"> - <mat-form-field> - <mat-select name="day" id="day" title="{{lang.day}}" placeholder="{{lang.day}}" [(ngModel)]="newCron.dow" required> - <mat-option *ngFor="let day of dow" [value]="day.value"> - {{day.label}} - </mat-option> - </mat-select> - </mat-form-field> - </div> + <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" + fixedTopGap="56" position='end' [opened]="appService.getViewMode() ? false : false"> + <mat-list> + <h3 mat-subheader>{{lang.notificationSchedule}}</h3> + <form class="form-horizontal" #notifForm="ngForm" style="overflow:hidden;"> + <div class="form-group" style="padding-left:15px;padding-right:15px;"> + <div class="col-sm-4"> + <mat-form-field> + <mat-select name="hour" id="hour" title="{{lang.hour}}" placeholder="{{lang.hour}}" + [(ngModel)]="newCron.h" required> + <mat-option *ngFor="let hour of hours" [value]="hour.value"> + {{hour.label}} + </mat-option> + </mat-select> + </mat-form-field> </div> - <div class="form-group" style="padding-left:15px;padding-right:15px;"> - <div class="col-sm-6"> - <mat-form-field> - <mat-select name="month" id="month" title="{{lang.month}}" placeholder="{{lang.month}}" [(ngModel)]="newCron.mon" required> - <mat-option *ngFor="let month of months" [value]="month.value"> - {{month.label}} - </mat-option> - </mat-select> - </mat-form-field> - </div> - <div class="col-sm-6"> - <mat-form-field> - <mat-select name="dayM" id="dayM" title="{{lang.dayOfMonth}}" placeholder="{{lang.dayOfMonth}}" [(ngModel)]="newCron.dom" required> - <mat-option *ngFor="let dayM of dom" [value]="dayM.value"> - {{dayM.label}} - </mat-option> - </mat-select> - </mat-form-field> - </div> - <div class="col-sm-12"> - <mat-form-field> - <mat-select name="script" id="script" title="{{lang.script}}" placeholder="{{lang.script}}" [(ngModel)]="newCron.cmd" required> - <mat-option *ngFor="let notif of authorizedNotification" [value]="notif.path"> - {{notif.description}} - </mat-option> - </mat-select> - </mat-form-field> - </div> - <div class="col-sm-12 text-center" style="padding:10px;"> - <button mat-raised-button [disabled]="!notifForm.form.valid" color="primary" (click)="saveCron()">{{lang.save}}</button> - </div> + <div class="col-sm-4"> + <mat-form-field> + <mat-select name="minute" id="minute" title="{{lang.minute}}" placeholder="{{lang.minute}}" + [(ngModel)]="newCron.m" required> + <mat-option *ngFor="let minute of minutes" [value]="minute.value"> + {{minute.label}} + </mat-option> + </mat-select> + </mat-form-field> </div> - </form> - </mat-list> - <mat-divider></mat-divider> - <div class="alert alert-info" role="alert" style="margin:15px;"> - {{lang.NotificationScheduleInfo}} - </div> - <mat-list> - <h3 mat-subheader>{{lang.activeCron}}</h3> - <mat-chip-list #chipList class="mat-chip-list-stacked"> - <span *ngFor="let notif of crontab;let i = index"> - <mat-chip color="primary" *ngIf="notif.state == 'normal'" style="margin:5px;border-radius:0px;display:flex;" - selectable="false" removable="true" (removed)="deleteCron(i)"> - {{notif.description}} - <span style="flex: 1 1 auto;"></span> - <b>{{notif.m}} {{notif.h}} {{notif.dom}} {{notif.mon}} {{notif.dow}}</b> - <mat-icon matTooltip="{{lang.delete}}" matChipRemove color="warn" class="fa fa-times"></mat-icon> - </mat-chip> - </span> - </mat-chip-list> - </mat-list> - </mat-sidenav> + <div class="col-sm-4"> + <mat-form-field> + <mat-select name="day" id="day" title="{{lang.day}}" placeholder="{{lang.day}}" + [(ngModel)]="newCron.dow" required> + <mat-option *ngFor="let day of dow" [value]="day.value"> + {{day.label}} + </mat-option> + </mat-select> + </mat-form-field> + </div> + </div> + <div class="form-group" style="padding-left:15px;padding-right:15px;"> + <div class="col-sm-6"> + <mat-form-field> + <mat-select name="month" id="month" title="{{lang.month}}" placeholder="{{lang.month}}" + [(ngModel)]="newCron.mon" required> + <mat-option *ngFor="let month of months" [value]="month.value"> + {{month.label}} + </mat-option> + </mat-select> + </mat-form-field> + </div> + <div class="col-sm-6"> + <mat-form-field> + <mat-select name="dayM" id="dayM" title="{{lang.dayOfMonth}}" + placeholder="{{lang.dayOfMonth}}" [(ngModel)]="newCron.dom" required> + <mat-option *ngFor="let dayM of dom" [value]="dayM.value"> + {{dayM.label}} + </mat-option> + </mat-select> + </mat-form-field> + </div> + <div class="col-sm-12"> + <mat-form-field> + <mat-select name="script" id="script" title="{{lang.script}}" placeholder="{{lang.script}}" + [(ngModel)]="newCron.cmd" required> + <mat-option *ngFor="let notif of authorizedNotification" [value]="notif.path"> + {{notif.description}} + </mat-option> + </mat-select> + </mat-form-field> + </div> + <div class="col-sm-12 text-center" style="padding:10px;"> + <button mat-raised-button [disabled]="!notifForm.form.valid" color="primary" + (click)="saveCron()">{{lang.save}}</button> + </div> + </div> + </form> + </mat-list> + <mat-divider></mat-divider> + <div class="alert alert-info" role="alert" style="margin:15px;"> + {{lang.NotificationScheduleInfo}} + </div> + <mat-list> + <h3 mat-subheader>{{lang.activeCron}}</h3> + <mat-chip-list #chipList class="mat-chip-list-stacked"> + <span *ngFor="let notif of crontab;let i = index"> + <mat-chip color="primary" *ngIf="notif.state == 'normal'" + style="margin:5px;border-radius:0px;display:flex;" selectable="false" removable="true" + (removed)="deleteCron(i)"> + {{notif.description}} + <span style="flex: 1 1 auto;"></span> + <b>{{notif.m}} {{notif.h}} {{notif.dom}} {{notif.mon}} {{notif.dow}}</b> + <mat-icon matTooltip="{{lang.delete}}" matChipRemove color="warn" class="fa fa-times"> + </mat-icon> + </mat-chip> + </span> + </mat-chip-list> + </mat-list> + </mat-sidenav> </mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/notification/notifications-administration.component.ts b/src/frontend/app/administration/notification/notifications-administration.component.ts index 0c992b7e47728f1de81d9987f9cfe3812c083363..bef18a1ee1648952bdea51458c2be1e820a5dd45 100755 --- a/src/frontend/app/administration/notification/notifications-administration.component.ts +++ b/src/frontend/app/administration/notification/notifications-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, ViewChild, OnInit } from '@angular/core'; +import { Component, ViewChild, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { MatPaginator } from '@angular/material/paginator'; @@ -18,8 +18,8 @@ declare function $j(selector: any): any; }) export class NotificationsAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; notifications: any[] = []; loading: boolean = false; @@ -64,7 +64,8 @@ export class NotificationsAdministrationComponent implements OnInit { private notify: NotificationService, private headerService: HeaderService, public appService: AppService, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -72,7 +73,7 @@ export class NotificationsAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.notifications); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/parameter/parameter-administration.component.html b/src/frontend/app/administration/parameter/parameter-administration.component.html index 47dca96646005c095ea2be0fff7bc77485cff3f6..f675446e8f8684f7002680476499e20d80e87bc3 100755 --- a/src/frontend/app/administration/parameter/parameter-administration.component.html +++ b/src/frontend/app/administration/parameter/parameter-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> diff --git a/src/frontend/app/administration/parameter/parameter-administration.component.ts b/src/frontend/app/administration/parameter/parameter-administration.component.ts index 4877d552faa33b73615d4a576acddaa76fef58b4..e628bab860770b4a04e142e0c70b3a2238afb702 100755 --- a/src/frontend/app/administration/parameter/parameter-administration.component.ts +++ b/src/frontend/app/administration/parameter/parameter-administration.component.ts @@ -1,10 +1,9 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Router, ActivatedRoute } from '@angular/router'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { HeaderService } from '../../../service/header.service'; -import { MatSidenav } from '@angular/material/sidenav'; import { AppService } from '../../../service/app.service'; declare function $j(selector: any): any; @@ -15,9 +14,6 @@ declare function $j(selector: any): any; }) export class ParameterAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; - lang : any = LANG; loading : boolean = false; @@ -42,8 +38,6 @@ export class ParameterAdministrationComponent implements OnInit { this.route.params.subscribe((params) => { - this.headerService.sideNavLeft = this.sidenavLeft; - if (typeof params['id'] == "undefined") { this.headerService.setHeader(this.lang.parameterCreation); diff --git a/src/frontend/app/administration/parameter/parameters-administration.component.html b/src/frontend/app/administration/parameter/parameters-administration.component.html index 34ff89c4bf024c2836e789d3f9f8529e93c7f76d..da0cfc8c56e2b9e8696460f45315246aa0e5f5e6 100755 --- a/src/frontend/app/administration/parameter/parameters-administration.component.html +++ b/src/frontend/app/administration/parameter/parameters-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/parameters/new"> @@ -13,13 +9,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -37,7 +32,8 @@ <div class="row"> <div class="col-md-6 col-xs-6"> <mat-form-field> - <input matInput (keyup)="applyFilter($event.target.value)" placeholder="{{lang.filterBy}}"> + <input matInput (keyup)="applyFilter($event.target.value)" + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> @@ -52,7 +48,9 @@ {{element.id}} </mat-cell> </ng-container> <ng-container matColumnDef="description"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()">{{lang.description}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()">{{lang.description}} + </mat-header-cell> <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()"> {{element.description}} </mat-cell> </ng-container> @@ -64,17 +62,22 @@ <ng-container matColumnDef="actions"> <mat-header-cell *matHeaderCellDef></mat-header-cell> <mat-cell *matCellDef="let element" style="justify-content: flex-end;"> - <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" (click)="$event.stopPropagation();deleteParameter(element.id)"> + <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" + (click)="$event.stopPropagation();deleteParameter(element.id)"> <mat-icon class="fa fa-trash-alt fa-2x" aria-hidden="true"></mat-icon> </button> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;" routerLink="/administration/parameters/{{row.id}}" style="cursor:pointer;" matTooltip="{{lang.view}}"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumns;" + routerLink="/administration/parameters/{{row.id}}" style="cursor:pointer;" + matTooltip="{{lang.view}}"></mat-row> </mat-table> - <div class="mat-paginator" style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">{{parameters.length}} {{lang.parameters}}</div> + <div class="mat-paginator" + style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> + {{parameters.length}} {{lang.parameters}}</div> </mat-card> </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/parameter/parameters-administration.component.ts b/src/frontend/app/administration/parameter/parameters-administration.component.ts index 3fe60c4ba2929a92bfce509c57ee0eec96e2ead6..274641a854903bd41b52cd61a7cac1a95b137323 100755 --- a/src/frontend/app/administration/parameter/parameters-administration.component.ts +++ b/src/frontend/app/administration/parameter/parameters-administration.component.ts @@ -1,10 +1,9 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { HeaderService } from '../../../service/header.service'; import { MatPaginator } from '@angular/material/paginator'; -import { MatSidenav } from '@angular/material/sidenav'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { AppService } from '../../../service/app.service'; @@ -18,8 +17,7 @@ declare function $j(selector: any): any; }) export class ParametersAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; @@ -38,7 +36,8 @@ export class ParametersAdministrationComponent implements OnInit { private notify: NotificationService, private headerService: HeaderService, public appService: AppService, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -55,7 +54,7 @@ export class ParametersAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.parameters); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/priority/priorities-administration.component.html b/src/frontend/app/administration/priority/priorities-administration.component.html index 7cdcfc486685a61e95bf2ef30686df92946c0739..1c128d80c3323757ab2cf1c19b12af8c4ed1cb3a 100755 --- a/src/frontend/app/administration/priority/priorities-administration.component.html +++ b/src/frontend/app/administration/priority/priorities-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/priorities/new"> @@ -19,13 +15,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -43,7 +38,8 @@ <div class="row"> <div class="col-md-6 col-xs-6"> <mat-form-field> - <input matInput (keyup)="applyFilter($event.target.value)" placeholder="{{lang.filterBy}}"> + <input matInput (keyup)="applyFilter($event.target.value)" + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> @@ -53,55 +49,65 @@ </div> <mat-table #table [dataSource]="dataSource" matSort matSortActive="label" matSortDirection="asc"> <ng-container matColumnDef="id"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.technicalId}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.technicalId}} + </mat-header-cell> <mat-cell *matCellDef="let element" style="flex:2;"> - <span (click)="$event.stopPropagation()"> - {{element.id}} - </span> + <span (click)="$event.stopPropagation()"> + {{element.id}} + </span> </mat-cell> </ng-container> <ng-container matColumnDef="label"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.label}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.label}} + </mat-header-cell> <mat-cell *matCellDef="let element" style="flex:2;"> - <input type="color" value="{{element.color}}" style="background:none;border:none;width:45px;" disabled> {{element.label}} + <input type="color" value="{{element.color}}" + style="background:none;border:none;width:45px;" disabled> {{element.label}} </mat-cell> </ng-container> <ng-container matColumnDef="delays"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()" style="flex:2;">{{lang.processDelayDay}}</mat-header-cell> - <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()" style="flex:2;"> - <span> - {{element.delays}} - </span> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()" style="flex:2;"> + {{lang.processDelayDay}}</mat-header-cell> + <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()" + style="flex:2;"> + <span> + {{element.delays}} + </span> </mat-cell> </ng-container> <ng-container matColumnDef="actions"> <mat-header-cell *matHeaderCellDef></mat-header-cell> <mat-cell *matCellDef="let element" style="justify-content: flex-end;"> - <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" (click)="$event.stopPropagation();deletePriority(element.id)"> + <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" + (click)="$event.stopPropagation();deletePriority(element.id)"> <mat-icon class="fa fa-trash-alt fa-2x" aria-hidden="true"></mat-icon> </button> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;" routerLink="/administration/priorities/{{row.id}}" style="cursor:pointer;" matTooltip="{{lang.view}}"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumns;" + routerLink="/administration/priorities/{{row.id}}" style="cursor:pointer;" + matTooltip="{{lang.view}}"></mat-row> </mat-table> - <div class="mat-paginator" style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">{{priorities.length}} {{lang.priorities}}</div> + <div class="mat-paginator" + style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> + {{priorities.length}} {{lang.priorities}}</div> </mat-card> </div> </div> </mat-sidenav-content> - - <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" fixedTopGap="56" - position='end' [opened]="appService.getViewMode() ? false : false"> + <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" + fixedTopGap="56" position='end' [opened]="appService.getViewMode() ? false : false"> <p style="font-size:15px;padding:5px"> {{lang.prioritiesHelpDesc}} </p> <mat-list> - <span dnd-sortable-container [dropZones]="['boxers-zone']" [sortableData]="prioritiesOrder"> - <mat-list-item disableRipple="true" *ngFor="let priority of prioritiesOrder;let i = index" title="{{lang.move}}" dnd-sortable - [sortableIndex]="i" (onDropSuccess)="updatePrioritiesOrder()"> - <mat-icon color="primary" mat-list-icon class="fa fa-inbox"></mat-icon> - <p mat-line>{{i+1}} - {{priority.label}}</p> - </mat-list-item> - </span> + <span dnd-sortable-container [dropZones]="['boxers-zone']" [sortableData]="prioritiesOrder"> + <mat-list-item disableRipple="true" *ngFor="let priority of prioritiesOrder;let i = index" + title="{{lang.move}}" dnd-sortable [sortableIndex]="i" (onDropSuccess)="updatePrioritiesOrder()"> + <mat-icon color="primary" mat-list-icon class="fa fa-inbox"></mat-icon> + <p mat-line>{{i+1}} - {{priority.label}}</p> + </mat-list-item> + </span> </mat-list> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/priority/priorities-administration.component.ts b/src/frontend/app/administration/priority/priorities-administration.component.ts index 779cf5dae2060d448b7bb697c719b9d63d61e3af..7979fc8349da16f605a8d5eff9a0eff67d5a43db 100755 --- a/src/frontend/app/administration/priority/priorities-administration.component.ts +++ b/src/frontend/app/administration/priority/priorities-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; @@ -17,9 +17,9 @@ declare function $j(selector: any): any; providers: [AppService] }) export class PrioritiesAdministrationComponent implements OnInit { - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; + @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang : any = LANG; loading : boolean = false; @@ -46,7 +46,8 @@ export class PrioritiesAdministrationComponent implements OnInit { private notify: NotificationService, private headerService: HeaderService, public appService: AppService, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -54,7 +55,7 @@ export class PrioritiesAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.priorities); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/priority/priority-administration.component.html b/src/frontend/app/administration/priority/priority-administration.component.html index 47af322aa74c3395f016b47cffee31cfd7683ed7..714a1426d5119e49eab63d0d59ea9613cb4bae26 100755 --- a/src/frontend/app/administration/priority/priority-administration.component.html +++ b/src/frontend/app/administration/priority/priority-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -30,13 +24,14 @@ <div class="col-md-1 col-xs-2"> <mat-form-field> <input matInput type="color" name="color" matTooltip="{{lang.chooseColor}}" - [(ngModel)]="priority.color" required> + [(ngModel)]="priority.color" required> </mat-form-field> </div> <div class="col-md-11 col-xs-10"> <mat-form-field> - <input matInput type="text" name="label" title="{{lang.label}}" placeholder="{{lang.label}}" - [(ngModel)]="priority.label" maxlength="128" required> + <input matInput type="text" name="label" title="{{lang.label}}" + placeholder="{{lang.label}}" [(ngModel)]="priority.label" maxlength="128" + required> </mat-form-field> </div> </div> @@ -44,16 +39,15 @@ <div class="form-group"> <div class="col-md-4"> <mat-form-field> - <input matInput type="number" name="delays" - placeholder="{{lang.processDelayDay}}" [(ngModel)]="priority.delays" required - pattern="^\d+$"> + <input matInput type="number" name="delays" placeholder="{{lang.processDelayDay}}" + [(ngModel)]="priority.delays" required pattern="^\d+$"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-md-12 text-center" style="padding:10px;"> <button mat-raised-button [disabled]="!priorityForm.form.valid" - color="primary">{{lang.save}}</button> + color="primary">{{lang.save}}</button> </div> </div> </form> @@ -61,4 +55,4 @@ </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/priority/priority-administration.component.ts b/src/frontend/app/administration/priority/priority-administration.component.ts index 90afaaf3c352e4f60c0e59fb1c19a85e7b95f297..c43a6c825723e69487fcbd8d5e7e87ca3884b26b 100755 --- a/src/frontend/app/administration/priority/priority-administration.component.ts +++ b/src/frontend/app/administration/priority/priority-administration.component.ts @@ -1,9 +1,8 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Router, ActivatedRoute } from '@angular/router'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; -import { MatSidenav } from '@angular/material/sidenav'; import { HeaderService } from '../../../service/header.service'; import { AppService } from '../../../service/app.service'; @@ -14,10 +13,6 @@ declare function $j(selector: any): any; providers: [AppService] }) export class PriorityAdministrationComponent implements OnInit { - - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; id : string; creationMode : boolean; @@ -45,8 +40,6 @@ export class PriorityAdministrationComponent implements OnInit { this.route.params.subscribe((params) => { - this.headerService.sideNavLeft = this.sidenavLeft; - if (typeof params['id'] == "undefined") { this.headerService.setHeader(this.lang.priorityCreation); diff --git a/src/frontend/app/administration/report/reports-administration.component.html b/src/frontend/app/administration/report/reports-administration.component.html index afbd6e8e7381e999eb5fbefb973cfec70e406b51..37b7d9530d7a69773430a765ef180b71c79149c6 100755 --- a/src/frontend/app/administration/report/reports-administration.component.html +++ b/src/frontend/app/administration/report/reports-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -24,17 +18,18 @@ <mat-spinner style="margin:auto;"></mat-spinner> </div> <mat-card *ngIf="!loading" class="card-app-content"> - <mat-tab-group [(selectedIndex)]="selectedTabIndex_2" *ngIf="!creationMode" (selectedTabChange)="loadReports($event.index)"> + <mat-tab-group [(selectedIndex)]="selectedTabIndex_2" *ngIf="!creationMode" + (selectedTabChange)="loadReports($event.index)"> <mat-tab *ngFor="let group of groups" label="{{group.group_desc}"> <ng-template mat-tab-label> {{group.group_desc}} </ng-template> - <div *ngIf="loadingOptions"> - <mat-spinner style="margin:auto;"></mat-spinner> - </div> - <form> - <mat-list *ngIf="reports.length > 0 && !loadingOptions"> - <!--{{lang.folders}} + <div *ngIf=" loadingOptions"> + <mat-spinner style="margin:auto;"></mat-spinner> + </div> + <form> + <mat-list *ngIf="reports.length > 0 && !loadingOptions"> + <!--{{lang.folders}} <mat-divider></mat-divider> <span *ngFor="let report of reports;let i = index"> <mat-list-item *ngIf="report.module == 'folder'"> @@ -45,34 +40,32 @@ </mat-list-item> </span>--> - {{lang.entities}} - <mat-divider></mat-divider> - <span *ngFor="let report of reports;let i = index"> - <mat-list-item *ngIf="report.module == 'entities'"> - <mat-checkbox color="primary" [(ngModel)]="report.checked" (change)="saveReport()" name="report_{{report.module}}_{{i}}" - matTooltip="{{report.desc}}"> - {{report.label}} - </mat-checkbox> - </mat-list-item> - </span> - - - {{lang.maarchApplication}} - <mat-divider></mat-divider> - <span *ngFor="let report of reports;let i = index"> - <mat-list-item *ngIf="report.module == 'application'"> - <mat-checkbox color="primary" [(ngModel)]="report.checked" (change)="saveReport()" name="report_{{report.module}}_{{i}}" - matTooltip="{{report.desc}}"> - {{report.label}} - </mat-checkbox> - </mat-list-item> - </span> - </mat-list> - </form> - </mat-tab> - </mat-tab-group> - </mat-card> - </div> + {{lang.entities}} + <mat-divider></mat-divider> + <span *ngFor="let report of reports;let i = index"> + <mat-list-item *ngIf="report.module == 'entities'"> + <mat-checkbox color="primary" [(ngModel)]="report.checked" (change)="saveReport()" + name="report_{{report.module}}_{{i}}" matTooltip="{{report.desc}}"> + {{report.label}} + </mat-checkbox> + </mat-list-item> + </span> + {{lang.maarchApplication}} + <mat-divider></mat-divider> + <span *ngFor="let report of reports;let i = index"> + <mat-list-item *ngIf="report.module == 'application'"> + <mat-checkbox color="primary" [(ngModel)]="report.checked" (change)="saveReport()" + name="report_{{report.module}}_{{i}}" matTooltip="{{report.desc}}"> + {{report.label}} + </mat-checkbox> + </mat-list-item> + </span> + </mat-list> + </form> + </mat-tab> + </mat-tab-group> + </mat-card> + </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/report/reports-administration.component.ts b/src/frontend/app/administration/report/reports-administration.component.ts index 33528e8c3c1d4c313702585d87697e13c614124b..9b76d7e125ac8dc48de37c960235236d25c3c474 100755 --- a/src/frontend/app/administration/report/reports-administration.component.ts +++ b/src/frontend/app/administration/report/reports-administration.component.ts @@ -1,8 +1,7 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; -import { MatSidenav } from '@angular/material/sidenav'; import { HeaderService } from '../../../service/header.service'; import { AppService } from '../../../service/app.service'; @@ -13,10 +12,7 @@ declare function $j(selector: any): any; providers: [AppService] }) export class ReportsAdministrationComponent implements OnInit { - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; - + lang: any = LANG; groups: any[] = []; @@ -38,8 +34,6 @@ export class ReportsAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.reports); - this.headerService.sideNavLeft = this.sidenavLeft; - this.loading = true; this.http.get('../../rest/reports/groups') diff --git a/src/frontend/app/administration/security/securities-administration.component.html b/src/frontend/app/administration/security/securities-administration.component.html index b1a5ee41d0732918944d02e7820fbfe2ca6aa9cd..ea13eacc23ec8ab5affecfefd54c1ce75d13e362 100755 --- a/src/frontend/app/administration/security/securities-administration.component.html +++ b/src/frontend/app/administration/security/securities-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -29,77 +23,105 @@ <form (ngSubmit)="onSubmit()" #passwordForm="ngForm"> <mat-list> <p style="margin-bottom: 40px;text-align: center;"> - <mat-slide-toggle [name]="passwordRules['complexityUpper'].label" [checked]="passwordRules['complexityUpper'].enabled" color="primary" - (change)="toggleRule(passwordRules['complexityUpper']);" style="padding-left:10px;padding-right:10px;">{{passwordRules['complexityUpper'].label}}</mat-slide-toggle> - <mat-slide-toggle [name]="passwordRules['complexityNumber'].label" [checked]="passwordRules['complexityNumber'].enabled" - color="primary" (change)="toggleRule(passwordRules['complexityNumber']);" style="padding-left:10px;padding-right:10px;">{{passwordRules['complexityNumber'].label}}</mat-slide-toggle> - <mat-slide-toggle [name]="passwordRules['complexitySpecial'].label" [checked]="passwordRules['complexitySpecial'].enabled" - color="primary" (change)="toggleRule(passwordRules['complexitySpecial']);" style="padding-left:10px;padding-right:10px;">{{passwordRules['complexitySpecial'].label}}</mat-slide-toggle> + <mat-slide-toggle [name]="passwordRules['complexityUpper'].label" + [checked]="passwordRules['complexityUpper'].enabled" color="primary" + (change)="toggleRule(passwordRules['complexityUpper']);" + style="padding-left:10px;padding-right:10px;"> + {{passwordRules['complexityUpper'].label}}</mat-slide-toggle> + <mat-slide-toggle [name]="passwordRules['complexityNumber'].label" + [checked]="passwordRules['complexityNumber'].enabled" color="primary" + (change)="toggleRule(passwordRules['complexityNumber']);" + style="padding-left:10px;padding-right:10px;"> + {{passwordRules['complexityNumber'].label}}</mat-slide-toggle> + <mat-slide-toggle [name]="passwordRules['complexitySpecial'].label" + [checked]="passwordRules['complexitySpecial'].enabled" color="primary" + (change)="toggleRule(passwordRules['complexitySpecial']);" + style="padding-left:10px;padding-right:10px;"> + {{passwordRules['complexitySpecial'].label}}</mat-slide-toggle> </p> <mat-list-item style="margin-top: 15px;margin-bottom: 15px;"> <mat-icon mat-list-icon> - <mat-slide-toggle style="position: relative;top:-10px;" [checked]="passwordRules['minLength'].enabled" - color="primary" (change)="toggleRule(passwordRules['minLength']);"></mat-slide-toggle> + <mat-slide-toggle style="position: relative;top:-10px;" + [checked]="passwordRules['minLength'].enabled" color="primary" + (change)="toggleRule(passwordRules['minLength']);"></mat-slide-toggle> </mat-icon> <p mat-line> <mat-form-field> - <input type="number" [disabled]="!passwordRules['minLength'].enabled" [name]="passwordRules['minLength'].label" [(ngModel)]="passwordRules['minLength'].value" - min="1" pattern="^[1-9][0-9]*" matInput placeholder="{{passwordRules['minLength'].label}}" - required> + <input type="number" [disabled]="!passwordRules['minLength'].enabled" + [name]="passwordRules['minLength'].label" + [(ngModel)]="passwordRules['minLength'].value" min="1" + pattern="^[1-9][0-9]*" matInput + placeholder="{{passwordRules['minLength'].label}}" required> <span matSuffix> {{lang.chars}}</span> </mat-form-field> </p> </mat-list-item> <mat-list-item style="margin-top: 15px;margin-bottom: 15px;"> <mat-icon mat-list-icon> - <mat-slide-toggle style="position: relative;top:-10px;" [checked]="passwordRules['lockAttempts'].enabled" - color="primary" (change)="toggleRule(passwordRules['lockAttempts']);"></mat-slide-toggle> + <mat-slide-toggle style="position: relative;top:-10px;" + [checked]="passwordRules['lockAttempts'].enabled" color="primary" + (change)="toggleRule(passwordRules['lockAttempts']);"> + </mat-slide-toggle> </mat-icon> <p mat-line style="display:flex;"> <mat-form-field style="flex:1;padding-right: 10px;"> - <input type="number" [disabled]="!passwordRules['lockAttempts'].enabled" [name]="passwordRules['lockAttempts'].label" [(ngModel)]="passwordRules['lockAttempts'].value" - min="1" pattern="^[1-9][0-9]*" matInput placeholder="{{passwordRules['lockAttempts'].label}}" - required> + <input type="number" [disabled]="!passwordRules['lockAttempts'].enabled" + [name]="passwordRules['lockAttempts'].label" + [(ngModel)]="passwordRules['lockAttempts'].value" min="1" + pattern="^[1-9][0-9]*" matInput + placeholder="{{passwordRules['lockAttempts'].label}}" required> </mat-form-field> <mat-form-field style="flex:1;"> - <input type="number" [disabled]="!passwordRules['lockTime'].enabled" [name]="passwordRules['lockTime'].label" [(ngModel)]="passwordRules['lockTime'].value" - min="1" pattern="^[1-9][0-9]*" matInput placeholder="{{passwordRules['lockTime'].label}}" - required> + <input type="number" [disabled]="!passwordRules['lockTime'].enabled" + [name]="passwordRules['lockTime'].label" + [(ngModel)]="passwordRules['lockTime'].value" min="1" + pattern="^[1-9][0-9]*" matInput + placeholder="{{passwordRules['lockTime'].label}}" required> <span matSuffix> {{lang.minutes}}</span> </mat-form-field> </p> </mat-list-item> <mat-list-item style="margin-top: 15px;margin-bottom: 15px;"> <mat-icon mat-list-icon> - <mat-slide-toggle style="position: relative;top:-10px;" [checked]="passwordRules['renewal'].enabled" - color="primary" (change)="toggleRule(passwordRules['renewal']);"></mat-slide-toggle> + <mat-slide-toggle style="position: relative;top:-10px;" + [checked]="passwordRules['renewal'].enabled" color="primary" + (change)="toggleRule(passwordRules['renewal']);"></mat-slide-toggle> </mat-icon> <p mat-line> <mat-form-field> - <input type="number" [disabled]="!passwordRules['renewal'].enabled" [name]="passwordRules['renewal'].label" [(ngModel)]="passwordRules['renewal'].value" - min="1" pattern="^[1-9][0-9]*" matInput placeholder="{{passwordRules['renewal'].label}}" - required> + <input type="number" [disabled]="!passwordRules['renewal'].enabled" + [name]="passwordRules['renewal'].label" + [(ngModel)]="passwordRules['renewal'].value" min="1" + pattern="^[1-9][0-9]*" matInput + placeholder="{{passwordRules['renewal'].label}}" required> <span matSuffix> {{lang.days}}</span> </mat-form-field> </p> </mat-list-item> <mat-list-item style="margin-top: 15px;margin-bottom: 15px;"> <mat-icon mat-list-icon> - <mat-slide-toggle style="position: relative;top:-10px;" [checked]="passwordRules['historyLastUse'].enabled" - color="primary" (change)="toggleRule(passwordRules['historyLastUse']);"></mat-slide-toggle> + <mat-slide-toggle style="position: relative;top:-10px;" + [checked]="passwordRules['historyLastUse'].enabled" color="primary" + (change)="toggleRule(passwordRules['historyLastUse']);"> + </mat-slide-toggle> </mat-icon> <p mat-line> <mat-form-field> - <input type="number" [disabled]="!passwordRules['historyLastUse'].enabled" [name]="passwordRules['historyLastUse'].label" - [(ngModel)]="passwordRules['historyLastUse'].value" min="1" pattern="^[1-9][0-9]*" - matInput placeholder="{{passwordRules['historyLastUse'].label}}" required> + <input type="number" + [disabled]="!passwordRules['historyLastUse'].enabled" + [name]="passwordRules['historyLastUse'].label" + [(ngModel)]="passwordRules['historyLastUse'].value" min="1" + pattern="^[1-9][0-9]*" matInput + placeholder="{{passwordRules['historyLastUse'].label}}" required> </mat-form-field> </p> </mat-list-item> </mat-list> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button type="submit" color="primary" [disabled]="(!passwordForm.valid && !disabledForm()) || checkModif()">{{lang.validate}}</button> - <button mat-raised-button type="button" color="default" [disabled]="checkModif()" (click)="cancelModification()">{{lang.cancel}}</button> + <button mat-raised-button type="submit" color="primary" + [disabled]="(!passwordForm.valid && !disabledForm()) || checkModif()">{{lang.validate}}</button> + <button mat-raised-button type="button" color="default" [disabled]="checkModif()" + (click)="cancelModification()">{{lang.cancel}}</button> </div> </form> </mat-tab> @@ -108,4 +130,4 @@ </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/security/securities-administration.component.ts b/src/frontend/app/administration/security/securities-administration.component.ts index 10a5e9d16f60817e1908cd9e076714eeb3a087f0..76ddff726d58984fac0c3c8d340bf141bfab4da2 100755 --- a/src/frontend/app/administration/security/securities-administration.component.ts +++ b/src/frontend/app/administration/security/securities-administration.component.ts @@ -1,7 +1,6 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; -import { MatSidenav } from '@angular/material/sidenav'; import { NotificationService } from '../../notification.service'; import { HeaderService } from '../../../service/header.service'; import { AppService } from '../../../service/app.service'; @@ -14,9 +13,6 @@ declare function $j(selector: any): any; }) export class SecuritiesAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; - lang : any = LANG; loading : boolean = false; @@ -47,8 +43,6 @@ export class SecuritiesAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.securitiesAdministration); - this.headerService.sideNavLeft = this.sidenavLeft; - this.loading = true; this.http.get('../../rest/passwordRules') diff --git a/src/frontend/app/administration/sendmail/sendmail-administration.component.html b/src/frontend/app/administration/sendmail/sendmail-administration.component.html index aa8f25b989e510681075e2b068036d5605637490..4cd4da598f792204c561d5849777c7afa9603169 100644 --- a/src/frontend/app/administration/sendmail/sendmail-administration.component.html +++ b/src/frontend/app/administration/sendmail/sendmail-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item (click)="snav2.toggle();"> @@ -13,13 +9,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -41,7 +36,8 @@ <div class="col-md-12" style="margin-bottom: 20px;"> <mat-form-field> <mat-select #smtpType name="smtpType" - placeholder="{{lang.configurationType}}" [(ngModel)]="sendmail.type" required> + placeholder="{{lang.configurationType}}" [(ngModel)]="sendmail.type" + required> <mat-option *ngFor="let type of smtpTypeList" [value]="type.id"> {{type.label}} </mat-option> @@ -49,11 +45,13 @@ </mat-form-field> </div> </div> - <div class="form-group" [style.opacity]="['smtp', 'mail'].indexOf(sendmail.type) > -1 ? '1' : '0.5'"> + <div class="form-group" + [style.opacity]="['smtp', 'mail'].indexOf(sendmail.type) > -1 ? '1' : '0.5'"> <div class="col-md-2"> <mat-form-field> - <mat-select name="SMTPSecure" placeholder="{{lang.smtpAuth}}" [disabled]="['smtp', 'mail'].indexOf(sendmail.type) == -1" - [(ngModel)]="sendmail.secure"> + <mat-select name="SMTPSecure" placeholder="{{lang.smtpAuth}}" + [disabled]="['smtp', 'mail'].indexOf(sendmail.type) == -1" + [(ngModel)]="sendmail.secure"> <mat-option *ngFor="let security of smtpSecList" [value]="security.id"> {{security.label}} </mat-option> @@ -62,51 +60,64 @@ </div> <div class="col-md-9"> <mat-form-field> - <input matInput name="host" [disabled]="['smtp', 'mail'].indexOf(sendmail.type) == -1" [(ngModel)]="sendmail.host" - placeholder="{{lang.host}}" required> + <input matInput name="host" + [disabled]="['smtp', 'mail'].indexOf(sendmail.type) == -1" + [(ngModel)]="sendmail.host" placeholder="{{lang.host}}" required> </mat-form-field> </div> <div class="col-md-1"> <mat-form-field> <input name="port" type="number" matInput [(ngModel)]="sendmail.port" - [disabled]="['smtp', 'mail'].indexOf(sendmail.type) == -1" placeholder="{{lang.port}}" required> + [disabled]="['smtp', 'mail'].indexOf(sendmail.type) == -1" + placeholder="{{lang.port}}" required> </mat-form-field> </div> </div> - <div class="form-group" [style.opacity]="['smtp', 'mail'].indexOf(sendmail.type) > -1 ? '1' : '0.5'"> + <div class="form-group" + [style.opacity]="['smtp', 'mail'].indexOf(sendmail.type) > -1 ? '1' : '0.5'"> <div class="col-md-12"> <mat-slide-toggle color="primary" name="SMTPAuth" [(ngModel)]="sendmail.auth" - [disabled]="['smtp', 'mail'].indexOf(sendmail.type) == -1"(change)="cleanAuthInfo($event)">{{lang.enableAuth}}</mat-slide-toggle> + [disabled]="['smtp', 'mail'].indexOf(sendmail.type) == -1" + (change)="cleanAuthInfo($event)">{{lang.enableAuth}}</mat-slide-toggle> </div> </div> - <div class="form-group" [style.opacity]="['smtp', 'mail'].indexOf(sendmail.type) > -1 ? '1' : '0.5'"> + <div class="form-group" + [style.opacity]="['smtp', 'mail'].indexOf(sendmail.type) > -1 ? '1' : '0.5'"> <div class="col-md-12"> <mat-form-field> - <input name="user" [(ngModel)]="sendmail.user" [disabled]="!sendmail.auth || ['smtp', 'mail'].indexOf(sendmail.type) == -1" - matInput placeholder="{{lang.id}}" required> + <input name="user" [(ngModel)]="sendmail.user" + [disabled]="!sendmail.auth || ['smtp', 'mail'].indexOf(sendmail.type) == -1" + matInput placeholder="{{lang.id}}" required> </mat-form-field> </div> <div class="col-md-12"> <mat-form-field> - <input name="password" [type]="hidePassword ? 'password' : 'text'" [(ngModel)]="sendmail.password" - [disabled]="!sendmail.auth || ['smtp', 'mail'].indexOf(sendmail.type) == -1" matInput [placeholder]="sendmail.passwordAlreadyExists === true ? this.lang.passwordModification : this.lang.password" [required]="!sendmail.passwordAlreadyExists"> - <mat-icon color="primary" style="cursor: pointer;" matSuffix (click)="hidePassword = !hidePassword" - class="fa fa-2x" [ngClass]="[hidePassword ? 'fa-eye-slash' : 'fa-eye']"></mat-icon> + <input name="password" [type]="hidePassword ? 'password' : 'text'" + [(ngModel)]="sendmail.password" + [disabled]="!sendmail.auth || ['smtp', 'mail'].indexOf(sendmail.type) == -1" + matInput + [placeholder]="sendmail.passwordAlreadyExists === true ? this.lang.passwordModification : this.lang.password" + [required]="!sendmail.passwordAlreadyExists"> + <mat-icon color="primary" style="cursor: pointer;" matSuffix + (click)="hidePassword = !hidePassword" class="fa fa-2x" + [ngClass]="[hidePassword ? 'fa-eye-slash' : 'fa-eye']"></mat-icon> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-md-12"> <mat-form-field> - <input name="mailFrom" [(ngModel)]="sendmail.from" required - matInput placeholder="{{lang.mailFrom}}" pattern="(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"> + <input name="mailFrom" [(ngModel)]="sendmail.from" required matInput + placeholder="{{lang.mailFrom}}" + pattern="(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"> </mat-form-field> </div> </div> <div class="col-md-12 text-center" style="padding:10px;"> - <button mat-raised-button type="submit" color="primary" [disabled]="checkModif() || !sendmailForm.valid">{{lang.validate}}</button> + <button mat-raised-button type="submit" color="primary" + [disabled]="checkModif() || !sendmailForm.valid">{{lang.validate}}</button> <button mat-raised-button type="button" color="default" [disabled]="checkModif()" - (click)="cancelModification()">{{lang.cancel}}</button> + (click)="cancelModification()">{{lang.cancel}}</button> </div> </form> </mat-tab> @@ -115,20 +126,21 @@ </div> </div> </mat-sidenav-content> - <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - fixedTopGap="56" position='end' [opened]="appService.getViewMode() ? false : false" style="overflow-x:hidden;width:500px;" - (opened)="onSubmit();initEmailSend()"> + fixedTopGap="56" position='end' [opened]="appService.getViewMode() ? false : false" + style="overflow-x:hidden;width:500px;" (opened)="onSubmit();initEmailSend()"> <mat-nav-list disableRipple="true" style="display: flex;flex-direction: column;"> <h3 mat-subheader>{{lang.emailSendTest}}</h3> <div class="form-group"> <div class="col-md-12"> <form #testSendmailForm="ngForm"> <mat-form-field> - <input name="recipientTest" matInput placeholder="{{lang.mailTo}}" [(ngModel)]="recipientTest" [disabled]="emailSendLoading" - pattern="(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"> - <mat-icon *ngIf="!emailSendLoading && testSendmailForm.valid" title="{{lang.beginSendTest}}" (click)="testEmailSend()" - color="primary" style="cursor: pointer;" matSuffix class="fa fa-paper-plane fa-2x"></mat-icon> + <input name="recipientTest" matInput placeholder="{{lang.mailTo}}" + [(ngModel)]="recipientTest" [disabled]="emailSendLoading" + pattern="(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"> + <mat-icon *ngIf="!emailSendLoading && testSendmailForm.valid" title="{{lang.beginSendTest}}" + (click)="testEmailSend()" color="primary" style="cursor: pointer;" matSuffix + class="fa fa-paper-plane fa-2x"></mat-icon> </mat-form-field> </form> </div> @@ -142,4 +154,4 @@ {{this.emailSendResult.debug}} </div> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/sendmail/sendmail-administration.component.ts b/src/frontend/app/administration/sendmail/sendmail-administration.component.ts index 7bf17590cf79cecd4d788519cef7c0a6eb36e9a7..328460bd730ffd65597f1fef331eb9c716610a7b 100644 --- a/src/frontend/app/administration/sendmail/sendmail-administration.component.ts +++ b/src/frontend/app/administration/sendmail/sendmail-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { MatSidenav } from '@angular/material/sidenav'; @@ -16,8 +16,9 @@ declare function $j(selector: any): any; }) export class SendmailAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; + @ViewChild('sendmailForm', { static: false }) public sendmailFormCpt: NgForm; lang: any = LANG; @@ -86,7 +87,8 @@ export class SendmailAdministrationComponent implements OnInit { public http: HttpClient, private notify: NotificationService, private headerService: HeaderService, - public appService: AppService + public appService: AppService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -94,7 +96,7 @@ export class SendmailAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.sendmailShort); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/shipping/shipping-administration.component.html b/src/frontend/app/administration/shipping/shipping-administration.component.html index d653643bd8904ac82a2def093a296de7ae35428a..659e7b8907267f201fe0682fc0ce4b1f4cf7bb4c 100644 --- a/src/frontend/app/administration/shipping/shipping-administration.component.html +++ b/src/frontend/app/administration/shipping/shipping-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> diff --git a/src/frontend/app/administration/shipping/shipping-administration.component.ts b/src/frontend/app/administration/shipping/shipping-administration.component.ts index 0f7dd6f9873c69d1dd203a60f91ef948ea3a15f3..6717cb6c9afb6de99d1b7338cb27bbb16039eef9 100644 --- a/src/frontend/app/administration/shipping/shipping-administration.component.ts +++ b/src/frontend/app/administration/shipping/shipping-administration.component.ts @@ -19,7 +19,6 @@ declare function $j(selector: any): any; }) export class ShippingAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; lang: any = LANG; @@ -92,9 +91,6 @@ export class ShippingAdministrationComponent implements OnInit { ).subscribe(); this.route.params.subscribe(params => { - - this.headerService.sideNavLeft = this.sidenavLeft; - if (typeof params['id'] == "undefined") { this.headerService.setHeader(this.lang.shippingCreation); @@ -102,7 +98,6 @@ export class ShippingAdministrationComponent implements OnInit { this.http.get('../../rest/administration/shippings/new') .subscribe((data: any) => { - console.log(data); this.entities = data['entities']; this.entitiesClone = JSON.parse(JSON.stringify(this.entities)); setTimeout(() => { diff --git a/src/frontend/app/administration/shipping/shippings-administration.component.html b/src/frontend/app/administration/shipping/shippings-administration.component.html index a33a3edac850c248184d65783e0447f544cbe674..79940be9ce869adce371ee6884680b2d8fa2c10e 100644 --- a/src/frontend/app/administration/shipping/shippings-administration.component.html +++ b/src/frontend/app/administration/shipping/shippings-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/shippings/new"> @@ -13,13 +9,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -37,7 +32,8 @@ <div class="row"> <div class="col-md-6 col-xs-6"> <mat-form-field> - <input matInput (keyup)="applyFilter($event.target.value)" placeholder="{{lang.filterBy}}"> + <input matInput (keyup)="applyFilter($event.target.value)" + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> @@ -47,7 +43,8 @@ </div> <mat-table #table [dataSource]="dataSource" matSort matSortActive="id" matSortDirection="asc"> <ng-container matColumnDef="label"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()">{{lang.label}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()">{{lang.label}}</mat-header-cell> <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()"> {{element.label}} </mat-cell> </ng-container> @@ -64,17 +61,22 @@ <ng-container matColumnDef="actions"> <mat-header-cell *matHeaderCellDef></mat-header-cell> <mat-cell *matCellDef="let element" style="justify-content: flex-end;"> - <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" (click)="$event.stopPropagation();deleteShipping(element.id)"> + <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" + (click)="$event.stopPropagation();deleteShipping(element.id)"> <mat-icon class="fa fa-trash-alt fa-2x" aria-hidden="true"></mat-icon> </button> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;" routerLink="/administration/shippings/{{row.id}}" style="cursor:pointer;" matTooltip="{{lang.view}}"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumns;" + routerLink="/administration/shippings/{{row.id}}" style="cursor:pointer;" + matTooltip="{{lang.view}}"></mat-row> </mat-table> - <div class="mat-paginator" style="min-height:48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">{{shippings.length}} {{lang.shippings}}</div> + <div class="mat-paginator" + style="min-height:48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> + {{shippings.length}} {{lang.shippings}}</div> </mat-card> </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/shipping/shippings-administration.component.ts b/src/frontend/app/administration/shipping/shippings-administration.component.ts index c234100c37064179997d0f818f9807100345711c..566311871456e7eeb8a3025ab699f6a18b0fa431 100644 --- a/src/frontend/app/administration/shipping/shippings-administration.component.ts +++ b/src/frontend/app/administration/shipping/shippings-administration.component.ts @@ -1,10 +1,9 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { HeaderService } from '../../../service/header.service'; import { MatPaginator } from '@angular/material/paginator'; -import { MatSidenav } from '@angular/material/sidenav'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { AppService } from '../../../service/app.service'; @@ -18,8 +17,7 @@ declare function $j(selector: any): any; }) export class ShippingsAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; @@ -38,7 +36,8 @@ export class ShippingsAdministrationComponent implements OnInit { private notify: NotificationService, private headerService: HeaderService, public appService: AppService, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -55,7 +54,7 @@ export class ShippingsAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.shippings); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/status/status-administration.component.html b/src/frontend/app/administration/status/status-administration.component.html index 1dfeb18ccd075f33038c89c5b08d89524055ec0d..6a806b87de03931b6bb0a59e61615085be56faf9 100755 --- a/src/frontend/app/administration/status/status-administration.component.html +++ b/src/frontend/app/administration/status/status-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -28,10 +22,13 @@ <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [formControl]="statusId" [(ngModel)]="status.id" *ngIf="creationMode" maxlength="10" name="id" id="id" title="{{lang.id}}" placeholder="{{lang.id}}" (blur)="isAvailable()" - type="text" pattern="^[\w.-]*$" required> - <input matInput [(ngModel)]="status.id" *ngIf="!creationMode" maxlength="10" name="id" id="id" title="{{lang.id}}" placeholder="{{lang.id}}" - required disabled> + <input matInput [formControl]="statusId" [(ngModel)]="status.id" + *ngIf="creationMode" maxlength="10" name="id" id="id" title="{{lang.id}}" + placeholder="{{lang.id}}" (blur)="isAvailable()" type="text" pattern="^[\w.-]*$" + required> + <input matInput [(ngModel)]="status.id" *ngIf="!creationMode" maxlength="10" + name="id" id="id" title="{{lang.id}}" placeholder="{{lang.id}}" required + disabled> <mat-error *ngIf="statusId.invalid">{{getErrorMessage()}}</mat-error> </mat-form-field> </div> @@ -39,34 +36,40 @@ <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput name="label_status" id="label_status" maxlength="50" [(ngModel)]="status.label_status" title="{{lang.label}}" - placeholder="{{lang.label}}" type="text" required> + <input matInput name="label_status" id="label_status" maxlength="50" + [(ngModel)]="status.label_status" title="{{lang.label}}" + placeholder="{{lang.label}}" type="text" required> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-6" style="white-space:nowrap;text-align:center;"> - <mat-slide-toggle matTooltip="{{lang.tooltipSearchStatus}}" [(ngModel)]="status.can_be_searched" id="can_be_search" name="can_be_search" - color="primary" [checked]="status.can_be_searched == true"> + <mat-slide-toggle matTooltip="{{lang.tooltipSearchStatus}}" + [(ngModel)]="status.can_be_searched" id="can_be_search" name="can_be_search" + color="primary" [checked]="status.can_be_searched == true"> {{lang.canBeSearched}} </mat-slide-toggle> </div> <div class="col-sm-6" style="white-space:nowrap;text-align:center;"> - <mat-slide-toggle matTooltip="{{lang.tooltipIndexStatus}}" [(ngModel)]="status.can_be_modified" id="can_be_modified" name="can_be_modified" - color="primary" [checked]="status.can_be_modified == true"> + <mat-slide-toggle matTooltip="{{lang.tooltipIndexStatus}}" + [(ngModel)]="status.can_be_modified" id="can_be_modified" name="can_be_modified" + color="primary" [checked]="status.can_be_modified == true"> {{lang.canBeModified}} </mat-slide-toggle> </div> </div> <div class="form-group"> <div class="col-sm-1" style="text-align:right;"> - <mat-icon [ngClass]="[status.img_filename.indexOf('fm') == 0 ? 'fm fm-2x' : 'fa fa-2x']" class="{{status.img_filename}}" aria-hidden="true" color="primary"></mat-icon> + <mat-icon [ngClass]="[status.img_filename.indexOf('fm') == 0 ? 'fm fm-2x' : 'fa fa-2x']" + class="{{status.img_filename}}" aria-hidden="true" color="primary"></mat-icon> </div> <div class="col-sm-11"> <mat-form-field> - <mat-select [(ngModel)]="status.img_filename" placeholder="{{lang.imgRelated}}" id="status" name="status" required> + <mat-select [(ngModel)]="status.img_filename" placeholder="{{lang.imgRelated}}" + id="status" name="status" required> <mat-option *ngFor="let image of statusImages" [value]="image.image_name"> - <i [ngClass]="[image.image_name.indexOf('fm') == 0 ? 'fm' : 'fa']" class="{{image.image_name}}" color="primary"></i> {{image.image_name}} + <i [ngClass]="[image.image_name.indexOf('fm') == 0 ? 'fm' : 'fa']" + class="{{image.image_name}}" color="primary"></i> {{image.image_name}} </mat-option> </mat-select> </mat-form-field> @@ -74,7 +77,8 @@ </div> <div class="form-group"> <div class="col-sm-12" style="text-align:center;"> - <button mat-raised-button color="primary" type="submit" [disabled]="!statusFormUp.form.valid">{{lang.save}}</button> + <button mat-raised-button color="primary" type="submit" + [disabled]="!statusFormUp.form.valid">{{lang.save}}</button> </div> </div> </form> @@ -82,4 +86,4 @@ </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/status/status-administration.component.ts b/src/frontend/app/administration/status/status-administration.component.ts index 590b21700b8bab698e1c1340b48b338e756cde29..0650ae745f06b88e74149a5df3b9f6764239eb41 100755 --- a/src/frontend/app/administration/status/status-administration.component.ts +++ b/src/frontend/app/administration/status/status-administration.component.ts @@ -1,11 +1,10 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Router, ActivatedRoute } from '@angular/router'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { HeaderService } from '../../../service/header.service'; import { FormControl, Validators} from '@angular/forms'; -import { MatSidenav } from '@angular/material/sidenav'; import { AppService } from '../../../service/app.service'; declare function $j(selector: any): any; @@ -16,9 +15,6 @@ declare function $j(selector: any): any; }) export class StatusAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; - lang: any = LANG; creationMode: boolean; @@ -58,9 +54,6 @@ export class StatusAdministrationComponent implements OnInit { this.loading = true; this.route.params.subscribe((params: any) => { - - this.headerService.sideNavLeft = this.sidenavLeft; - if (typeof params['identifier'] == "undefined") { this.headerService.setHeader(this.lang.statusCreation); diff --git a/src/frontend/app/administration/status/statuses-administration.component.html b/src/frontend/app/administration/status/statuses-administration.component.html index 6a3619075d5ad7cc763153b6bed68e530015f6d1..1a39b470ee3baafb62a5237df41451ab4a20c5a7 100755 --- a/src/frontend/app/administration/status/statuses-administration.component.html +++ b/src/frontend/app/administration/status/statuses-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/statuses/new"> @@ -13,13 +9,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -37,7 +32,8 @@ <div class="row"> <div class="col-md-6 col-xs-6"> <mat-form-field> - <input matInput (keyup)="applyFilter($event.target.value)" placeholder="{{lang.filterBy}}"> + <input matInput (keyup)="applyFilter($event.target.value)" + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> @@ -45,16 +41,20 @@ </mat-paginator> </div> </div> - <mat-table #table [dataSource]="dataSource" matSort matSortActive="label_status" matSortDirection="asc"> + <mat-table #table [dataSource]="dataSource" matSort matSortActive="label_status" + matSortDirection="asc"> <ng-container matColumnDef="img_filename"> <mat-header-cell *matHeaderCellDef>{{lang.imgRelated}}</mat-header-cell> <mat-cell *matCellDef="let element" color="primary"> - <mat-icon class="fm {{element.img_filename}} fm-2x" *ngIf="element.img_filename.indexOf('fm') == 0" aria-hidden="true"></mat-icon> - <mat-icon class="fa {{element.img_filename}} fa-2x" *ngIf="element.img_filename.indexOf('fa') == 0" aria-hidden="true"></mat-icon> + <mat-icon class="fm {{element.img_filename}} fm-2x" + *ngIf="element.img_filename.indexOf('fm') == 0" aria-hidden="true"></mat-icon> + <mat-icon class="fa {{element.img_filename}} fa-2x" + *ngIf="element.img_filename.indexOf('fa') == 0" aria-hidden="true"></mat-icon> </mat-cell> </ng-container> <ng-container matColumnDef="id"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()">{{lang.id}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()">{{lang.id}}</mat-header-cell> <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()"> {{element.id}} </mat-cell> </ng-container> @@ -66,17 +66,22 @@ <ng-container matColumnDef="identifier"> <mat-header-cell *matHeaderCellDef></mat-header-cell> <mat-cell *matCellDef="let element" style="justify-content: flex-end;"> - <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" (click)="$event.stopPropagation();deleteStatus(element)"> + <button mat-icon-button color="warn" matTooltip="{{lang.delete}}" + (click)="$event.stopPropagation();deleteStatus(element)"> <mat-icon class="fa fa-trash-alt fa-2x" aria-hidden="true"></mat-icon> </button> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;" routerLink="/administration/statuses/{{row.identifier}}" style="cursor:pointer;" matTooltip="{{lang.view}}"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumns;" + routerLink="/administration/statuses/{{row.identifier}}" style="cursor:pointer;" + matTooltip="{{lang.view}}"></mat-row> </mat-table> - <div class="mat-paginator" style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">{{statuses.length}} {{lang.statuses}}</div> + <div class="mat-paginator" + style="min-height:48px;min-height: 48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> + {{statuses.length}} {{lang.statuses}}</div> </mat-card> </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/status/statuses-administration.component.ts b/src/frontend/app/administration/status/statuses-administration.component.ts index 2f350ed757594aa322d7dc15e13bd720b7a81fb6..2940213628ffeeef6130feed0ee1d78a9d6b2680 100755 --- a/src/frontend/app/administration/status/statuses-administration.component.ts +++ b/src/frontend/app/administration/status/statuses-administration.component.ts @@ -1,8 +1,7 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { MatPaginator } from '@angular/material/paginator'; -import { MatSidenav } from '@angular/material/sidenav'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { NotificationService } from '../../notification.service'; @@ -18,8 +17,7 @@ declare function $j(selector: any): any; }) export class StatusesAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang : any = LANG; loading : boolean = false; @@ -45,7 +43,8 @@ export class StatusesAdministrationComponent implements OnInit { private notify: NotificationService, private headerService: HeaderService, public appService: AppService, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -53,7 +52,7 @@ export class StatusesAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.statuses); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/tag/tag-administration.component.html b/src/frontend/app/administration/tag/tag-administration.component.html index d03b233f73781977ed4ec620a32c8a7b12d86473..e929e99233d77f616549d793916de93b0b5e4d82 100644 --- a/src/frontend/app/administration/tag/tag-administration.component.html +++ b/src/frontend/app/administration/tag/tag-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> diff --git a/src/frontend/app/administration/tag/tag-administration.component.ts b/src/frontend/app/administration/tag/tag-administration.component.ts index 502331182a87d79eecb81870e2456b91fa218a75..4e74477c7f7f09a748bf1cfd7ef2206a7541bfcd 100644 --- a/src/frontend/app/administration/tag/tag-administration.component.ts +++ b/src/frontend/app/administration/tag/tag-administration.component.ts @@ -1,9 +1,8 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Router, ActivatedRoute } from '@angular/router'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; -import { MatSidenav } from '@angular/material/sidenav'; import { HeaderService } from '../../../service/header.service'; import { AppService } from '../../../service/app.service'; import { FormControl, Validators, FormGroup } from '@angular/forms'; @@ -19,10 +18,6 @@ import { MatDialog } from '@angular/material'; }) export class TagAdministrationComponent implements OnInit { - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; - id: string; creationMode: boolean; lang: any = LANG; @@ -59,9 +54,6 @@ export class TagAdministrationComponent implements OnInit { this.loading = true; this.route.params.subscribe((params) => { - - this.headerService.sideNavLeft = this.sidenavLeft; - if (typeof params['id'] == "undefined") { this.headerService.setHeader(this.lang.tagCreation); this.creationMode = true; diff --git a/src/frontend/app/administration/tag/tags-administration.component.html b/src/frontend/app/administration/tag/tags-administration.component.html index 2c32244d163010ff94d9a66a0c9f2d959fd05726..90cda710b895f8754d02d8f761ec2bd09efe5c64 100644 --- a/src/frontend/app/administration/tag/tags-administration.component.html +++ b/src/frontend/app/administration/tag/tags-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/tags/new"> @@ -13,13 +9,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -76,4 +71,4 @@ </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/tag/tags-administration.component.ts b/src/frontend/app/administration/tag/tags-administration.component.ts index 3c1883ee637dfd384a7fea28c0d3ef50592715af..26628d0dba52f3f185218eb73c3b2a9cf724ace7 100644 --- a/src/frontend/app/administration/tag/tags-administration.component.ts +++ b/src/frontend/app/administration/tag/tags-administration.component.ts @@ -1,9 +1,8 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { MatPaginator } from '@angular/material/paginator'; -import { MatSidenav } from '@angular/material/sidenav'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { HeaderService } from '../../../service/header.service'; @@ -19,9 +18,8 @@ import {FunctionsService} from "../../../service/functions.service"; providers: [AppService] }) export class TagsAdministrationComponent implements OnInit { - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; loading: boolean = true; @@ -48,13 +46,14 @@ export class TagsAdministrationComponent implements OnInit { private headerService: HeaderService, public appService: AppService, public dialog: MatDialog, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { } ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.tags); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loadList(); } diff --git a/src/frontend/app/administration/template/template-administration.component.html b/src/frontend/app/administration/template/template-administration.component.html index 9960796a177df47af05cd76961b343775ce6e749..91ab4fb6125bd58d387810b064bbd89dd455bd1f 100755 --- a/src/frontend/app/administration/template/template-administration.component.html +++ b/src/frontend/app/administration/template/template-administration.component.html @@ -1,25 +1,22 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list *ngIf="!creationMode && !loading"> <h3 mat-subheader>{{lang.actions}}</h3> - <a mat-list-item [disableRipple]="lockFound || template.template_target == 'acknowledgementReceipt'" [class.disabled]="lockFound || template.template_target == 'acknowledgementReceipt'" (click)="duplicateTemplate()"> + <a mat-list-item [disableRipple]="lockFound || template.template_target == 'acknowledgementReceipt'" + [class.disabled]="lockFound || template.template_target == 'acknowledgementReceipt'" + (click)="duplicateTemplate()"> <mat-icon color="primary" mat-list-icon class="fa fa-copy"></mat-icon> <p mat-line> {{lang.duplicate}} </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -39,16 +36,19 @@ <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput [(ngModel)]="template.template_label" required name="template_label" id="template_label" title="{{lang.templateName}}" - type="text" placeholder="{{lang.templateName}}" maxlength="255"> + <input matInput [(ngModel)]="template.template_label" required + name="template_label" id="template_label" title="{{lang.templateName}}" + type="text" placeholder="{{lang.templateName}}" maxlength="255"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <textarea matInput [(ngModel)]="template.template_comment" required name="template_comment" id="template_comment" placeholder="{{lang.description}}" - title="{{lang.description}}" matTextareaAutosize matAutosizeMinRows="2" matAutosizeMaxRows="5"> + <textarea matInput [(ngModel)]="template.template_comment" required + name="template_comment" id="template_comment" + placeholder="{{lang.description}}" title="{{lang.description}}" + matTextareaAutosize matAutosizeMinRows="2" matAutosizeMaxRows="5"> </textarea> </mat-form-field> </div> @@ -56,10 +56,13 @@ <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <mat-select [disabled]="!creationMode" id="template_target" name="template_target" title="{{lang.templateTarget}}" placeholder="{{lang.templateTarget}}" - [(ngModel)]="template.template_target" (ngModelChange)="updateTemplateType()"> + <mat-select [disabled]="!creationMode" id="template_target" + name="template_target" title="{{lang.templateTarget}}" + placeholder="{{lang.templateTarget}}" [(ngModel)]="template.template_target" + (ngModelChange)="updateTemplateType()"> <mat-option value="">{{lang.noTarget}}</mat-option> - <mat-option value="acknowledgementReceipt">{{lang.acknowledgementReceipt}}</mat-option> + <mat-option value="acknowledgementReceipt">{{lang.acknowledgementReceipt}} + </mat-option> <mat-option value="notes">{{lang.notes}}</mat-option> <mat-option value="sendmail">{{lang.sendmail}}</mat-option> <mat-option value="indexingFile">{{lang.indexingFile}}</mat-option> @@ -72,8 +75,9 @@ <div class="form-group" *ngIf="template.template_target == 'attachments'"> <div class="col-sm-12"> <mat-form-field> - <mat-select id="template_attachment_type" name="template_attachment_type" title="{{lang.attachmentType}}" placeholder="{{lang.attachmentType}}" - [(ngModel)]="template.template_attachment_type"> + <mat-select id="template_attachment_type" name="template_attachment_type" + title="{{lang.attachmentType}}" placeholder="{{lang.attachmentType}}" + [(ngModel)]="template.template_attachment_type"> <mat-option value="all">{{lang.allAttachments}}</mat-option> <mat-option *ngFor="let value of attachmentTypesList" [value]="value.id"> {{value.label}} @@ -86,8 +90,10 @@ <div class="form-group" *ngIf="template.template_target == 'acknowledgementReceipt'"> <div class="col-sm-12"> <mat-form-field> - <mat-select [disabled]="!creationMode" id="template_attachment_type" name="template_attachment_type" title="{{lang.acknowledgementReceiptType}}" placeholder="{{lang.acknowledgementReceiptType}}" - [(ngModel)]="template.template_attachment_type" required> + <mat-select [disabled]="!creationMode" id="template_attachment_type" + name="template_attachment_type" title="{{lang.acknowledgementReceiptType}}" + placeholder="{{lang.acknowledgementReceiptType}}" + [(ngModel)]="template.template_attachment_type" required> <mat-option value="simple">{{lang.ARsimple}}</mat-option> <mat-option value="sva">{{lang.ARsva}}</mat-option> <mat-option value="svr">{{lang.ARsvr}}</mat-option> @@ -96,16 +102,23 @@ </div> </div> - <div class="form-group" [hidden]="template.template_target=='attachments' || template.template_target=='notifications' || template.template_target=='doctypes' || template.template_target=='notes' || template.template_target=='acknowledgementReceipt'"> + <div class="form-group" + [hidden]="template.template_target=='attachments' || template.template_target=='notifications' || template.template_target=='doctypes' || template.template_target=='notes' || template.template_target=='acknowledgementReceipt'"> <div class="col-sm-12"> - <mat-radio-group [disabled]="!creationMode" required name="template_type" [(ngModel)]="template.template_type"> - <mat-radio-button style="margin-left:10px" color="primary" name="template_type" value="OFFICE" [checked]="template.template_type=='OFFICE'" - *ngIf="template.template_target=='attachments' || template.template_target==''">{{lang.office}}</mat-radio-button> - <mat-radio-button style="margin-left:10px" color="primary" name="template_type" value="HTML" [checked]="template.template_type=='HTML'" - *ngIf="template.template_target=='sendmail' || template.template_target=='doctypes' || template.template_target == 'notifications' || template.template_target == ''" - (click)="initMce('textarea#templateHtml')">{{lang.html}}</mat-radio-button> - <mat-radio-button style="margin-left:10px" color="primary" name="template_type" value="TXT" [checked]="template.template_type=='TXT'" - *ngIf="template.template_target=='sendmail' || template.template_target=='notes' || template.template_target == ''">{{lang.txt}}</mat-radio-button> + <mat-radio-group [disabled]="!creationMode" required name="template_type" + [(ngModel)]="template.template_type"> + <mat-radio-button style="margin-left:10px" color="primary" name="template_type" + value="OFFICE" [checked]="template.template_type=='OFFICE'" + *ngIf="template.template_target=='attachments' || template.template_target==''"> + {{lang.office}}</mat-radio-button> + <mat-radio-button style="margin-left:10px" color="primary" name="template_type" + value="HTML" [checked]="template.template_type=='HTML'" + *ngIf="template.template_target=='sendmail' || template.template_target=='doctypes' || template.template_target == 'notifications' || template.template_target == ''" + (click)="initMce('textarea#templateHtml')">{{lang.html}}</mat-radio-button> + <mat-radio-button style="margin-left:10px" color="primary" name="template_type" + value="TXT" [checked]="template.template_type=='TXT'" + *ngIf="template.template_target=='sendmail' || template.template_target=='notes' || template.template_target == ''"> + {{lang.txt}}</mat-radio-button> </mat-radio-group> </div> </div> @@ -113,23 +126,31 @@ <div class="col-md-12" style="display: none;"> <div class="form-inline hide"> <div class="form-group"> - <input type="file" name="files[]" id="uploadSignFileOffice" (change)="uploadFileTrigger($event)" accept="application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml‌.slideshow,application/vnd.oasis.opendocument.text,application/vnd.oasis.opendocument.presentation,application/vnd.oasis.opendocument.spreadsheet"> + <input type="file" name="files[]" id="uploadSignFileOffice" + (change)="uploadFileTrigger($event)" + accept="application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml‌.slideshow,application/vnd.oasis.opendocument.text,application/vnd.oasis.opendocument.presentation,application/vnd.oasis.opendocument.spreadsheet"> </div> </div> </div> <div class="col-sm-12"> <mat-form-field *ngIf="creationMode || template.template_style"> - <mat-select id="template_style" [disabled]="!creationMode" name="template_style" title="{{lang.defaultTemplate}}" placeholder="{{lang.chosenModel}}" - [(ngModel)]="template.template_style" (ngModelChange)="resetFileUploaded()" [required]="template.template_target!='acknowledgementReceipt'"> + <mat-select id="template_style" [disabled]="!creationMode" name="template_style" + title="{{lang.defaultTemplate}}" placeholder="{{lang.chosenModel}}" + [(ngModel)]="template.template_style" (ngModelChange)="resetFileUploaded()" + [required]="template.template_target!='acknowledgementReceipt'"> <mat-optgroup label="{{lang.loadedFile}} :"> - <mat-option class="selectFile" (click)="clickOnUploader('uploadSignFileOffice')" value="uploadFile"> - <mat-icon class="fa fa-paperclip" color="primary" style="height:auto;"></mat-icon> {{buttonFileName}} + <mat-option class="selectFile" + (click)="clickOnUploader('uploadSignFileOffice')" + value="uploadFile"> + <mat-icon class="fa fa-paperclip" color="primary" + style="height:auto;"></mat-icon> {{buttonFileName}} </mat-option> </mat-optgroup> <ng-container *ngFor="let extension of extensionModels"> <mat-optgroup label="{{extension}} :"> <ng-container *ngFor="let default of defaultTemplatesList"> - <mat-option *ngIf="extension == default.fileExt" value="{{default.fileExt}}: {{default.fileName}}"> + <mat-option *ngIf="extension == default.fileExt" + value="{{default.fileExt}}: {{default.fileName}}"> {{default.fileExt}}: {{default.fileName}} </mat-option> </ng-container> @@ -137,15 +158,24 @@ </ng-container> </mat-select> </mat-form-field> - <button mat-raised-button color="default" type="button" (click)="$event.stopPropagation();startJnlp()" *ngIf="((creationMode && template.template_style != 'uploadFile' && template.template_style) || (!creationMode))" [disabled]="lockFound">{{lang.templateEdition}}</button> - <button mat-raised-button color="default" type="button" (click)="$event.stopPropagation();clickOnUploader('uploadSignFileOffice')" *ngIf="((creationMode && template.template_style && template.template_style == 'uploadFile') || (!creationMode))" [disabled]="lockFound">{{lang.importFile}}</button> + <button mat-raised-button color="default" type="button" + (click)="$event.stopPropagation();startJnlp()" + *ngIf="((creationMode && template.template_style != 'uploadFile' && template.template_style) || (!creationMode))" + [disabled]="lockFound">{{lang.templateEdition}}</button> + <button mat-raised-button color="default" type="button" + (click)="$event.stopPropagation();clickOnUploader('uploadSignFileOffice')" + *ngIf="((creationMode && template.template_style && template.template_style == 'uploadFile') || (!creationMode))" + [disabled]="lockFound">{{lang.importFile}}</button> </div> </div> <div class="form-group" *ngIf="template.template_type=='TXT'"> <div class="col-sm-12"> <mat-form-field> - <textarea matInput [(ngModel)]="template.template_content" name="templateTxt" id="templateTxt" placeholder="{{lang.contentTxtTemplate}}" - title="{{lang.contentTxtTemplate}}" matTextareaAutosize matAutosizeMinRows="5" matAutosizeMaxRows="5" [required]="template.template_target!='acknowledgementReceipt'"> + <textarea matInput [(ngModel)]="template.template_content" name="templateTxt" + id="templateTxt" placeholder="{{lang.contentTxtTemplate}}" + title="{{lang.contentTxtTemplate}}" matTextareaAutosize + matAutosizeMinRows="5" matAutosizeMaxRows="5" + [required]="template.template_target!='acknowledgementReceipt'"> </textarea> </mat-form-field> </div> @@ -153,18 +183,23 @@ <div class="form-group" *ngIf="template.template_type=='HTML'"> <div class="col-sm-12"> <div id="html_mode" style="display: block; width:100%;"> - <textarea [(ngModel)]="template.template_content" name="templateHtml" id="templateHtml" style="width:100%" rows="15" cols="60" [required]="template.template_target!='acknowledgementReceipt'"></textarea> + <textarea [(ngModel)]="template.template_content" name="templateHtml" + id="templateHtml" style="width:100%" rows="15" cols="60" + [required]="template.template_target!='acknowledgementReceipt'"></textarea> </div> </div> </div> <div class="form-group" *ngIf="template.template_target=='notifications'"> <div class="col-sm-12"> <mat-form-field> - <mat-select id="template_datasource" name="template_datasource" title="{{lang.templateDatasource}}" placeholder="{{lang.templateDatasource}}" - [(ngModel)]="template.template_datasource"> + <mat-select id="template_datasource" name="template_datasource" + title="{{lang.templateDatasource}}" + placeholder="{{lang.templateDatasource}}" + [(ngModel)]="template.template_datasource"> <mat-option value="">{{lang.noDatasource}}</mat-option> <ng-container *ngFor="let datasource of datasourcesList"> - <mat-option *ngIf="displayDatasources(datasource)" [value]="datasource.id">{{datasource.label}}</mat-option> + <mat-option *ngIf="displayDatasources(datasource)" + [value]="datasource.id">{{datasource.label}}</mat-option> </ng-container> </mat-select> </mat-form-field> @@ -176,7 +211,10 @@ <mat-tab label="{{lang.electronicTemplate}}"> <div class="col-sm-12"> <div id="html_mode" style="display: block; width:100%;"> - <textarea [(ngModel)]="template.template_content" name="templateOfficeHtml" id="templateOfficeHtml" style="width:100%" rows="15" cols="60" [required]="template.template_target!='acknowledgementReceipt'"></textarea> + <textarea [(ngModel)]="template.template_content" + name="templateOfficeHtml" id="templateOfficeHtml" style="width:100%" + rows="15" cols="60" + [required]="template.template_target!='acknowledgementReceipt'"></textarea> </div> </div> </mat-tab> @@ -184,23 +222,34 @@ <div class="col-md-12" style="display: none;"> <div class="form-inline hide"> <div class="form-group"> - <input type="file" name="files[]" id="uploadSignFileOfficeHtml" (change)="uploadFileTrigger($event)" accept="application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml‌.slideshow,application/vnd.oasis.opendocument.text,application/vnd.oasis.opendocument.presentation,application/vnd.oasis.opendocument.spreadsheet"> + <input type="file" name="files[]" id="uploadSignFileOfficeHtml" + (change)="uploadFileTrigger($event)" + accept="application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml‌.slideshow,application/vnd.oasis.opendocument.text,application/vnd.oasis.opendocument.presentation,application/vnd.oasis.opendocument.spreadsheet"> </div> </div> </div> <div class="col-sm-12"> <mat-form-field> - <mat-select id="template_style" [disabled]="!creationMode && template.template_file_name != null" name="template_style" title="{{lang.defaultTemplate}}" placeholder="{{lang.chosenModel}}" - [(ngModel)]="template.template_style" (ngModelChange)="resetFileUploaded()" [required]="template.template_target!='acknowledgementReceipt'"> + <mat-select id="template_style" + [disabled]="!creationMode && template.template_file_name != null" + name="template_style" title="{{lang.defaultTemplate}}" + placeholder="{{lang.chosenModel}}" + [(ngModel)]="template.template_style" + (ngModelChange)="resetFileUploaded()" + [required]="template.template_target!='acknowledgementReceipt'"> <mat-optgroup label="{{lang.loadedFile}} :"> - <mat-option (click)="clickOnUploader('uploadSignFileOfficeHtml')" style="text-align: center;" value="uploadFile"> - <mat-icon class="fa fa-paperclip" color="primary" style="height:auto;"></mat-icon> {{buttonFileName}} + <mat-option + (click)="clickOnUploader('uploadSignFileOfficeHtml')" + style="text-align: center;" value="uploadFile"> + <mat-icon class="fa fa-paperclip" color="primary" + style="height:auto;"></mat-icon> {{buttonFileName}} </mat-option> </mat-optgroup> <ng-container *ngFor="let extension of extensionModels"> <mat-optgroup label="{{extension}} :"> <ng-container *ngFor="let default of defaultTemplatesList"> - <mat-option *ngIf="extension == default.fileExt" value="{{default.fileExt}}: {{default.fileName}}"> + <mat-option *ngIf="extension == default.fileExt" + value="{{default.fileExt}}: {{default.fileName}}"> {{default.fileExt}}: {{default.fileName}} </mat-option> </ng-container> @@ -208,12 +257,14 @@ </ng-container> </mat-select> </mat-form-field> - <button mat-raised-button color="default" type="button" (click)="$event.stopPropagation();startJnlp()" - *ngIf="template.template_file_name != null || (template.template_style != 'uploadFile' && template.template_style)" - [disabled]="lockFound">{{lang.templateEdition}}</button> - <button mat-raised-button color="default" type="button" (click)="$event.stopPropagation();clickOnUploader('uploadSignFileOfficeHtml')" - *ngIf="template.template_file_name != null || (template.template_style && template.template_style == 'uploadFile')" - [disabled]="lockFound">{{lang.importFile}}</button> + <button mat-raised-button color="default" type="button" + (click)="$event.stopPropagation();startJnlp()" + *ngIf="template.template_file_name != null || (template.template_style != 'uploadFile' && template.template_style)" + [disabled]="lockFound">{{lang.templateEdition}}</button> + <button mat-raised-button color="default" type="button" + (click)="$event.stopPropagation();clickOnUploader('uploadSignFileOfficeHtml')" + *ngIf="template.template_file_name != null || (template.template_style && template.template_style == 'uploadFile')" + [disabled]="lockFound">{{lang.importFile}}</button> </div> </mat-tab> </mat-tab-group> @@ -221,7 +272,8 @@ </div> <div class="form-group"> <div class="col-sm-12" style="text-align:center;"> - <button mat-raised-button color="primary" type="submit" [disabled]="!templatesFormUp.form.valid || lockFound">{{lang.save}}</button> + <button mat-raised-button color="primary" type="submit" + [disabled]="!templatesFormUp.form.valid || lockFound">{{lang.save}}</button> </div> </div> </form> @@ -230,16 +282,17 @@ </div> </mat-sidenav-content> - <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" fixedTopGap="56" - position='end' [opened]="!appService.getViewMode()" style="overflow-x:hidden;width:400px;"> + <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" + fixedTopGap="56" position='end' [opened]="!appService.getViewMode()" style="overflow-x:hidden;width:400px;"> <mat-list> <h3 mat-subheader>{{lang.chooseEntityAssociationModel}}</h3> <div style="padding:10px;"> <mat-form-field> - <input matInput id="jstree_search" name="jstree_search" type="text" placeholder="{{lang.searchEntities}}"> + <input matInput id="jstree_search" name="jstree_search" type="text" + placeholder="{{lang.searchEntities}}"> </mat-form-field> <div id="jstree"></div> </div> </mat-list> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/template/template-administration.component.ts b/src/frontend/app/administration/template/template-administration.component.ts index bab89ea93b1c68c8c02bbfbdaa4247007b826377..f3e744a794ed86a85c87ca1957194df5b2ff02c3 100755 --- a/src/frontend/app/administration/template/template-administration.component.ts +++ b/src/frontend/app/administration/template/template-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, NgZone, ViewChild, Inject } from '@angular/core'; +import { Component, OnInit, NgZone, ViewChild, Inject, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Router, ActivatedRoute } from '@angular/router'; import { LANG } from '../../translate.component'; @@ -18,9 +18,8 @@ declare var tinymce: any; }) export class TemplateAdministrationComponent implements OnInit { - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang : any = LANG; loading : boolean = false; @@ -52,7 +51,8 @@ export class TemplateAdministrationComponent implements OnInit { private notify: NotificationService, private headerService: HeaderService, public dialog: MatDialog, - public appService: AppService + public appService: AppService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); window['angularTemplateComponent'] = { @@ -65,7 +65,7 @@ export class TemplateAdministrationComponent implements OnInit { this.route.params.subscribe(params => { - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); if (typeof params['id'] == "undefined") { this.headerService.setHeader(this.lang.templateCreation); diff --git a/src/frontend/app/administration/template/templates-administration.component.html b/src/frontend/app/administration/template/templates-administration.component.html index 0da76a115bd4b35a3f99bd097f0d7f612833d025..20eac677a47628f8edb09426aa18900b3d5750cb 100755 --- a/src/frontend/app/administration/template/templates-administration.component.html +++ b/src/frontend/app/administration/template/templates-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/templates/new"> @@ -13,13 +9,12 @@ </p> </a> </mat-nav-list> - <mat-divider></mat-divider> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -37,7 +32,8 @@ <div class="row"> <div class="col-md-6 col-xs-6"> <mat-form-field> - <input matInput (keyup)="applyFilter($event.target.value)" placeholder="{{lang.filterBy}}"> + <input matInput (keyup)="applyFilter($event.target.value)" + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> @@ -45,37 +41,54 @@ </mat-paginator> </div> </div> - <mat-table #table [dataSource]="dataSource" matSort matSortActive="template_label" matSortDirection="asc"> + <mat-table #table [dataSource]="dataSource" matSort matSortActive="template_label" + matSortDirection="asc"> <ng-container matColumnDef="template_label"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.templateName}}</mat-header-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:2;">{{lang.templateName}} + </mat-header-cell> <mat-cell *matCellDef="let element" style="flex:2;"> {{element.template_label}} </mat-cell> </ng-container> <ng-container matColumnDef="template_comment"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()" style="flex:2;">{{lang.description}}</mat-header-cell> - <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()" style="flex:2;"> {{element.template_comment}} </mat-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()" style="flex:2;">{{lang.description}} + </mat-header-cell> + <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()" + style="flex:2;"> {{element.template_comment}} </mat-cell> </ng-container> <ng-container matColumnDef="template_target"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()" style="flex:1;">{{lang.templateTarget}}</mat-header-cell> - <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()" style="flex:1;"> {{lang[element.template_target]}} </mat-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()" style="flex:1;"> + {{lang.templateTarget}}</mat-header-cell> + <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()" + style="flex:1;"> {{lang[element.template_target]}} </mat-cell> </ng-container> <ng-container matColumnDef="template_type"> - <mat-header-cell *matHeaderCellDef mat-sort-header [class.hide-for-mobile]="appService.getViewMode()" style="flex:1;">{{lang.templateType}}</mat-header-cell> - <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()" style="flex:1;"> {{element.template_type}} </mat-cell> + <mat-header-cell *matHeaderCellDef mat-sort-header + [class.hide-for-mobile]="appService.getViewMode()" style="flex:1;">{{lang.templateType}} + </mat-header-cell> + <mat-cell *matCellDef="let element" [class.hide-for-mobile]="appService.getViewMode()" + style="flex:1;"> {{element.template_type}} </mat-cell> </ng-container> <ng-container matColumnDef="actions"> <mat-header-cell *matHeaderCellDef></mat-header-cell> <mat-cell *matCellDef="let element" style="justify-content: flex-end;"> - <button mat-icon-button color="warn" [disabled]="element.is_system == 'Y'" matTooltip="{{lang.delete}}" (click)="$event.stopPropagation();deleteTemplate(element)"> + <button mat-icon-button color="warn" [disabled]="element.is_system == 'Y'" + matTooltip="{{lang.delete}}" + (click)="$event.stopPropagation();deleteTemplate(element)"> <mat-icon class="fa fa-trash-alt fa-2x" aria-hidden="true"></mat-icon> </button> </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> - <mat-row *matRowDef="let row; columns: displayedColumns;" routerLink="/administration/templates/{{row.template_id}}" style="cursor:pointer;" matTooltip="{{lang.view}}"></mat-row> + <mat-row *matRowDef="let row; columns: displayedColumns;" + routerLink="/administration/templates/{{row.template_id}}" style="cursor:pointer;" + matTooltip="{{lang.view}}"></mat-row> </mat-table> - <div class="mat-paginator" style="min-height:48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;">{{templates.length}} {{lang.templates}}</div> + <div class="mat-paginator" + style="min-height:48px;display: flex;justify-content: end;align-items: center;padding-right: 20px;"> + {{templates.length}} {{lang.templates}}</div> </mat-card> </div> </div> </mat-sidenav-content> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/template/templates-administration.component.ts b/src/frontend/app/administration/template/templates-administration.component.ts index 50ec04bcd95b7c27860b6074c52eefa4f45eb595..27dfcce654ab08fdc47c48633593473d7b29bde0 100755 --- a/src/frontend/app/administration/template/templates-administration.component.ts +++ b/src/frontend/app/administration/template/templates-administration.component.ts @@ -1,9 +1,8 @@ -import { Component, ViewChild, OnInit } from '@angular/core'; +import { Component, ViewChild, OnInit, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { NotificationService } from '../../notification.service'; import { MatPaginator } from '@angular/material/paginator'; -import { MatSidenav } from '@angular/material/sidenav'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { HeaderService } from '../../../service/header.service'; @@ -18,9 +17,8 @@ declare function $j(selector: any): any; }) export class TemplatesAdministrationComponent implements OnInit { - /*HEADER*/ - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; search: string = null; @@ -48,7 +46,8 @@ export class TemplatesAdministrationComponent implements OnInit { private notify: NotificationService, private headerService: HeaderService, public appService: AppService, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -56,7 +55,7 @@ export class TemplatesAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.templates); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.loading = true; diff --git a/src/frontend/app/administration/updateStatus/update-status-administration.component.html b/src/frontend/app/administration/updateStatus/update-status-administration.component.html index b533e8330dc46551d97bcf900d443aa55a88797c..8f7107898595af66b43fb5b5371841f48039c799 100755 --- a/src/frontend/app/administration/updateStatus/update-status-administration.component.html +++ b/src/frontend/app/administration/updateStatus/update-status-administration.component.html @@ -1,15 +1,9 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> diff --git a/src/frontend/app/administration/updateStatus/update-status-administration.component.ts b/src/frontend/app/administration/updateStatus/update-status-administration.component.ts index 8b3411578d0061309b5ddda22b4976a05a9933ad..ac3391bec2b2b4b82a7e23b0c28681408ed8bd0a 100755 --- a/src/frontend/app/administration/updateStatus/update-status-administration.component.ts +++ b/src/frontend/app/administration/updateStatus/update-status-administration.component.ts @@ -16,9 +16,6 @@ declare function $j(selector: any): any; }) export class UpdateStatusAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; - lang : any = LANG; loading : boolean = false; @@ -41,8 +38,6 @@ export class UpdateStatusAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.updateStatus); - this.headerService.sideNavLeft = this.sidenavLeft; - this.loading = true; this.http.get('../../rest/autocomplete/statuses').pipe( diff --git a/src/frontend/app/administration/user/user-administration.component.html b/src/frontend/app/administration/user/user-administration.component.html index 258102a12f1c72d1cd9894a6dbb1a939ecd81360..58b01b3da463d57e79ac3561d0b8be9f97a2e6fc 100755 --- a/src/frontend/app/administration/user/user-administration.component.html +++ b/src/frontend/app/administration/user/user-administration.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list *ngIf="!creationMode && !loading"> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item *ngIf="user.status != 'ABS'" (click)="activateAbsence()"> @@ -30,8 +26,8 @@ {{lang.changePassword}} </p> </a> - <a mat-list-item *ngIf="user.canCreateMaarchParapheurUser || maarchParapheurLink.login === ''" (click)="linkMaarchParapheurAccount()" - title="{{lang.createUserInMaarchParapheur}}"> + <a mat-list-item *ngIf="user.canCreateMaarchParapheurUser || maarchParapheurLink.login === ''" + (click)="linkMaarchParapheurAccount()" title="{{lang.createUserInMaarchParapheur}}"> <mat-icon color="primary" mat-list-icon class="fa fa-link"></mat-icon> <p mat-line> {{lang.linkAccount}} @@ -45,23 +41,25 @@ <mat-list *ngIf="maarchParapheurLink.login !== ''"> <h3 mat-subheader>Compte Maarch Parapheur</h3> <mat-list-item> - <mat-icon class="avatarAccount" color="primary" mat-list-icon [style.background-image]="'url('+maarchParapheurLink.picture+')'"></mat-icon> + <mat-icon class="avatarAccount" color="primary" mat-list-icon + [style.background-image]="'url('+maarchParapheurLink.picture+')'"></mat-icon> <p mat-line class="accountInfo"> - <span> - {{maarchParapheurLink.login}} - </span> - <button mat-icon-button color="warn" (click)="unlinkMaarchParapheurAccount()" title="{{lang.unlinkAccount}}"> + <span> + {{maarchParapheurLink.login}} + </span> + <button mat-icon-button color="warn" (click)="unlinkMaarchParapheurAccount()" + title="{{lang.unlinkAccount}}"> <mat-icon class="fas fa-unlink"></mat-icon> </button> </p> </mat-list-item> </mat-list> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -83,12 +81,12 @@ <div class="form-group"> <mat-form-field style="padding:10px;"> <input matInput placeholder="{{lang.typeCurrentPassword}}" - formControlName="currentPasswordCtrl" required - [type]="hidePassword ? 'password' : 'text'"> + formControlName="currentPasswordCtrl" required + [type]="hidePassword ? 'password' : 'text'"> <mat-icon matSuffix (click)="hidePassword = !hidePassword" class="fa fa-2x" - [ngClass]="[hidePassword ? 'fa-eye-slash' : 'fa-eye']"></mat-icon> + [ngClass]="[hidePassword ? 'fa-eye-slash' : 'fa-eye']"></mat-icon> <mat-error - *ngIf="firstFormGroup.controls['currentPasswordCtrl'].hasError('required')"> + *ngIf="firstFormGroup.controls['currentPasswordCtrl'].hasError('required')"> {{lang.requiredField}}</mat-error> </mat-form-field> </div> @@ -98,10 +96,11 @@ <div class="col-sm-6" style="padding-left:0px;padding-right: 0px;"> <mat-form-field style="padding:10px;"> <input matInput #inputPasswd placeholder="{{lang.typeNewPassword}}" - formControlName="newPasswordCtrl" required - [type]="hidePassword ? 'password' : 'text'"> - <mat-icon matSuffix (click)="hidePassword = !hidePassword" class="fa fa-2x" - [ngClass]="[hidePassword ? 'fa-eye-slash' : 'fa-eye']"></mat-icon> + formControlName="newPasswordCtrl" required + [type]="hidePassword ? 'password' : 'text'"> + <mat-icon matSuffix (click)="hidePassword = !hidePassword" + class="fa fa-2x" + [ngClass]="[hidePassword ? 'fa-eye-slash' : 'fa-eye']"></mat-icon> <mat-hint *ngIf="validPassword"> <i color="accent" class="fa fa-check"></i> <span color="accent">{{lang.passwordValid}}</span> @@ -112,12 +111,13 @@ <div class="col-sm-6" style="padding-left:0px;padding-right:0px;"> <mat-form-field style="padding:10px;"> <input matInput #inputPasswd2 placeholder="{{lang.retypeNewPassword}}" - required [type]="hidePassword ? 'password' : 'text'" - formControlName="retypePasswordCtrl"> - <mat-icon matSuffix (click)="hidePassword = !hidePassword" class="fa fa-2x" - [ngClass]="[hidePassword ? 'fa-eye-slash' : 'fa-eye']"></mat-icon> + required [type]="hidePassword ? 'password' : 'text'" + formControlName="retypePasswordCtrl"> + <mat-icon matSuffix (click)="hidePassword = !hidePassword" + class="fa fa-2x" + [ngClass]="[hidePassword ? 'fa-eye-slash' : 'fa-eye']"></mat-icon> <mat-hint - *ngIf="!firstFormGroup.controls['retypePasswordCtrl'].hasError('mismatch') && firstFormGroup.controls['retypePasswordCtrl'].value != ''"> + *ngIf="!firstFormGroup.controls['retypePasswordCtrl'].hasError('mismatch') && firstFormGroup.controls['retypePasswordCtrl'].value != ''"> <i color="accent" class="fa fa-check"></i> <span color="accent">{{lang.passwordMatch}}</span> </mat-hint> @@ -126,28 +126,28 @@ </div> </div> <div *ngIf="passwordRules.renewal.enabled || passwordRules.historyLastUse.enabled" - class="form-group"> + class="form-group"> <div class="col-sm-12" style="padding-left:0px;padding-right:0px;"> <div class="alert alert-warning" role="alert" [innerHTML]="otherRuleText" - style="text-align:center;"></div> + style="text-align:center;"></div> </div> </div> <div class="form-group"> <div style="text-align:center;"> <button mat-raised-button color="primary" type="button" - (click)="updatePassword()" - [disabled]="!firstFormGroup.valid">{{lang.update}}</button> + (click)="updatePassword()" + [disabled]="!firstFormGroup.valid">{{lang.update}}</button> <button mat-raised-button color="default" type="button" - (click)="showPassword=false">{{lang.cancel}}</button> + (click)="showPassword=false">{{lang.cancel}}</button> </div> </div> </form> </div> <div *ngIf="user.status == 'ABS' && !showPassword" class="text-warning" - style="position: absolute;opacity: 0.25;font-size: 120px;transform: rotate(324deg);-webkit-transform: rotate(324deg);margin-left: 35%;margin-top: 90px;"> + style="position: absolute;opacity: 0.25;font-size: 120px;transform: rotate(324deg);-webkit-transform: rotate(324deg);margin-left: 35%;margin-top: 90px;"> {{user.status}}</div> <form class="form-horizontal" (ngSubmit)="onSubmit()" #profileForm="ngForm" - *ngIf="!showPassword"> + *ngIf="!showPassword"> <div class="form-group"> <div class="col-sm-12"> <div class="pull-left"> @@ -158,10 +158,10 @@ <div class="input-group"> <mat-form-field> <input matInput *ngIf="creationMode" type="text" title="{{lang.id}}" - name="user_id" [(ngModel)]="user.userId" placeholder="{{lang.id}}" - pattern="^[\w.@-]*$" required (keyup)="setLowerUserId()"> + name="user_id" [(ngModel)]="user.userId" placeholder="{{lang.id}}" + pattern="^[\w.@-]*$" required (keyup)="setLowerUserId()"> <input matInput *ngIf="!creationMode" type="text" title="{{lang.id}}" - value="{{user.user_id}}" placeholder="{{lang.id}}" disabled> + value="{{user.user_id}}" placeholder="{{lang.id}}" disabled> </mat-form-field> </div> </div> @@ -170,31 +170,32 @@ <div class="col-sm-5" style="font-weight:bold;"> <mat-form-field> <input matInput type="text" id="lastname" name="lastname" - title="{{lang.lastname}}" placeholder="{{lang.lastname}}" - [(ngModel)]="user.lastname" required> + title="{{lang.lastname}}" placeholder="{{lang.lastname}}" + [(ngModel)]="user.lastname" required> </mat-form-field> </div> <div class="col-sm-5" style="font-weight:bold;"> <mat-form-field> <input matInput type="text" id="firstname" name="firstname" - title="{{lang.firstname}}" placeholder="{{lang.firstname}}" - [(ngModel)]="user.firstname" required> + title="{{lang.firstname}}" placeholder="{{lang.firstname}}" + [(ngModel)]="user.firstname" required> </mat-form-field> </div> <div class="col-sm-2" style="font-style:italic;"> <mat-form-field> <input matInput type="text" id="initials" name="initials" - title="{{lang.initials}}" placeholder="{{lang.initials}}" - [(ngModel)]="user.initials"> + title="{{lang.initials}}" placeholder="{{lang.initials}}" + [(ngModel)]="user.initials"> </mat-form-field> </div> </div> <div class="form-group"> <div class="col-sm-12"> <mat-form-field> - <input matInput type="tel" id="phone" name="phone" title="{{lang.phoneNumber}}" - placeholder="{{lang.phoneNumber}}" [(ngModel)]="user.phone" - pattern="\+?((|\ |\.|\(|\)|\-)?(\d)*)*\d$" [disabled]="(creationMode && !canManagePersonalDatas) || (!creationMode && (!canManagePersonalDatas || !canViewPersonalDatas))"> + <input matInput type="tel" id="phone" name="phone" + title="{{lang.phoneNumber}}" placeholder="{{lang.phoneNumber}}" + [(ngModel)]="user.phone" pattern="\+?((|\ |\.|\(|\)|\-)?(\d)*)*\d$" + [disabled]="(creationMode && !canManagePersonalDatas) || (!creationMode && (!canManagePersonalDatas || !canViewPersonalDatas))"> </mat-form-field> </div> </div> @@ -202,8 +203,8 @@ <div class="col-sm-12"> <mat-form-field> <input matInput type="email" id="mail" name="mail" title="{{lang.email}}" - placeholder="{{lang.email}}" [(ngModel)]="user.mail" - pattern="(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)" required> + placeholder="{{lang.email}}" [(ngModel)]="user.mail" + pattern="(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)" required> </mat-form-field> </div> </div> @@ -216,9 +217,10 @@ </mat-expansion-panel-header> <div class="form-group"> <div class="col-sm-12"> - <mat-checkbox color="primary" matTooltip="{{lang.webserviceAccountDesc}}" - name="loginmode" (change)="setUserModeLogin($event)" - [checked]="user.loginmode == 'restMode'"> + <mat-checkbox color="primary" + matTooltip="{{lang.webserviceAccountDesc}}" name="loginmode" + (change)="setUserModeLogin($event)" + [checked]="user.loginmode == 'restMode'"> {{lang.webserviceAccount}} </mat-checkbox> </div> @@ -228,9 +230,9 @@ <div class="form-group" style="margin-top: 10px;"> <div style="text-align:center;"> <button mat-raised-button color="primary" *ngIf="creationMode" type="submit" - [disabled]="!profileForm.form.valid">{{lang.save}}</button> + [disabled]="!profileForm.form.valid">{{lang.save}}</button> <button mat-raised-button color="primary" *ngIf="!creationMode" type="submit" - [disabled]="!profileForm.form.valid">{{lang.update}}</button> + [disabled]="!profileForm.form.valid">{{lang.update}}</button> </div> </div> </form> @@ -239,7 +241,8 @@ <mat-nav-list> <mat-list-item *ngFor="let group of user.allGroups" disableRipple="true"> <mat-slide-toggle id="{{group.group_id}}" color="primary" - [checked]="group.checked == true" [disabled]="!group.enabled" (change)="toggleGroup(group)"> + [checked]="group.checked == true" [disabled]="!group.enabled" + (change)="toggleGroup(group)"> {{group.group_desc}}</mat-slide-toggle> </mat-list-item> </mat-nav-list> @@ -257,30 +260,35 @@ <mat-list-item> <mat-icon mat-list-icon color="primary"> <mat-checkbox color="primary" - (change)="$event ? masterToggleBaskets($event) : null" - [checked]="selectionBaskets.hasValue()" matTooltip="{{lang.selectAll}}"> + (change)="$event ? masterToggleBaskets($event) : null" + [checked]="selectionBaskets.hasValue()" matTooltip="{{lang.selectAll}}"> </mat-checkbox> </mat-icon> <p mat-line *ngIf="!selectionBaskets.hasValue()" - style="opacity: 0.5;font-style: italic;font-size: 80%;margin-top:10px;"> + style="opacity: 0.5;font-style: italic;font-size: 80%;margin-top:10px;"> {{lang.selectAll}} </p> <p mat-line *ngIf="selectionBaskets.hasValue()" style="margin-top:10px;"> <button [matMenuTriggerFor]="menu" mat-icon-button - matTooltip="{{ lang.redirectBaskets }}"> + matTooltip="{{ lang.redirectBaskets }}"> <mat-icon class="fa fa-reply"></mat-icon> <mat-divider [vertical]="true" class="vertical-divider"></mat-divider> </button> <button color="warn" mat-icon-button matTooltip="{{lang.disableBasket}}" - (click)="toggleBasket(false)"> + (click)="toggleBasket(false)"> <mat-icon class="fa fa-ban"></mat-icon> </button> <button color="accent" mat-icon-button matTooltip="{{lang.enableBasket}}" - (click)="toggleBasket(true)"> + (click)="toggleBasket(true)"> <mat-icon class="fa fa-check"></mat-icon> </button> <mat-menu #menu="matMenu" style="width:200px !important;"> - <plugin-autocomplete [labelPlaceholder]="lang.redirectBaskets" [routeDatas]="['/rest/autocomplete/users']" [targetSearchKey]="'idToDisplay'" [subInfoKey]="'descriptionToDisplay'" (triggerEvent)="addBasketRedirection($event)" appearance="outline"></plugin-autocomplete> + <plugin-autocomplete [labelPlaceholder]="lang.redirectBaskets" + [routeDatas]="['/rest/autocomplete/users']" + [targetSearchKey]="'idToDisplay'" + [subInfoKey]="'descriptionToDisplay'" + (triggerEvent)="addBasketRedirection($event)" appearance="outline"> + </plugin-autocomplete> </mat-menu> </p> </mat-list-item> @@ -289,19 +297,19 @@ <mat-list-item *ngIf="basket.userToDisplay == null" style="cursor: pointer;"> <mat-icon mat-list-icon color="primary" *ngIf="basket.enabled"> <mat-checkbox (click)="$event.stopPropagation()" - (change)="$event ? selectionBaskets.toggle(basket) : null" - [checked]="selectionBaskets.isSelected(basket)" color="primary"> + (change)="$event ? selectionBaskets.toggle(basket) : null" + [checked]="selectionBaskets.isSelected(basket)" color="primary"> </mat-checkbox> </mat-icon> <h4 mat-line color="primary" style="display: flex;align-items: center;"> - <span (click)="selectionBaskets.toggle(basket);" - matTooltip="{{basket.basket_name}} [{{basket.group_desc}}]" - [ngStyle]="{'opacity': basket.allowed ? '1' : '0.5'}" - style="flex: 2;overflow: hidden;text-overflow: ellipsis;"> - {{basket.basket_name}} - <span class="label label-primary" - style="font-weight:normal">{{basket.group_desc}}</span> - </span> + <span (click)="selectionBaskets.toggle(basket);" + matTooltip="{{basket.basket_name}} [{{basket.group_desc}}]" + [ngStyle]="{'opacity': basket.allowed ? '1' : '0.5'}" + style="flex: 2;overflow: hidden;text-overflow: ellipsis;"> + {{basket.basket_name}} + <span class="label label-primary" + style="font-weight:normal">{{basket.group_desc}}</span> + </span> </h4> </mat-list-item> </ng-container> @@ -314,19 +322,20 @@ <ng-container *ngFor="let basket of user.redirectedBaskets;let i = index"> <mat-list-item> <mat-icon mat-list-icon color="primary" style="margin-top:-60px;" - class="fa fa-paper-plane"> + class="fa fa-paper-plane"> </mat-icon> <h4 mat-line color="primary">{{basket.basket_name}} <span class="label label-primary" - style="font-weight:normal">{{basket.group_desc}}</span> + style="font-weight:normal">{{basket.group_desc}}</span> </h4> <p mat-line> <mat-form-field> <input type="text" color="warn" matInput disabled - value="{{lang.redirectedTo}} {{basket.userToDisplay}}"> + value="{{lang.redirectedTo}} {{basket.userToDisplay}}"> <button mat-button color="warn" matSuffix mat-icon-button - aria-label="Clear" (click)="delBasketRedirection(basket,i)" - matTooltip="{{lang.deleteRedirection}}"> + aria-label="Clear" + (click)="delBasketRedirection(basket,i)" + matTooltip="{{lang.deleteRedirection}}"> <mat-icon color="warn" class="fa fa-times text-danger"> </mat-icon> </button> @@ -344,26 +353,32 @@ <ng-container *ngFor="let basket of user.assignedBaskets;let i = index"> <mat-list-item> <mat-icon mat-list-icon color="primary" style="margin-top:-60px;" - class="fa fa-reply"> + class="fa fa-reply"> </mat-icon> <h4 mat-line color="primary">{{basket.basket_name}} <span class="label label-primary" - style="font-weight:normal">{{basket.group_desc}}</span> + style="font-weight:normal">{{basket.group_desc}}</span> </h4> <p mat-line> - <plugin-autocomplete *ngIf="basket.userToDisplay == null" [labelPlaceholder]="lang.redirectBaskets" [routeDatas]="['/rest/autocomplete/users']" [targetSearchKey]="'idToDisplay'" [subInfoKey]="'descriptionToDisplay'" (triggerEvent)="reassignBasketRedirection($event,basket,i)" appearance="outline"></plugin-autocomplete> + <plugin-autocomplete *ngIf="basket.userToDisplay == null" + [labelPlaceholder]="lang.redirectBaskets" + [routeDatas]="['/rest/autocomplete/users']" + [targetSearchKey]="'idToDisplay'" + [subInfoKey]="'descriptionToDisplay'" + (triggerEvent)="reassignBasketRedirection($event,basket,i)" + appearance="outline"></plugin-autocomplete> <mat-form-field> <input type="text" color="warn" matInput disabled - value="{{lang.assignBy}} {{basket.userToDisplay}}"> + value="{{lang.assignBy}} {{basket.userToDisplay}}"> <button mat-button color="warn" matSuffix mat-icon-button - aria-label="Clear" (click)="basket.userToDisplay=null" - matTooltip="{{lang.reassign}}"> + aria-label="Clear" (click)="basket.userToDisplay=null" + matTooltip="{{lang.reassign}}"> <mat-icon color="primary" class="fa fa-edit"></mat-icon> </button> <button mat-button color="warn" matSuffix mat-icon-button - aria-label="Clear" - (click)="delBasketAssignRedirection(basket,i)" - matTooltip="{{lang.deleteAssignation}}"> + aria-label="Clear" + (click)="delBasketAssignRedirection(basket,i)" + matTooltip="{{lang.deleteAssignation}}"> <mat-icon color="warn" class="fa fa-times text-danger"> </mat-icon> </button> @@ -378,37 +393,40 @@ </mat-tab> <mat-tab *ngIf="!creationMode" label="{{lang.signatures}}" [disabled]="!canViewPersonalDatas"> <div *ngIf="canManagePersonalDatas" dnd-droppable matTooltip="{{lang.uploadSignFileInfo}}" - (click)="clickOnUploader('uploadSignFile')" [class.dndFileHighlighted]="highlightMe" - (dragover)="highlightMe=true" (dragleave)="highlightMe=false" - (onDropSuccess)="test($event);highlightMe=false;" class="dndFile"> + (click)="clickOnUploader('uploadSignFile')" [class.dndFileHighlighted]="highlightMe" + (dragover)="highlightMe=true" (dragleave)="highlightMe=false" + (onDropSuccess)="test($event);highlightMe=false;" class="dndFile"> {{lang.uploadSignFile}} </div> <div style="display: flex;align-items: flex-start;"> <div style="flex:1;"> <div class="col-md-3 col-sm-6 col-xm-12" - *ngFor="let signature of user.signatures; let i = index"> + *ngFor="let signature of user.signatures; let i = index"> <mat-card style="margin-bottom:10px;overflow:hidden;"> <mat-card-content style="text-align:center;"> <mat-form-field floatLabel="never"> <input matInput type="text" [(ngModel)]="signature.signature_label" - name="selectedSignatureLabel" placeholder="{{lang.label}}" - (change)="updateSignature(i)" [disabled]="!canManagePersonalDatas"> + name="selectedSignatureLabel" placeholder="{{lang.label}}" + (change)="updateSignature(i)" + [disabled]="!canManagePersonalDatas"> <button mat-button matSuffix mat-icon-button - (click)="deleteSignature(signature)" color="warn" - matTooltip="{{lang.delete}}" [disabled]="!canManagePersonalDatas"> + (click)="deleteSignature(signature)" color="warn" + matTooltip="{{lang.delete}}" + [disabled]="!canManagePersonalDatas"> <mat-icon class="fa fa-times"></mat-icon> </button> </mat-form-field> <img src="../../rest/users/{{user.id}}/signatures/{{signature.id}}/content" - alt="Signature" style="width:auto;height:60px;"> + alt="Signature" style="width:auto;height:60px;"> </mat-card-content> </mat-card> </div> </div> <div> - <button *ngIf="user.signatures.length > 0 && canManagePersonalDatas" mat-icon-button color="primary" (click)="syncMP()" - matTooltip="{{lang.syncSignsToMaarchParapheur}}" - [disabled]="!user.external_id.maarchParapheur || loadingSign"> + <button *ngIf="user.signatures.length > 0 && canManagePersonalDatas" mat-icon-button + color="primary" (click)="syncMP()" + matTooltip="{{lang.syncSignsToMaarchParapheur}}" + [disabled]="!user.external_id.maarchParapheur || loadingSign"> <mat-icon class="fa fa-sync-alt fa-2x" [class.fa-spin]="loadingSign"></mat-icon> </button> </div> @@ -416,29 +434,29 @@ <form (ngSubmit)="submitSignature()" #signatureForm="ngForm" style="display:none;"> <div class="col-md-11"> <input type="text" [(ngModel)]="signatureModel.label" id="signLabel" name="label" - placeholder="{{lang.label}}" class="form-control" required> + placeholder="{{lang.label}}" class="form-control" required> <div class="form-inline hide"> <div class="form-group"> <input type="file" name="files[]" id="uploadSignFile" - (change)="uploadSignatureTrigger($event)" accept="image/*"> + (change)="uploadSignatureTrigger($event)" accept="image/*"> </div> </div> </div> <div class="col-md-1" style="margin-bottom:5px;"> <button class="form-control btn btn-sm btn-success" type="submit" - [disabled]="!signatureForm.form.valid || !signatureModel.size"> + [disabled]="!signatureForm.form.valid || !signatureModel.size"> <i class="fa fa-plus"></i> </button> </div> <div [ngClass]="[signatureModel.size != '' ? 'col-md-10' : 'col-md-12']"> <div class="upload-drop-zone" (click)="clickOnUploader('uploadSignFile')" - style="cursor:pointer"> + style="cursor:pointer"> {{lang.clickOn}} <i class="fa fa-upload fa-2x"></i> ( < 2MB ) </div> </div> <div class="col-md-2" *ngIf="signatureModel.size"> - <img id="signaturePreview" src="{{signatureModel.base64ForJs}}" - alt="Invalid image" style="width: 100%;"> - </div> + <img id="signaturePreview" src="{{signatureModel.base64ForJs}}" + alt="Invalid image" style="width: 100%;"> + </div> </form> </mat-tab> <mat-tab *ngIf="!creationMode" label="{{lang.history}}"> @@ -448,18 +466,20 @@ <div class="col-md-6 col-xs-6"> <mat-form-field> <input matInput (keyup)="applyFilter($event.target.value)" - placeholder="{{lang.filterBy}}"> + placeholder="{{lang.filterBy}}"> </mat-form-field> </div> <div class="col-md-6 col-xs-6"> - <mat-paginator #paginator [length]="100" [hidePageSize]="true" [pageSize]="10"> + <mat-paginator #paginator [length]="100" [hidePageSize]="true" + [pageSize]="10"> </mat-paginator> </div> </div> <mat-table #table [dataSource]="dataSource" matSort matSortActive="event_date" - matSortDirection="desc"> + matSortDirection="desc"> <ng-container matColumnDef="event_date"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:1;">{{lang.date}} + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:1;"> + {{lang.date}} </mat-header-cell> <mat-cell *matCellDef="let element" style="flex:1;"> {{element.event_date | date : "dd/MM/y HH:mm"}}</mat-cell> @@ -477,7 +497,8 @@ </mat-cell> </ng-container> <ng-container matColumnDef="remote_ip"> - <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:1;">{{lang.ip}} + <mat-header-cell *matHeaderCellDef mat-sort-header style="flex:1;"> + {{lang.ip}} </mat-header-cell> <mat-cell *matCellDef="let element" style="flex:1;"> {{element.remote_ip}} </mat-cell> @@ -489,7 +510,7 @@ <div class="col-md-3 pull-right" style="padding-top:10px;"> <mat-form-field> <input matInput [(ngModel)]="minDate" [matDatepicker]="picker" - placeholder="{{lang.since}}" disabled> + placeholder="{{lang.since}}" disabled> <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle> <mat-datepicker #picker startView="month" [startAt]="minDate"> </mat-datepicker> @@ -506,8 +527,8 @@ </mat-sidenav-content> <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - fixedTopGap="56" position='end' [opened]="appService.getViewMode() || creationMode ? false : true" - style="overflow-x:hidden;max-width:500px;"> + fixedTopGap="56" position='end' [opened]="appService.getViewMode() || creationMode ? false : true" + style="overflow-x:hidden;max-width:500px;"> <mat-list> <h3 mat-subheader>{{lang.groups}}</h3> <mat-list-item *ngFor="let userGroup of user.groups"> @@ -516,8 +537,7 @@ <p mat-line> <mat-form-field style="font-size:10px;"> <input matInput type="text" id="role" name="role" title="{{lang.role}}" - placeholder="{{lang.role}}" [(ngModel)]="userGroup.role" - (change)="updateGroup(userGroup)"> + placeholder="{{lang.role}}" [(ngModel)]="userGroup.role" (change)="updateGroup(userGroup)"> <mat-hint matTooltip="{{lang.perimeter}}">{{userGroup.maarch_comment}}</mat-hint> </mat-form-field> </p> @@ -525,13 +545,13 @@ <mat-divider></mat-divider> <h3 mat-subheader>{{lang.entities}}</h3> <mat-list-item *ngFor="let userEntity of user.entities"> - <mat-icon color="primary" *ngIf="userEntity.primary_entity == 'Y'" mat-list-icon - class="fa fa-sitemap"></mat-icon> - <mat-icon color="primary" *ngIf="userEntity.primary_entity != 'Y'" mat-list-icon - class="fa fa-sitemap" style="position:relative;"> + <mat-icon color="primary" *ngIf="userEntity.primary_entity == 'Y'" mat-list-icon class="fa fa-sitemap"> + </mat-icon> + <mat-icon color="primary" *ngIf="userEntity.primary_entity != 'Y'" mat-list-icon class="fa fa-sitemap" + style="position:relative;"> <button mat-icon-button - style="cursor:pointer;position: absolute;right: -20px;top: -20px;font-size:10px;" - (click)="updatePrimaryEntity(userEntity)" matTooltip="{{lang.entityTooglePrimary}}"> + style="cursor:pointer;position: absolute;right: -20px;top: -20px;font-size:10px;" + (click)="updatePrimaryEntity(userEntity)" matTooltip="{{lang.entityTooglePrimary}}"> <mat-icon class="fa fa-arrow-up"></mat-icon> </button> </mat-icon> @@ -539,17 +559,17 @@ matTooltip="{{userEntity.entity_label}}"> {{userEntity.entity_label}} <span *ngIf="userEntity.primary_entity == 'Y'" class="label label-primary" - style="font-weight:normal">{{lang.primary}}</span> + style="font-weight:normal">{{lang.primary}}</span> </h4> <p mat-line> <mat-form-field style="font-size:10px;"> <input matInput type="text" id="role" name="role" title="{{lang.role}}" - placeholder="{{lang.role}}" [(ngModel)]="userEntity.user_role" - (change)="updateEntity(userEntity)"> + placeholder="{{lang.role}}" [(ngModel)]="userEntity.user_role" + (change)="updateEntity(userEntity)"> </mat-form-field> </p> </mat-list-item> </mat-list> </mat-sidenav> -</mat-sidenav-container> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/administration/user/user-administration.component.ts b/src/frontend/app/administration/user/user-administration.component.ts index 4b6c3710b0236528142018fac81170d10650c103..1bd7477c8d0518688613c58de069657eb116d159 100755 --- a/src/frontend/app/administration/user/user-administration.component.ts +++ b/src/frontend/app/administration/user/user-administration.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, NgZone, ViewChild, Inject } from '@angular/core'; +import { Component, OnInit, NgZone, ViewChild, Inject, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { ActivatedRoute, Router } from '@angular/router'; import { LANG } from '../../translate.component'; @@ -14,7 +14,6 @@ import { HeaderService } from '../../../service/header.service'; import { SelectionModel } from '@angular/cdk/collections'; import { AccountLinkComponent } from './account-link/account-link.component'; import { AppService } from '../../../service/app.service'; -import { MenuShortcutComponent } from '../../menu/menu-shortcut.component'; import { PrivilegeService } from '../../../service/privileges.service'; declare function $j(selector: any): any; @@ -25,8 +24,9 @@ declare function $j(selector: any): any; providers: [AppService] }) export class UserAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; + @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; lang: any = LANG; loading: boolean = false; @@ -121,7 +121,8 @@ export class UserAdministrationComponent implements OnInit { private headerService: HeaderService, private _formBuilder: FormBuilder, public appService: AppService, - private privilegeService: PrivilegeService + private privilegeService: PrivilegeService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); window['angularUserAdministrationComponent'] = { @@ -135,7 +136,7 @@ export class UserAdministrationComponent implements OnInit { this.route.params.subscribe((params: any) => { - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); if (typeof params['id'] == "undefined") { diff --git a/src/frontend/app/administration/user/users-administration.component.html b/src/frontend/app/administration/user/users-administration.component.html index a0e0d8e833b9376f99315eaf542d980dcf820e0b..b216c5c958b0e8063bbff73743da3cd9c4c2fe77 100755 --- a/src/frontend/app/administration/user/users-administration.component.html +++ b/src/frontend/app/administration/user/users-administration.component.html @@ -1,10 +1,5 @@ <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="appService.getViewMode() ? false : true" - [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> + <ng-template #adminMenuTemplate> <mat-nav-list> <h3 mat-subheader>{{lang.actions}}</h3> <a mat-list-item routerLink="/administration/users/new"> @@ -22,12 +17,12 @@ <p mat-line style="margin-left:20px">{{lang.inactives}} : {{quota.inactives}}</p> <p mat-line style="margin-left:20px">{{lang.quota}} : {{quota.userQuota}}</p> </mat-nav-list> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> diff --git a/src/frontend/app/administration/user/users-administration.component.ts b/src/frontend/app/administration/user/users-administration.component.ts index 2661aa6c24c9c40f40d760c73b3f6444eee02d89..d1fe770cc79e3734158dea7bbbafdd41288425ab 100755 --- a/src/frontend/app/administration/user/users-administration.component.ts +++ b/src/frontend/app/administration/user/users-administration.component.ts @@ -1,9 +1,8 @@ -import { Component, OnInit, ViewChild, Inject } from '@angular/core'; +import { Component, OnInit, ViewChild, Inject, TemplateRef, ViewContainerRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../../translate.component'; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; -import { MatSidenav } from '@angular/material/sidenav'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { NotificationService } from '../../notification.service'; @@ -22,8 +21,7 @@ declare var angularGlobals: any; }) export class UsersAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft : MatSidenav; - @ViewChild('snav2', { static: true }) public sidenavRight : MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; dialogRef : MatDialogRef<any>; @@ -64,7 +62,8 @@ export class UsersAdministrationComponent implements OnInit { public dialog: MatDialog, private headerService: HeaderService, public appService: AppService, - public functions: FunctionsService + public functions: FunctionsService, + private viewContainerRef: ViewContainerRef ) { $j("link[href='merged_css.php']").remove(); } @@ -72,7 +71,7 @@ export class UsersAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.administration + ' ' + this.lang.users); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu'); this.user = angularGlobals.user; this.loading = true; diff --git a/src/frontend/app/administration/versionUpdate/versions-update-administration.component.html b/src/frontend/app/administration/versionUpdate/versions-update-administration.component.html index eb6b8f7f192b3cfa6fb0971d24fa6d0860f36005..4800f5d4b6b116965c2d2d13e9512d6bd0a50398 100755 --- a/src/frontend/app/administration/versionUpdate/versions-update-administration.component.html +++ b/src/frontend/app/administration/versionUpdate/versions-update-administration.component.html @@ -6,17 +6,11 @@ </div> <mat-sidenav-container autosize class="maarch-container"> - <mat-sidenav #snav [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" - [opened]="!appService.getViewMode()" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel [snavLeft]="snav"></header-panel> - <menu-shortcut></menu-shortcut> - <menu-nav></menu-nav> - </mat-sidenav> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -56,7 +50,6 @@ </div> </div> </mat-sidenav-content> - <mat-sidenav #snav2 [mode]="appService.getViewMode() ? 'over' : 'side'" [fixedInViewport]="appService.getViewMode()" fixedTopGap="56" position='end' [opened]="!appService.getViewMode()" style="overflow-x:hidden;"> <div class="alert-message alert-message-info" *ngIf="versions.lastAvailableMajorVersion!=null" diff --git a/src/frontend/app/administration/versionUpdate/versions-update-administration.component.ts b/src/frontend/app/administration/versionUpdate/versions-update-administration.component.ts index 4d5ba2906ea8f9bd1d7767cef213a708a8fb3f29..6d80ffb7935f661a9ee7bc6b3faa656eabb0f5e0 100755 --- a/src/frontend/app/administration/versionUpdate/versions-update-administration.component.ts +++ b/src/frontend/app/administration/versionUpdate/versions-update-administration.component.ts @@ -20,7 +20,6 @@ declare function $j(selector: any): any; }) export class VersionsUpdateAdministrationComponent implements OnInit { - @ViewChild('snav', { static: true }) public sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) public sidenavRight: MatSidenav; lang: any = LANG; @@ -43,8 +42,6 @@ export class VersionsUpdateAdministrationComponent implements OnInit { ngOnInit(): void { this.headerService.setHeader(this.lang.updateVersionControl); - this.headerService.sideNavLeft = this.sidenavLeft; - this.loading = true; this.http.get('../../rest/versionsUpdate').pipe( diff --git a/src/frontend/app/app.component.html b/src/frontend/app/app.component.html index db0964caeb4e53f7e5522289500cc300fcd51b9c..e69dcec83455b7b648ae66e222c3740e9d17de4e 100644 --- a/src/frontend/app/app.component.html +++ b/src/frontend/app/app.component.html @@ -1,13 +1,16 @@ -<mat-sidenav-container class="maarch-container"> +<mat-sidenav-container class="maarch-container" autosize> <mat-sidenav #snavLeft class="panel-left" [mode]="appService.getViewMode() ? 'over' : 'side'" - [fixedInViewport]="appService.getViewMode()" [opened]="appService.getViewMode() || headerService.hideSideBar ? false : true" autoFocus="false" - style="overflow-x:hidden;" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> - <header-panel></header-panel> - <menu-shortcut #menuShortcut></menu-shortcut> - <menu-nav></menu-nav> - <basket-home #basketHome></basket-home> - <mat-divider></mat-divider> - <panel-folder #panelFolder></panel-folder> + [fixedInViewport]="appService.getViewMode()" [opened]="appService.getViewMode() ? false : true" + autoFocus="false" style="overflow-x:hidden;" [class.sideBarForm]="headerService.sideBarForm && !appService.getViewMode()" [class.sideBarFormMobile]="appService.getViewMode() && headerService.sideBarForm" [ngStyle]="{'width': appService.getViewMode() ? '80%' : '350px'}"> + <header-panel *ngIf="headerService.showhHeaderPanel"></header-panel> + <menu-shortcut *ngIf="headerService.showMenuShortcut"></menu-shortcut> + <menu-nav *ngIf="headerService.showMenuShortcut"></menu-nav> + <ng-container *ngIf="!headerService.sideBarAdmin"> + <basket-home #basketHome></basket-home> + <mat-divider></mat-divider> + <panel-folder #panelFolder></panel-folder> + </ng-container> + <div id="adminMenu" style="display: contents;"></div> </mat-sidenav> <mat-sidenav-content> <router-outlet></router-outlet> diff --git a/src/frontend/app/app.component.ts b/src/frontend/app/app.component.ts index 47b180ec7df3715b140f6591162b5df41ad948e3..89a02731045941edf77d98023f43c13248fef690 100755 --- a/src/frontend/app/app.component.ts +++ b/src/frontend/app/app.component.ts @@ -29,19 +29,19 @@ declare function $j(selector: any): any; viewProviders: [MatIconRegistry], providers: [ AppService, - {provide: MAT_TOOLTIP_DEFAULT_OPTIONS, useValue: myCustomTooltipDefaults} + { provide: MAT_TOOLTIP_DEFAULT_OPTIONS, useValue: myCustomTooltipDefaults } ], }) export class AppComponent { @ViewChild('snavLeft', { static: false }) snavLeft: MatSidenav; - + constructor( - iconReg: MatIconRegistry, - sanitizer: DomSanitizer, + iconReg: MatIconRegistry, + sanitizer: DomSanitizer, public appService: AppService, public headerService: HeaderService - ) { + ) { iconReg.addSvgIcon('maarchLogo', sanitizer.bypassSecurityTrustResourceUrl('static.php?filename=logo_white.svg')).addSvgIcon('maarchLogoOnly', sanitizer.bypassSecurityTrustResourceUrl('img/logo_only_white.svg')); iconReg.addSvgIcon('maarchLogoFull', sanitizer.bypassSecurityTrustResourceUrl('static.php?filename=logo.svg')).addSvgIcon('maarchLogoOnlyDefault', sanitizer.bypassSecurityTrustResourceUrl('img/logo.svg')); @@ -49,7 +49,7 @@ export class AppComponent { //this.headerService.loadHeader(); /*REMOVE AFTER FULL MAARCH V2*/ - $j('my-app').css({"display":"block"}); + $j('my-app').css({ "display": "block" }); $j('#maarch_content').remove(); $j('#loadingAngularContent').remove(); $j('#header').remove(); @@ -57,7 +57,7 @@ export class AppComponent { $j('#menunav').hide(); $j('#divList').remove(); $j('#container').css({ - "width": "100%", + "width": "100%", "min-width": "auto" }); $j('#content').css({ @@ -71,11 +71,8 @@ export class AppComponent { ngOnInit(): void { setTimeout(() => { this.headerService.sideNavLeft = this.snavLeft; - this.headerService.defaultSideNavLeft = this.snavLeft; }, 0); - - + this.headerService.sideNavLeft = this.snavLeft; - this.headerService.defaultSideNavLeft = this.snavLeft; } } diff --git a/src/frontend/app/header/header-panel.component.html b/src/frontend/app/header/header-panel.component.html index 151e240739eb317f28425adf4f1ad87e4adb8777..ec1c20905748a52fdfd3c43287cd6522da547ff0 100644 --- a/src/frontend/app/header/header-panel.component.html +++ b/src/frontend/app/header/header-panel.component.html @@ -1,11 +1,11 @@ <div class="panelHeader"> - <div *ngIf="navButton !== null" class="panelHeader-backHome"> + <div *ngIf="headerService.sideBarButton !== null" class="panelHeader-backHome"> <button mat-button style="padding-top: 5px;padding-bottom: 5px;" (click)="goTo()"> - <i class="{{navButton.icon}}" style="height: auto"></i> - <span>{{navButton.label}}</span> + <i class="{{headerService.sideBarButton.icon}}" style="height: auto"></i> + <span>{{headerService.sideBarButton.label}}</span> </button> </div> - <div class="panelHeader-logo" [class.text-center]="navButton !== null"> + <div class="panelHeader-logo" [class.text-center]="headerService.sideBarButton !== null"> <button mat-button style="margin-right: 30px;" (click)="goToHome()" title="{{lang.home}}"> <mat-icon class="maarchLogo" svgIcon="maarchLogoFull"></mat-icon> </button> diff --git a/src/frontend/app/header/header-panel.component.ts b/src/frontend/app/header/header-panel.component.ts index b87b7379ae3b611491488b9c282cbd6a435c0b30..92758fae0ea542e55400c55a76776693f57a5437 100644 --- a/src/frontend/app/header/header-panel.component.ts +++ b/src/frontend/app/header/header-panel.component.ts @@ -33,10 +33,10 @@ export class HeaderPanelComponent implements OnInit { ngOnInit(): void { } goTo() { - if (this.navButton.route === '__GOBACK') { + if (this.headerService.sideBarButton.route === '__GOBACK') { this._location.back(); } else { - this.router.navigate([this.navButton.route]); + this.router.navigate([this.headerService.sideBarButton.route]); } } diff --git a/src/frontend/app/home/home.component.html b/src/frontend/app/home/home.component.html index 56c8741c49807190cdb8310204bb67606f319067..fc442ccbc7248c5e3ca5f69cff303649686dd097 100644 --- a/src/frontend/app/home/home.component.html +++ b/src/frontend/app/home/home.component.html @@ -1,117 +1,122 @@ -<mat-card id="viewThumbnail" style="display:none;position: fixed;z-index: 2;margin-left: 1px;"><img - style="max-height: 100vh;" src="{{thumbnailUrl}}" /> -</mat-card> -<div class="bg-head"> - <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> - <div class="bg-head-title-label"> - <header-left></header-left> - </div> - <div class="bg-head-title-tool"> - <header-right></header-right> - </div> - </div> - <div class="bg-head-content" [class.fullContainer]="appService.getViewMode()"> - <mat-card *ngIf="homeMessage" - style="background: #135F7F;color: white;box-shadow: none;border: solid 2px white;width: 100%;border-radius: 20px;padding-bottom: 40px;"> - <div style="display: flex;max-height: 250px;overflow: auto;"> - <div style="padding-left: 10px;"> - <span [innerHTML]="homeMessage"></span> +<mat-sidenav-container autosize class="maarch-container"> + <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> + <div class="bg-head"> + <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> + <div class="bg-head-title-label"> + <header-left></header-left> + </div> + <div class="bg-head-title-tool"> + <header-right></header-right> </div> </div> - <div style="text-align: right;opacity: 0.5;"> - <button mat-button routerLink="/about-us" - style="position:absolute;font-size:10px;right: 0px;bottom: 0px;">{{lang.aboutUs}}</button> + <div class="bg-head-content" [class.fullContainer]="appService.getViewMode()"> + <mat-card *ngIf="homeMessage" + style="background: #135F7F;color: white;box-shadow: none;border: solid 2px white;width: 100%;border-radius: 20px;padding-bottom: 40px;"> + <div style="display: flex;max-height: 250px;overflow: auto;"> + <div style="padding-left: 10px;"> + <span [innerHTML]="homeMessage"></span> + </div> + </div> + <div style="text-align: right;opacity: 0.5;"> + <button mat-button routerLink="/about-us" + style="position:absolute;font-size:10px;right: 0px;bottom: 0px;">{{lang.aboutUs}}</button> + </div> + </mat-card> </div> - </mat-card> - </div> -</div> -<div class="container" [class.fullContainer]="appService.getViewMode()"> - <div class="container-content"> - <mat-tab-group> - <mat-tab *ngIf="homeData !== undefined && homeData.isLinkedToMaarchParapheur"> - <ng-template matTabLabel> - <span [class.noDoc]="nbMpDocs === 0" matBadge="{{nbMpDocs}}" - matBadgeOverlap="false">{{lang.maarchParapheurDocuments}}</span> - </ng-template> - <app-maarch-parapheur-list (triggerEvent)="updateNbMpDocs($event)"></app-maarch-parapheur-list> - </mat-tab> - <mat-tab label="{{lang.myLastResources}}" *ngIf="homeData !== undefined"> - <div *ngIf="loading" style="display:flex;height:100%;"> - <mat-spinner style="margin:auto;"></mat-spinner> - </div> - <table *ngIf="!loading" mat-table [dataSource]="dataSource" matSort matSortActive="res_id" - matSortDisableClear matSortDirection="asc" style="width:100%;table-layout: fixed;"> - <!-- Number Column --> - <ng-container matColumnDef="res_id"> - <td class="first_col" mat-cell *matCellDef="let row" - [ngStyle]="{'width': appService.getViewMode() ? '30%' : '15%'}"> - <div *ngIf="row.closing_date == null && appService.getViewMode()" - id="{{row.res_id}}_creation_date" - style="color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;" - title='{{row.creation_date | date : lang.onRange + " dd/MM/y " + lang.atRange +" HH:mm"}}'> - <i class="fa fa-calendar" title="{{lang.creationDate}}"></i> - {{row.creation_date | timeAgo}} - </div> - <div style="overflow: hidden;text-overflow: ellipsis;"> - <mat-icon [ngStyle]="{'color': row.priority_color}" color="primary" - class="{{row.status_icon.charAt(0)}}{{row.status_icon.charAt(1)}} {{row.status_icon}} {{row.status_icon.charAt(0)}}{{row.status_icon.charAt(1)}}-2x" - title="{{row.status_label}} ({{row.status_id}})"></mat-icon> - <span *ngIf="row.confidentiality === 'Y'" class="watermark">{{lang.confidential}}</span> - </div> - <div style="padding-top: 5px;color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;" - title="{{row.alt_identifier}} (n°{{row.res_id}})"> - {{row.alt_identifier}} - </div> - </td> - </ng-container> - <ng-container matColumnDef="subject"> - <td mat-cell *matCellDef="let row" - style="width:45%;overflow:hidden;text-overflow: ellipsis;padding: 5px;vertical-align: middle;"> - <div *ngIf="row.closing_date == null && appService.getViewMode()" - style="color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;text-align: right;"> - <i class="fa fa-stopwatch" title="{{lang.processLimitDate}}"></i> - <span [innerHTML]="row.process_limit_date | timeLimit" - title='{{row.process_limit_date | date : lang.onRange + " dd/MM/y " + lang.atRange +" HH:mm"}}'></span> - </div> - <div style="overflow: hidden;line-height: 1.5em;height: 3em;overflow: hidden;" - title="{{row.subject}}"> - <span>{{row.subject}}</span> - </div> - </td> - </ng-container> - <ng-container matColumnDef="creation_date"> - <td mat-cell *matCellDef="let row" - style="text-align: right;width:15%;overflow:hidden;text-overflow: ellipsis;white-space: nowrap;padding: 5px;vertical-align: middle;"> - <div *ngIf="row.closing_date == null" id="{{row.res_id}}_creation_date" - style="color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;" - title='{{row.creation_date | date : lang.onRange + " dd/MM/y " + lang.atRange +" HH:mm"}}'> - <i class="fa fa-calendar" title="{{lang.creationDate}}"></i> - {{row.creation_date | timeAgo}} - </div> - <div *ngIf="row.closing_date == null" - style="color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;"> - <i class="fa fa-stopwatch" title="{{lang.processLimitDate}}"></i> - <span [innerHTML]="row.process_limit_date | timeLimit" - title='{{row.process_limit_date | date : lang.onRange + " dd/MM/y " + lang.atRange +" HH:mm"}}'></span> - </div> - <div *ngIf="row.closing_date != null" - style="color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;"> - <i class="fa fa-lock" title="{{lang.closingDate}}"></i> - <span - title='{{row.closing_date | date : lang.onRange + " dd/MM/y " + lang.atRange +" HH:mm"}}'>{{row.closing_date | timeAgo}}</span> - </div> - <div> - <button mat-icon-button (click)="$event.stopPropagation();viewDocument(row);" - (mouseenter)="viewThumbnail(row);" (mouseleave)="closeThumbnail();"> - <mat-icon color="primary" class="fa fa-eye"></mat-icon> - </button> - </div> - </td> - </ng-container> - <tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="goToDetail(row);" - style="cursor:pointer;"></tr> - </table> - </mat-tab> - </mat-tab-group> - </div> -</div> \ No newline at end of file + </div> + <div class="container" [class.fullContainer]="appService.getViewMode()"> + <div class="container-content"> + <mat-tab-group> + <mat-tab *ngIf="homeData !== undefined && homeData.isLinkedToMaarchParapheur"> + <ng-template matTabLabel> + <span [class.noDoc]="nbMpDocs === 0" matBadge="{{nbMpDocs}}" + matBadgeOverlap="false">{{lang.maarchParapheurDocuments}}</span> + </ng-template> + <app-maarch-parapheur-list (triggerEvent)="updateNbMpDocs($event)"></app-maarch-parapheur-list> + </mat-tab> + <mat-tab label="{{lang.myLastResources}}" *ngIf="homeData !== undefined"> + <div *ngIf="loading" style="display:flex;height:100%;"> + <mat-spinner style="margin:auto;"></mat-spinner> + </div> + <table *ngIf="!loading" mat-table [dataSource]="dataSource" matSort matSortActive="res_id" + matSortDisableClear matSortDirection="asc" style="width:100%;table-layout: fixed;"> + <!-- Number Column --> + <ng-container matColumnDef="res_id"> + <td class="first_col" mat-cell *matCellDef="let row" + [ngStyle]="{'width': appService.getViewMode() ? '30%' : '15%'}"> + <div *ngIf="row.closing_date == null && appService.getViewMode()" + id="{{row.res_id}}_creation_date" + style="color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;" + title='{{row.creation_date | date : lang.onRange + " dd/MM/y " + lang.atRange +" HH:mm"}}'> + <i class="fa fa-calendar" title="{{lang.creationDate}}"></i> + {{row.creation_date | timeAgo}} + </div> + <div style="overflow: hidden;text-overflow: ellipsis;"> + <mat-icon [ngStyle]="{'color': row.priority_color}" color="primary" + class="{{row.status_icon.charAt(0)}}{{row.status_icon.charAt(1)}} {{row.status_icon}} {{row.status_icon.charAt(0)}}{{row.status_icon.charAt(1)}}-2x" + title="{{row.status_label}} ({{row.status_id}})"></mat-icon> + <span *ngIf="row.confidentiality === 'Y'" + class="watermark">{{lang.confidential}}</span> + </div> + <div style="padding-top: 5px;color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;" + title="{{row.alt_identifier}} (n°{{row.res_id}})"> + {{row.alt_identifier}} + </div> + </td> + </ng-container> + <ng-container matColumnDef="subject"> + <td mat-cell *matCellDef="let row" + style="width:45%;overflow:hidden;text-overflow: ellipsis;padding: 5px;vertical-align: middle;"> + <div *ngIf="row.closing_date == null && appService.getViewMode()" + style="color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;text-align: right;"> + <i class="fa fa-stopwatch" title="{{lang.processLimitDate}}"></i> + <span [innerHTML]="row.process_limit_date | timeLimit" + title='{{row.process_limit_date | date : lang.onRange + " dd/MM/y " + lang.atRange +" HH:mm"}}'></span> + </div> + <div style="overflow: hidden;line-height: 1.5em;height: 3em;overflow: hidden;" + title="{{row.subject}}"> + <span>{{row.subject}}</span> + </div> + </td> + </ng-container> + <ng-container matColumnDef="creation_date"> + <td mat-cell *matCellDef="let row" + style="text-align: right;width:15%;overflow:hidden;text-overflow: ellipsis;white-space: nowrap;padding: 5px;vertical-align: middle;"> + <div *ngIf="row.closing_date == null" id="{{row.res_id}}_creation_date" + style="color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;" + title='{{row.creation_date | date : lang.onRange + " dd/MM/y " + lang.atRange +" HH:mm"}}'> + <i class="fa fa-calendar" title="{{lang.creationDate}}"></i> + {{row.creation_date | timeAgo}} + </div> + <div *ngIf="row.closing_date == null" + style="color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;"> + <i class="fa fa-stopwatch" title="{{lang.processLimitDate}}"></i> + <span [innerHTML]="row.process_limit_date | timeLimit" + title='{{row.process_limit_date | date : lang.onRange + " dd/MM/y " + lang.atRange +" HH:mm"}}'></span> + </div> + <div *ngIf="row.closing_date != null" + style="color: rgba(0,0,0,0.4);font-size: 90%;overflow: hidden;text-overflow: ellipsis;"> + <i class="fa fa-lock" title="{{lang.closingDate}}"></i> + <span + title='{{row.closing_date | date : lang.onRange + " dd/MM/y " + lang.atRange +" HH:mm"}}'>{{row.closing_date | timeAgo}}</span> + </div> + <div> + <button mat-icon-button (click)="$event.stopPropagation();viewDocument(row);" + (mouseenter)="viewThumbnail(row);" (mouseleave)="closeThumbnail();"> + <mat-icon color="primary" class="fa fa-eye"></mat-icon> + </button> + </div> + </td> + </ng-container> + <tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="goToDetail(row);" + style="cursor:pointer;"></tr> + </table> + </mat-tab> + </mat-tab-group> + </div> + </div> + </mat-sidenav-content> +</mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/indexation/indexation.component.html b/src/frontend/app/indexation/indexation.component.html index f4f637e81d3092f644ed6c8526ebd9857ccd9bc5..cdd283b3e0a7659c37e23a4161257684ea7ff439 100644 --- a/src/frontend/app/indexation/indexation.component.html +++ b/src/frontend/app/indexation/indexation.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container class="maarch-container"> - <mat-sidenav #snavLeft class="panel-left" #snav [mode]="appService.getViewMode() ? 'over' : 'side'" - [fixedInViewport]="appService.getViewMode()" [opened]="appService.getViewMode() ? false : true" - autoFocus="false" style="overflow-x:hidden;" [ngStyle]="{'width': appService.getViewMode() ? '95%' : '600px'}"> - <header-panel [snavLeft]="snav" [navButton]="{icon: 'fa fa-home', label: lang.backHome, route : '/home'}"> - </header-panel> + <ng-template #adminMenuTemplate> <ng-container *ngIf="indexingModels.length > 0"> <div class="listModels"> <button mat-button class="button-form-primary listModels-button" @@ -57,7 +53,8 @@ </div> <div class="indexing-form-container"> <app-indexing-form *ngIf="currentIndexingModel.id !== undefined" #indexingForm - [groupId]="currentGroupId" [indexingFormId]="currentIndexingModel.id" (retrieveDocumentEvent)="appDocumentViewer.saveDocService()"></app-indexing-form> + [groupId]="currentGroupId" [indexingFormId]="currentIndexingModel.id" + (retrieveDocumentEvent)="appDocumentViewer.saveDocService()"></app-indexing-form> </div> <div class="actions-indexing-form"> <ng-container @@ -105,12 +102,12 @@ </div> </ng-container> <div *ngIf="indexingModels.length === 0" class="emptyModel" [innerHTML]="lang.noAvailableIndexingModel"></div> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -119,15 +116,10 @@ </div> <div class="document-container" [class.fullContainer]="appService.getViewMode()"> <div class="content"> - <app-document-viewer #appDocumentViewer [editMode]="true" [tmpFilename]="tmpFilename" (triggerEvent)="refreshDatas()" [sidenavLeft]="sidenavLeft" - style="height:100%;width:100%;"> + <app-document-viewer #appDocumentViewer [editMode]="true" [tmpFilename]="tmpFilename" + (triggerEvent)="refreshDatas()" style="height:100%;width:100%;"> </app-document-viewer> </div> </div> </mat-sidenav-content> - <mat-sidenav #snav2 [fixedInViewport]="appService.getViewMode()" position='end' - [opened]="appService.getViewMode() ? false : false" [mode]="appService.getViewMode() ? 'over' : 'side'" - class="panel-right" style="overflow-x:hidden;" [class.docView]="!filtersListService.filterMode" - [ngStyle]="{'width': appService.getViewMode() ? '80%' : '30%'}" autoFocus="false"> - </mat-sidenav> </mat-sidenav-container> \ No newline at end of file diff --git a/src/frontend/app/indexation/indexation.component.ts b/src/frontend/app/indexation/indexation.component.ts index 4a3915499483cc2b243b99cf3264d7c8ba506bd6..dd65ffae3cf4e433a0bab126d7f6ff9305d23706 100644 --- a/src/frontend/app/indexation/indexation.component.ts +++ b/src/frontend/app/indexation/indexation.component.ts @@ -1,9 +1,8 @@ -import { Component, OnInit, ViewChild, ViewContainerRef } from '@angular/core'; +import { Component, OnInit, ViewChild, ViewContainerRef, TemplateRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../translate.component'; import { NotificationService } from '../notification.service'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { MatSidenav } from '@angular/material/sidenav'; import { ActivatedRoute, Router, ParamMap } from '@angular/router'; import { HeaderService } from '../../service/header.service'; @@ -35,8 +34,7 @@ export class IndexationComponent implements OnInit { loading: boolean = false; - @ViewChild('snav', { static: true }) sidenavLeft: MatSidenav; - @ViewChild('snav2', { static: true }) sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; @ViewChild('indexingForm', { static: false }) indexingForm: IndexingFormComponent; @ViewChild('appDocumentViewer', { static: false }) appDocumentViewer: DocumentViewerComponent; @@ -95,8 +93,8 @@ export class IndexationComponent implements OnInit { // Use to clean data after navigate on same url this._activatedRoute.queryParamMap.subscribe((paramMap: ParamMap) => { const refresh = paramMap.get('refresh'); - this.headerService.sideNavLeft.close(); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu', 'form'); + this.headerService.sideBarButton = {icon: 'fa fa-home', label: this.lang.backHome, route : '/home'}; if (refresh) { this.appDocumentViewer.templateListForm.reset(); this.appDocumentViewer.file = { @@ -133,7 +131,7 @@ export class IndexationComponent implements OnInit { if (this.appService.getViewMode()) { setTimeout(() => { - this.sidenavLeft.open(); + this.headerService.sideNavLeft.open(); }, 400); } }), diff --git a/src/frontend/app/menu/menu-nav.component.ts b/src/frontend/app/menu/menu-nav.component.ts index 87c2514548797daedd018b6272264ca88020bc92..eb69ed89abd57db4305728e2299e151d1316bc25 100755 --- a/src/frontend/app/menu/menu-nav.component.ts +++ b/src/frontend/app/menu/menu-nav.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { Location } from '@angular/common'; import { Router, ActivatedRoute } from '@angular/router'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../translate.component'; @@ -18,7 +19,8 @@ export class MenuNavComponent implements OnInit { constructor( public http: HttpClient, private _router: Router, - private activatedRoute:ActivatedRoute + private activatedRoute:ActivatedRoute, + private _location: Location ) { this.router = _router; } @@ -26,6 +28,7 @@ export class MenuNavComponent implements OnInit { ngOnInit(): void { } backClicked() { - this.router.navigate(['../'],{ relativeTo: this.activatedRoute }); + //this.router.navigate(['../'],{ relativeTo: this.activatedRoute }); + this._location.back(); } } diff --git a/src/frontend/app/process/process.component.html b/src/frontend/app/process/process.component.html index 6b0c1a198ce9eef58242498cf93c81399a6bed8a..2498ca7e5fdaaa7337f89dfd398ae91296176505 100644 --- a/src/frontend/app/process/process.component.html +++ b/src/frontend/app/process/process.component.html @@ -1,9 +1,5 @@ <mat-sidenav-container class="maarch-container"> - <mat-sidenav #snavLeft class="panel-left" #snav [mode]="appService.getViewMode() ? 'over' : 'side'" - [fixedInViewport]="appService.getViewMode()" [opened]="appService.getViewMode() ? false : true" - autoFocus="false" style="overflow-x:hidden;" [ngStyle]="{'width': appService.getViewMode() ? '95%' : '600px'}"> - <header-panel [snavLeft]="snav" [navButton]="navButton"> - </header-panel> + <ng-template #adminMenuTemplate> <div class="listModels"> <div class="processTool"> <div class="processTool-module jiggle" *ngFor="let module of processTool" @@ -162,12 +158,12 @@ </ng-container> <div class="emptyAction" *ngIf="actionsList.length === 0" [innerHTML]="lang.noAvailableActionProcess"></div> </div> - </mat-sidenav> + </ng-template> <mat-sidenav-content> <div class="bg-head"> <div class="bg-head-title" [class.customContainerRight]="appService.getViewMode()"> <div class="bg-head-title-label"> - <header-left [snavLeft]="snav"></header-left> + <header-left></header-left> </div> <div class="bg-head-title-tool"> <header-right></header-right> @@ -249,8 +245,7 @@ <div class="content"> <app-document-viewer #appDocumentViewer *ngIf="!loading" style="height:100%;width:100%;" [editMode]="canEditData" [resId]="currentResourceInformations.resId" - [title]="currentResourceInformations.chrono + ' - ' + currentResourceInformations.subject" - [sidenavLeft]="sidenavLeft"> + [title]="currentResourceInformations.chrono + ' - ' + currentResourceInformations.subject"> </app-document-viewer> </div> </div> diff --git a/src/frontend/app/process/process.component.scss b/src/frontend/app/process/process.component.scss index 1770944db47d16874acf9799e7b6102ea5c30f3c..3923fa49ec32813c0efb8b7bdc7bdcc734d884c2 100644 --- a/src/frontend/app/process/process.component.scss +++ b/src/frontend/app/process/process.component.scss @@ -1,12 +1,5 @@ @import "../../css/vars.scss"; -.panel-left { - ::ng-deep.mat-drawer-inner-container { - display: flex; - flex-direction: column; - } -} - .document-container { flex: 1; diff --git a/src/frontend/app/process/process.component.ts b/src/frontend/app/process/process.component.ts index 0988fd19ac8a18ca1a1dcf0be18363625bd5b6cc..2d9f25b4a879bd87d22a7430c0f433f6dad9b53a 100755 --- a/src/frontend/app/process/process.component.ts +++ b/src/frontend/app/process/process.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, ViewContainerRef } from '@angular/core'; +import { Component, OnInit, ViewChild, ViewContainerRef, TemplateRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../translate.component'; import { NotificationService } from '../notification.service'; @@ -43,7 +43,6 @@ export class ProcessComponent implements OnInit { loading: boolean = true; detailMode: boolean = false; - navButton: any = null; isMailing: boolean = false; currentResourceLock: any = null; @@ -146,8 +145,8 @@ export class ProcessComponent implements OnInit { }; - @ViewChild('snav', { static: true }) sidenavLeft: MatSidenav; @ViewChild('snav2', { static: true }) sidenavRight: MatSidenav; + @ViewChild('adminMenuTemplate', { static: true }) adminMenuTemplate: TemplateRef<any>; @ViewChild('appDocumentViewer', { static: false }) appDocumentViewer: DocumentViewerComponent; @ViewChild('indexingForm', { static: false }) indexingForm: IndexingFormComponent; @@ -186,8 +185,7 @@ export class ProcessComponent implements OnInit { ngOnInit(): void { this.loading = true; - this.headerService.sideNavLeft.close(); - this.headerService.sideNavLeft = this.sidenavLeft; + this.headerService.injectInSideBarLeft(this.adminMenuTemplate, this.viewContainerRef, 'adminMenu', 'form'); this.headerService.setHeader(this.lang.eventProcessDoc); this.route.params.subscribe(params => { @@ -235,7 +233,7 @@ export class ProcessComponent implements OnInit { mailtracking: false }; - this.navButton = { + this.headerService.sideBarButton = { icon: 'fa fa-inbox', label: this.lang.backBasket, route: `/basketList/users/${this.currentUserId}/groups/${this.currentGroupId}/baskets/${this.currentBasketId}` @@ -249,7 +247,7 @@ export class ProcessComponent implements OnInit { if (this.appService.getViewMode()) { setTimeout(() => { - this.sidenavLeft.open(); + this.headerService.sideNavLeft.open(); }, 800); } @@ -286,7 +284,7 @@ export class ProcessComponent implements OnInit { resId: params['detailResId'], mailtracking: false }; - this.navButton = { + this.headerService.sideBarButton = { icon: 'fas fa-arrow-left', label: this.lang.back, route: `__GOBACK` @@ -299,7 +297,7 @@ export class ProcessComponent implements OnInit { if (this.appService.getViewMode()) { setTimeout(() => { - this.sidenavLeft.open(); + this.headerService.sideNavLeft.open(); }, 800); } } diff --git a/src/frontend/app/viewer/document-viewer.component.html b/src/frontend/app/viewer/document-viewer.component.html index 989050e83083b146b2a866229a8d8de6fcbff591..564d0e338bcbb877e8c977ec121f49ffd9256283 100644 --- a/src/frontend/app/viewer/document-viewer.component.html +++ b/src/frontend/app/viewer/document-viewer.component.html @@ -106,7 +106,7 @@ </ng-container> <ng-container *ngIf="editInProgress && editor.mode === 'onlyoffice'"> <onlyoffice-viewer #onlyofficeViewer style="height:100%;width:100%;" [params]="editor.options" [file]="file" - [sidenavLeft]="sidenavLeft" [editMode]="true" (triggerAfterUpdatedDoc)="triggerEvent.emit()" + [editMode]="true" (triggerAfterUpdatedDoc)="triggerEvent.emit()" (triggerCloseEditor)="closeEditor()" (triggerModifiedDocument)="isDocModified = true"></onlyoffice-viewer> </ng-container> <button mat-fab *ngIf="isDocModified && mode === 'mainDocument' && resId !== null" color="accent" diff --git a/src/frontend/app/viewer/document-viewer.component.ts b/src/frontend/app/viewer/document-viewer.component.ts index 8ab0636cc572f6f64798394ee71bf342697691f8..58b52721b00b576b9e1b10f7edc729815ab1b64e 100644 --- a/src/frontend/app/viewer/document-viewer.component.ts +++ b/src/frontend/app/viewer/document-viewer.component.ts @@ -72,8 +72,6 @@ export class DocumentViewerComponent implements OnInit { @Input('attachType') attachType: string = null; @Input('format') format: string = null; - @Input() sidenavLeft: MatSidenav = null; - @Output('triggerEvent') triggerEvent = new EventEmitter<string>(); private eventAction = new Subject<any>(); diff --git a/src/frontend/css/engine_2.scss b/src/frontend/css/engine_2.scss index b1b642390ffb01d66bc7a51406345eb7f1364556..6c6528a6d369389816cc02c5f74ca55225ba7fa8 100644 --- a/src/frontend/css/engine_2.scss +++ b/src/frontend/css/engine_2.scss @@ -1,9 +1,11 @@ /******* CSS ACCORDING TO FINAL CSS *********/ -html,body { +html, +body { width: 100%; height: 100%; overflow: hidden; } + .maarch-container { position: absolute !important; top: 0; @@ -37,6 +39,7 @@ html,body { align-items: center; } + &-tool { flex: none; justify-content: flex-end; @@ -129,6 +132,7 @@ html,body { justify-content: flex-start; display: flex; flex-direction: row-reverse; + span { padding-left: 5px; padding-right: 5px; @@ -141,21 +145,22 @@ html,body { flex-wrap: initial !important; } } + .mat-icon { height: auto; } -.badgePipe_accent{ +.badgePipe_accent { color: #00CB55; font-size: 8px; } -.badgePipe_secondary{ +.badgePipe_secondary { color: #EF8717; font-size: 8px; } -.badgePipe_warn{ +.badgePipe_warn { color: red; font-size: 8px; } @@ -163,4 +168,20 @@ html,body { .mat-menu-content:not(:empty) { padding-top: 0 !important; padding-bottom: 0 !important; +} + +.sideBarForm { + width: 600px !important; + .mat-drawer-inner-container { + display: flex !important; + flex-direction: column !important; + } +} + +.sideBarFormMobile { + width: 95% !important; + .mat-drawer-inner-container { + display: flex !important; + flex-direction: column !important; + } } \ No newline at end of file diff --git a/src/frontend/css/maarch-material.css b/src/frontend/css/maarch-material.css index dc876fd4bd081741c1a54f175bf299c8003bdd59..17ce42e60a2fd08361ca94080de8eef2c1f2eaf5 100755 --- a/src/frontend/css/maarch-material.css +++ b/src/frontend/css/maarch-material.css @@ -1 +1 @@ -.mat-badge-content{font-weight:600;font-size:12px;font-family:Roboto, "Helvetica Neue", sans-serif}.mat-badge-small .mat-badge-content{font-size:9px}.mat-badge-large .mat-badge-content{font-size:24px}.mat-h1,.mat-headline,.mat-typography h1{font:400 24px/32px Roboto, "Helvetica Neue", sans-serif;margin:0 0 16px}.mat-h2,.mat-title,.mat-typography h2{font:500 20px/32px Roboto, "Helvetica Neue", sans-serif;margin:0 0 16px}.mat-h3,.mat-subheading-2,.mat-typography h3{font:400 16px/28px Roboto, "Helvetica Neue", sans-serif;margin:0 0 16px}.mat-h4,.mat-subheading-1,.mat-typography h4{font:400 15px/24px Roboto, "Helvetica Neue", sans-serif;margin:0 0 16px}.mat-h5,.mat-typography h5{font:400 calc(14px * 0.83)/20px Roboto, "Helvetica Neue", sans-serif;margin:0 0 12px}.mat-h6,.mat-typography h6{font:400 calc(14px * 0.67)/20px Roboto, "Helvetica Neue", sans-serif;margin:0 0 12px}.mat-body-strong,.mat-body-2{font:500 14px/24px Roboto, "Helvetica Neue", sans-serif}.mat-body,.mat-body-1,.mat-typography{font:400 14px/20px Roboto, "Helvetica Neue", sans-serif}.mat-body p,.mat-body-1 p,.mat-typography p{margin:0 0 12px}.mat-small,.mat-caption{font:400 12px/20px Roboto, "Helvetica Neue", sans-serif}.mat-display-4,.mat-typography .mat-display-4{font:300 112px/112px Roboto, "Helvetica Neue", sans-serif;letter-spacing:-.05em;margin:0 0 56px}.mat-display-3,.mat-typography .mat-display-3{font:400 56px/56px Roboto, "Helvetica Neue", sans-serif;letter-spacing:-.02em;margin:0 0 64px}.mat-display-2,.mat-typography .mat-display-2{font:400 45px/48px Roboto, "Helvetica Neue", sans-serif;letter-spacing:-.005em;margin:0 0 64px}.mat-display-1,.mat-typography .mat-display-1{font:400 34px/40px Roboto, "Helvetica Neue", sans-serif;margin:0 0 64px}.mat-bottom-sheet-container{font:400 14px/20px Roboto, "Helvetica Neue", sans-serif}.mat-button,.mat-raised-button,.mat-icon-button,.mat-stroked-button,.mat-flat-button,.mat-fab,.mat-mini-fab{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:14px;font-weight:500}.mat-button-toggle{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-card{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-card-title{font-size:24px;font-weight:500}.mat-card-header .mat-card-title{font-size:20px}.mat-card-subtitle,.mat-card-content{font-size:14px}.mat-checkbox{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-checkbox-layout .mat-checkbox-label{line-height:24px}.mat-chip{font-size:14px;font-weight:500}.mat-chip .mat-chip-trailing-icon.mat-icon,.mat-chip .mat-chip-remove.mat-icon{font-size:18px}.mat-table{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-header-cell{font-size:12px;font-weight:500}.mat-cell,.mat-footer-cell{font-size:14px}.mat-calendar{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-calendar-body{font-size:13px}.mat-calendar-body-label,.mat-calendar-period-button{font-size:14px;font-weight:500}.mat-calendar-table-header th{font-size:11px;font-weight:400}.mat-dialog-title{font:500 20px/32px Roboto, "Helvetica Neue", sans-serif}.mat-expansion-panel-header{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:15px;font-weight:400}.mat-expansion-panel-content{font:400 14px/20px Roboto, "Helvetica Neue", sans-serif}.mat-form-field{font-size:inherit;font-weight:400;line-height:1.125;font-family:Roboto, "Helvetica Neue", sans-serif}.mat-form-field-wrapper{padding-bottom:1.34375em}.mat-form-field-prefix .mat-icon,.mat-form-field-suffix .mat-icon{font-size:150%;line-height:1.125}.mat-form-field-prefix .mat-icon-button,.mat-form-field-suffix .mat-icon-button{height:1.5em;width:1.5em}.mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field-suffix .mat-icon-button .mat-icon{height:1.125em;line-height:1.125}.mat-form-field-infix{padding:.5em 0;border-top:.84375em solid transparent}.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.34375em) scale(.75);width:133.33333%}.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.34374em) scale(.75);width:133.33334%}.mat-form-field-label-wrapper{top:-.84375em;padding-top:.84375em}.mat-form-field-label{top:1.34375em}.mat-form-field-underline{bottom:1.34375em}.mat-form-field-subscript-wrapper{font-size:75%;margin-top:.66667em;top:calc(100% - 1.79167em)}.mat-form-field-appearance-legacy .mat-form-field-wrapper{padding-bottom:1.25em}.mat-form-field-appearance-legacy .mat-form-field-infix{padding:.4375em 0}.mat-form-field-appearance-legacy.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(0.001px);-ms-transform:translateY(-1.28125em) scale(.75);width:133.33333%}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(0.00101px);-ms-transform:translateY(-1.28124em) scale(.75);width:133.33334%}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(0.00102px);-ms-transform:translateY(-1.28123em) scale(.75);width:133.33335%}.mat-form-field-appearance-legacy .mat-form-field-label{top:1.28125em}.mat-form-field-appearance-legacy .mat-form-field-underline{bottom:1.25em}.mat-form-field-appearance-legacy .mat-form-field-subscript-wrapper{margin-top:.54167em;top:calc(100% - 1.66667em)}@media print{.mat-form-field-appearance-legacy.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.28122em) scale(.75)}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.28121em) scale(.75)}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.2812em) scale(.75)}}.mat-form-field-appearance-fill .mat-form-field-infix{padding:.25em 0 .75em 0}.mat-form-field-appearance-fill .mat-form-field-label{top:1.09375em;margin-top:-.5em}.mat-form-field-appearance-fill.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,.mat-form-field-appearance-fill.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-.59375em) scale(.75);width:133.33333%}.mat-form-field-appearance-fill.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-.59374em) scale(.75);width:133.33334%}.mat-form-field-appearance-outline .mat-form-field-infix{padding:1em 0 1em 0}.mat-form-field-appearance-outline .mat-form-field-label{top:1.84375em;margin-top:-.25em}.mat-form-field-appearance-outline.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,.mat-form-field-appearance-outline.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.59375em) scale(.75);width:133.33333%}.mat-form-field-appearance-outline.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.59374em) scale(.75);width:133.33334%}.mat-grid-tile-header,.mat-grid-tile-footer{font-size:14px}.mat-grid-tile-header .mat-line,.mat-grid-tile-footer .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-grid-tile-header .mat-line:nth-child(n+2),.mat-grid-tile-footer .mat-line:nth-child(n+2){font-size:12px}input.mat-input-element{margin-top:-.0625em}.mat-menu-item{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:14px;font-weight:400}.mat-paginator,.mat-paginator-page-size .mat-select-trigger{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:12px}.mat-radio-button{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-select{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-select-trigger{height:1.125em}.mat-slide-toggle-content{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-slider-thumb-label-text{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:12px;font-weight:500}.mat-stepper-vertical,.mat-stepper-horizontal{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-step-label{font-size:14px;font-weight:400}.mat-step-sub-label-error{font-weight:normal}.mat-step-label-error{font-size:14px}.mat-step-label-selected{font-size:14px;font-weight:500}.mat-tab-group{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-tab-label,.mat-tab-link{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:14px;font-weight:500}.mat-toolbar,.mat-toolbar h1,.mat-toolbar h2,.mat-toolbar h3,.mat-toolbar h4,.mat-toolbar h5,.mat-toolbar h6{font:500 20px/32px Roboto, "Helvetica Neue", sans-serif;margin:0}.mat-tooltip{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:10px;padding-top:6px;padding-bottom:6px}.mat-tooltip-handset{font-size:14px;padding-top:8px;padding-bottom:8px}.mat-list-item{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-list-option{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-list-base .mat-list-item{font-size:16px}.mat-list-base .mat-list-item .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base .mat-list-item .mat-line:nth-child(n+2){font-size:14px}.mat-list-base .mat-list-option{font-size:16px}.mat-list-base .mat-list-option .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base .mat-list-option .mat-line:nth-child(n+2){font-size:14px}.mat-list-base .mat-subheader{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:14px;font-weight:500}.mat-list-base[dense] .mat-list-item{font-size:12px}.mat-list-base[dense] .mat-list-item .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base[dense] .mat-list-item .mat-line:nth-child(n+2){font-size:12px}.mat-list-base[dense] .mat-list-option{font-size:12px}.mat-list-base[dense] .mat-list-option .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base[dense] .mat-list-option .mat-line:nth-child(n+2){font-size:12px}.mat-list-base[dense] .mat-subheader{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:12px;font-weight:500}.mat-option{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:16px}.mat-optgroup-label{font:500 14px/24px Roboto, "Helvetica Neue", sans-serif}.mat-simple-snackbar{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:14px}.mat-simple-snackbar-action{line-height:1;font-family:inherit;font-size:inherit;font-weight:500}.mat-tree{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-tree-node,.mat-nested-tree-node{font-weight:400;font-size:14px}.mat-ripple{overflow:hidden;position:relative}.mat-ripple.mat-ripple-unbounded{overflow:visible}.mat-ripple-element{position:absolute;border-radius:50%;pointer-events:none;transition:opacity,transform 0ms cubic-bezier(0, 0, 0.2, 1);transform:scale(0)}@media (-ms-high-contrast: active){.mat-ripple-element{display:none}}.cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;outline:0;-webkit-appearance:none;-moz-appearance:none}.cdk-overlay-container,.cdk-global-overlay-wrapper{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:1000;display:flex;max-width:100%;max-height:100%}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;transition:opacity 400ms cubic-bezier(0.25, 0.8, 0.25, 1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:1}@media screen and (-ms-high-contrast: active){.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:0.6}}.cdk-overlay-dark-backdrop{background:rgba(0,0,0,0.32)}.cdk-overlay-transparent-backdrop,.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{opacity:0}.cdk-overlay-connected-position-bounding-box{position:absolute;z-index:1000;display:flex;flex-direction:column;min-width:1px;min-height:1px}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}@keyframes cdk-text-field-autofill-start{/*!*/}@keyframes cdk-text-field-autofill-end{/*!*/}.cdk-text-field-autofill-monitored:-webkit-autofill{animation-name:cdk-text-field-autofill-start}.cdk-text-field-autofill-monitored:not(:-webkit-autofill){animation-name:cdk-text-field-autofill-end}textarea.cdk-textarea-autosize{resize:none}textarea.cdk-textarea-autosize-measuring{height:auto !important;overflow:hidden !important;padding:2px 0 !important;box-sizing:content-box !important}.mat-ripple-element{background-color:rgba(0,0,0,0.1)}.mat-option{color:rgba(0,0,0,0.87)}.mat-option:hover:not(.mat-option-disabled),.mat-option:focus:not(.mat-option-disabled){background:rgba(0,0,0,0.04)}.mat-option.mat-selected:not(.mat-option-multiple):not(.mat-option-disabled){background:rgba(0,0,0,0.04)}.mat-option.mat-active{background:rgba(0,0,0,0.04);color:rgba(0,0,0,0.87)}.mat-option.mat-option-disabled{color:rgba(0,0,0,0.38)}.mat-primary .mat-option.mat-selected:not(.mat-option-disabled){color:#135f7f}.mat-accent .mat-option.mat-selected:not(.mat-option-disabled){color:#006841}.mat-warn .mat-option.mat-selected:not(.mat-option-disabled){color:#8e3e52}.mat-optgroup-label{color:rgba(0,0,0,0.54)}.mat-optgroup-disabled .mat-optgroup-label{color:rgba(0,0,0,0.38)}.mat-pseudo-checkbox{color:rgba(0,0,0,0.54)}.mat-pseudo-checkbox::after{color:#fafafa}.mat-pseudo-checkbox-disabled{color:#b0b0b0}.mat-pseudo-checkbox-checked,.mat-pseudo-checkbox-indeterminate,.mat-accent .mat-pseudo-checkbox-checked,.mat-accent .mat-pseudo-checkbox-indeterminate{background:#006841}.mat-primary .mat-pseudo-checkbox-checked,.mat-primary .mat-pseudo-checkbox-indeterminate{background:#135f7f}.mat-warn .mat-pseudo-checkbox-checked,.mat-warn .mat-pseudo-checkbox-indeterminate{background:#8e3e52}.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled,.mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled{background:#b0b0b0}.mat-elevation-z0{box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-elevation-z1{box-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)}.mat-elevation-z2{box-shadow:0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)}.mat-elevation-z3{box-shadow:0px 3px 3px -2px rgba(0,0,0,0.2),0px 3px 4px 0px rgba(0,0,0,0.14),0px 1px 8px 0px rgba(0,0,0,0.12)}.mat-elevation-z4{box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)}.mat-elevation-z5{box-shadow:0px 3px 5px -1px rgba(0,0,0,0.2),0px 5px 8px 0px rgba(0,0,0,0.14),0px 1px 14px 0px rgba(0,0,0,0.12)}.mat-elevation-z6{box-shadow:0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)}.mat-elevation-z7{box-shadow:0px 4px 5px -2px rgba(0,0,0,0.2),0px 7px 10px 1px rgba(0,0,0,0.14),0px 2px 16px 1px rgba(0,0,0,0.12)}.mat-elevation-z8{box-shadow:0px 5px 5px -3px rgba(0,0,0,0.2),0px 8px 10px 1px rgba(0,0,0,0.14),0px 3px 14px 2px rgba(0,0,0,0.12)}.mat-elevation-z9{box-shadow:0px 5px 6px -3px rgba(0,0,0,0.2),0px 9px 12px 1px rgba(0,0,0,0.14),0px 3px 16px 2px rgba(0,0,0,0.12)}.mat-elevation-z10{box-shadow:0px 6px 6px -3px rgba(0,0,0,0.2),0px 10px 14px 1px rgba(0,0,0,0.14),0px 4px 18px 3px rgba(0,0,0,0.12)}.mat-elevation-z11{box-shadow:0px 6px 7px -4px rgba(0,0,0,0.2),0px 11px 15px 1px rgba(0,0,0,0.14),0px 4px 20px 3px rgba(0,0,0,0.12)}.mat-elevation-z12{box-shadow:0px 7px 8px -4px rgba(0,0,0,0.2),0px 12px 17px 2px rgba(0,0,0,0.14),0px 5px 22px 4px rgba(0,0,0,0.12)}.mat-elevation-z13{box-shadow:0px 7px 8px -4px rgba(0,0,0,0.2),0px 13px 19px 2px rgba(0,0,0,0.14),0px 5px 24px 4px rgba(0,0,0,0.12)}.mat-elevation-z14{box-shadow:0px 7px 9px -4px rgba(0,0,0,0.2),0px 14px 21px 2px rgba(0,0,0,0.14),0px 5px 26px 4px rgba(0,0,0,0.12)}.mat-elevation-z15{box-shadow:0px 8px 9px -5px rgba(0,0,0,0.2),0px 15px 22px 2px rgba(0,0,0,0.14),0px 6px 28px 5px rgba(0,0,0,0.12)}.mat-elevation-z16{box-shadow:0px 8px 10px -5px rgba(0,0,0,0.2),0px 16px 24px 2px rgba(0,0,0,0.14),0px 6px 30px 5px rgba(0,0,0,0.12)}.mat-elevation-z17{box-shadow:0px 8px 11px -5px rgba(0,0,0,0.2),0px 17px 26px 2px rgba(0,0,0,0.14),0px 6px 32px 5px rgba(0,0,0,0.12)}.mat-elevation-z18{box-shadow:0px 9px 11px -5px rgba(0,0,0,0.2),0px 18px 28px 2px rgba(0,0,0,0.14),0px 7px 34px 6px rgba(0,0,0,0.12)}.mat-elevation-z19{box-shadow:0px 9px 12px -6px rgba(0,0,0,0.2),0px 19px 29px 2px rgba(0,0,0,0.14),0px 7px 36px 6px rgba(0,0,0,0.12)}.mat-elevation-z20{box-shadow:0px 10px 13px -6px rgba(0,0,0,0.2),0px 20px 31px 3px rgba(0,0,0,0.14),0px 8px 38px 7px rgba(0,0,0,0.12)}.mat-elevation-z21{box-shadow:0px 10px 13px -6px rgba(0,0,0,0.2),0px 21px 33px 3px rgba(0,0,0,0.14),0px 8px 40px 7px rgba(0,0,0,0.12)}.mat-elevation-z22{box-shadow:0px 10px 14px -6px rgba(0,0,0,0.2),0px 22px 35px 3px rgba(0,0,0,0.14),0px 8px 42px 7px rgba(0,0,0,0.12)}.mat-elevation-z23{box-shadow:0px 11px 14px -7px rgba(0,0,0,0.2),0px 23px 36px 3px rgba(0,0,0,0.14),0px 9px 44px 8px rgba(0,0,0,0.12)}.mat-elevation-z24{box-shadow:0px 11px 15px -7px rgba(0,0,0,0.2),0px 24px 38px 3px rgba(0,0,0,0.14),0px 9px 46px 8px rgba(0,0,0,0.12)}.mat-app-background{background-color:#fafafa;color:rgba(0,0,0,0.87)}.mat-theme-loaded-marker{display:none}.mat-autocomplete-panel{background:#fff;color:rgba(0,0,0,0.87)}.mat-autocomplete-panel:not([class*='mat-elevation-z']){box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)}.mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover){background:#fff}.mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover):not(.mat-option-disabled){color:rgba(0,0,0,0.87)}.mat-badge-content{color:#fff;background:#135f7f}@media (-ms-high-contrast: active){.mat-badge-content{outline:solid 1px;border-radius:0}}.mat-badge-accent .mat-badge-content{background:#006841;color:#fff}.mat-badge-warn .mat-badge-content{color:#fff;background:#8e3e52}.mat-badge{position:relative}.mat-badge-hidden .mat-badge-content{display:none}.mat-badge-disabled .mat-badge-content{background:#b9b9b9;color:rgba(0,0,0,0.38)}.mat-badge-content{position:absolute;text-align:center;display:inline-block;border-radius:50%;transition:transform 200ms ease-in-out;transform:scale(0.6);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;pointer-events:none}.ng-animate-disabled .mat-badge-content,.mat-badge-content._mat-animation-noopable{transition:none}.mat-badge-content.mat-badge-active{transform:none}.mat-badge-small .mat-badge-content{width:16px;height:16px;line-height:16px}.mat-badge-small.mat-badge-above .mat-badge-content{top:-8px}.mat-badge-small.mat-badge-below .mat-badge-content{bottom:-8px}.mat-badge-small.mat-badge-before .mat-badge-content{left:-16px}[dir='rtl'] .mat-badge-small.mat-badge-before .mat-badge-content{left:auto;right:-16px}.mat-badge-small.mat-badge-after .mat-badge-content{right:-16px}[dir='rtl'] .mat-badge-small.mat-badge-after .mat-badge-content{right:auto;left:-16px}.mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-8px}[dir='rtl'] .mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-8px}.mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-8px}[dir='rtl'] .mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-8px}.mat-badge-medium .mat-badge-content{width:22px;height:22px;line-height:22px}.mat-badge-medium.mat-badge-above .mat-badge-content{top:-11px}.mat-badge-medium.mat-badge-below .mat-badge-content{bottom:-11px}.mat-badge-medium.mat-badge-before .mat-badge-content{left:-22px}[dir='rtl'] .mat-badge-medium.mat-badge-before .mat-badge-content{left:auto;right:-22px}.mat-badge-medium.mat-badge-after .mat-badge-content{right:-22px}[dir='rtl'] .mat-badge-medium.mat-badge-after .mat-badge-content{right:auto;left:-22px}.mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-11px}[dir='rtl'] .mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-11px}.mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-11px}[dir='rtl'] .mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-11px}.mat-badge-large .mat-badge-content{width:28px;height:28px;line-height:28px}.mat-badge-large.mat-badge-above .mat-badge-content{top:-14px}.mat-badge-large.mat-badge-below .mat-badge-content{bottom:-14px}.mat-badge-large.mat-badge-before .mat-badge-content{left:-28px}[dir='rtl'] .mat-badge-large.mat-badge-before .mat-badge-content{left:auto;right:-28px}.mat-badge-large.mat-badge-after .mat-badge-content{right:-28px}[dir='rtl'] .mat-badge-large.mat-badge-after .mat-badge-content{right:auto;left:-28px}.mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-14px}[dir='rtl'] .mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-14px}.mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-14px}[dir='rtl'] .mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-14px}.mat-bottom-sheet-container{box-shadow:0px 8px 10px -5px rgba(0,0,0,0.2),0px 16px 24px 2px rgba(0,0,0,0.14),0px 6px 30px 5px rgba(0,0,0,0.12);background:#fff;color:rgba(0,0,0,0.87)}.mat-button,.mat-icon-button,.mat-stroked-button{color:inherit;background:transparent}.mat-button.mat-primary,.mat-icon-button.mat-primary,.mat-stroked-button.mat-primary{color:#135f7f}.mat-button.mat-accent,.mat-icon-button.mat-accent,.mat-stroked-button.mat-accent{color:#006841}.mat-button.mat-warn,.mat-icon-button.mat-warn,.mat-stroked-button.mat-warn{color:#8e3e52}.mat-button.mat-primary[disabled],.mat-button.mat-accent[disabled],.mat-button.mat-warn[disabled],.mat-button[disabled][disabled],.mat-icon-button.mat-primary[disabled],.mat-icon-button.mat-accent[disabled],.mat-icon-button.mat-warn[disabled],.mat-icon-button[disabled][disabled],.mat-stroked-button.mat-primary[disabled],.mat-stroked-button.mat-accent[disabled],.mat-stroked-button.mat-warn[disabled],.mat-stroked-button[disabled][disabled]{color:rgba(0,0,0,0.26)}.mat-button.mat-primary .mat-button-focus-overlay,.mat-icon-button.mat-primary .mat-button-focus-overlay,.mat-stroked-button.mat-primary .mat-button-focus-overlay{background-color:#135f7f}.mat-button.mat-accent .mat-button-focus-overlay,.mat-icon-button.mat-accent .mat-button-focus-overlay,.mat-stroked-button.mat-accent .mat-button-focus-overlay{background-color:#006841}.mat-button.mat-warn .mat-button-focus-overlay,.mat-icon-button.mat-warn .mat-button-focus-overlay,.mat-stroked-button.mat-warn .mat-button-focus-overlay{background-color:#8e3e52}.mat-button[disabled] .mat-button-focus-overlay,.mat-icon-button[disabled] .mat-button-focus-overlay,.mat-stroked-button[disabled] .mat-button-focus-overlay{background-color:transparent}.mat-button .mat-ripple-element,.mat-icon-button .mat-ripple-element,.mat-stroked-button .mat-ripple-element{opacity:.1;background-color:currentColor}.mat-button-focus-overlay{background:#000}.mat-stroked-button:not([disabled]){border-color:rgba(0,0,0,0.12)}.mat-flat-button,.mat-raised-button,.mat-fab,.mat-mini-fab{color:rgba(0,0,0,0.87);background-color:#fff}.mat-flat-button.mat-primary,.mat-raised-button.mat-primary,.mat-fab.mat-primary,.mat-mini-fab.mat-primary{color:#fff}.mat-flat-button.mat-accent,.mat-raised-button.mat-accent,.mat-fab.mat-accent,.mat-mini-fab.mat-accent{color:#fff}.mat-flat-button.mat-warn,.mat-raised-button.mat-warn,.mat-fab.mat-warn,.mat-mini-fab.mat-warn{color:#fff}.mat-flat-button.mat-primary[disabled],.mat-flat-button.mat-accent[disabled],.mat-flat-button.mat-warn[disabled],.mat-flat-button[disabled][disabled],.mat-raised-button.mat-primary[disabled],.mat-raised-button.mat-accent[disabled],.mat-raised-button.mat-warn[disabled],.mat-raised-button[disabled][disabled],.mat-fab.mat-primary[disabled],.mat-fab.mat-accent[disabled],.mat-fab.mat-warn[disabled],.mat-fab[disabled][disabled],.mat-mini-fab.mat-primary[disabled],.mat-mini-fab.mat-accent[disabled],.mat-mini-fab.mat-warn[disabled],.mat-mini-fab[disabled][disabled]{color:rgba(0,0,0,0.26)}.mat-flat-button.mat-primary,.mat-raised-button.mat-primary,.mat-fab.mat-primary,.mat-mini-fab.mat-primary{background-color:#135f7f}.mat-flat-button.mat-accent,.mat-raised-button.mat-accent,.mat-fab.mat-accent,.mat-mini-fab.mat-accent{background-color:#006841}.mat-flat-button.mat-warn,.mat-raised-button.mat-warn,.mat-fab.mat-warn,.mat-mini-fab.mat-warn{background-color:#8e3e52}.mat-flat-button.mat-primary[disabled],.mat-flat-button.mat-accent[disabled],.mat-flat-button.mat-warn[disabled],.mat-flat-button[disabled][disabled],.mat-raised-button.mat-primary[disabled],.mat-raised-button.mat-accent[disabled],.mat-raised-button.mat-warn[disabled],.mat-raised-button[disabled][disabled],.mat-fab.mat-primary[disabled],.mat-fab.mat-accent[disabled],.mat-fab.mat-warn[disabled],.mat-fab[disabled][disabled],.mat-mini-fab.mat-primary[disabled],.mat-mini-fab.mat-accent[disabled],.mat-mini-fab.mat-warn[disabled],.mat-mini-fab[disabled][disabled]{background-color:rgba(0,0,0,0.12)}.mat-flat-button.mat-primary .mat-ripple-element,.mat-raised-button.mat-primary .mat-ripple-element,.mat-fab.mat-primary .mat-ripple-element,.mat-mini-fab.mat-primary .mat-ripple-element{background-color:rgba(255,255,255,0.1)}.mat-flat-button.mat-accent .mat-ripple-element,.mat-raised-button.mat-accent .mat-ripple-element,.mat-fab.mat-accent .mat-ripple-element,.mat-mini-fab.mat-accent .mat-ripple-element{background-color:rgba(255,255,255,0.1)}.mat-flat-button.mat-warn .mat-ripple-element,.mat-raised-button.mat-warn .mat-ripple-element,.mat-fab.mat-warn .mat-ripple-element,.mat-mini-fab.mat-warn .mat-ripple-element{background-color:rgba(255,255,255,0.1)}.mat-stroked-button:not([class*='mat-elevation-z']),.mat-flat-button:not([class*='mat-elevation-z']){box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-raised-button:not([class*='mat-elevation-z']){box-shadow:0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)}.mat-raised-button:not([disabled]):active:not([class*='mat-elevation-z']){box-shadow:0px 5px 5px -3px rgba(0,0,0,0.2),0px 8px 10px 1px rgba(0,0,0,0.14),0px 3px 14px 2px rgba(0,0,0,0.12)}.mat-raised-button[disabled]:not([class*='mat-elevation-z']){box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-fab:not([class*='mat-elevation-z']),.mat-mini-fab:not([class*='mat-elevation-z']){box-shadow:0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)}.mat-fab:not([disabled]):active:not([class*='mat-elevation-z']),.mat-mini-fab:not([disabled]):active:not([class*='mat-elevation-z']){box-shadow:0px 7px 8px -4px rgba(0,0,0,0.2),0px 12px 17px 2px rgba(0,0,0,0.14),0px 5px 22px 4px rgba(0,0,0,0.12)}.mat-fab[disabled]:not([class*='mat-elevation-z']),.mat-mini-fab[disabled]:not([class*='mat-elevation-z']){box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-button-toggle-standalone,.mat-button-toggle-group{box-shadow:0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)}.mat-button-toggle-standalone.mat-button-toggle-appearance-standard,.mat-button-toggle-group-appearance-standard{box-shadow:none}.mat-button-toggle{color:rgba(0,0,0,0.38)}.mat-button-toggle .mat-button-toggle-focus-overlay{background-color:rgba(0,0,0,0.12)}.mat-button-toggle-appearance-standard{color:rgba(0,0,0,0.87);background:#fff}.mat-button-toggle-appearance-standard .mat-button-toggle-focus-overlay{background-color:#000}.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:solid 1px rgba(0,0,0,0.12)}[dir='rtl'] .mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none;border-right:solid 1px rgba(0,0,0,0.12)}.mat-button-toggle-group-appearance-standard.mat-button-toggle-vertical .mat-button-toggle+.mat-button-toggle{border-left:none;border-right:none;border-top:solid 1px rgba(0,0,0,0.12)}.mat-button-toggle-checked{background-color:#e0e0e0;color:rgba(0,0,0,0.54)}.mat-button-toggle-checked.mat-button-toggle-appearance-standard{color:rgba(0,0,0,0.87)}.mat-button-toggle-disabled{color:rgba(0,0,0,0.26);background-color:#eee}.mat-button-toggle-disabled.mat-button-toggle-appearance-standard{background:#fff}.mat-button-toggle-disabled.mat-button-toggle-checked{background-color:#bdbdbd}.mat-button-toggle-standalone.mat-button-toggle-appearance-standard,.mat-button-toggle-group-appearance-standard{border:solid 1px rgba(0,0,0,0.12)}.mat-card{background:#fff;color:rgba(0,0,0,0.87)}.mat-card:not([class*='mat-elevation-z']){box-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)}.mat-card.mat-card-flat:not([class*='mat-elevation-z']){box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-card-subtitle{color:rgba(0,0,0,0.54)}.mat-checkbox-frame{border-color:rgba(0,0,0,0.54)}.mat-checkbox-checkmark{fill:#fafafa}.mat-checkbox-checkmark-path{stroke:#fafafa !important}@media (-ms-high-contrast: black-on-white){.mat-checkbox-checkmark-path{stroke:#000 !important}}.mat-checkbox-mixedmark{background-color:#fafafa}.mat-checkbox-indeterminate.mat-primary .mat-checkbox-background,.mat-checkbox-checked.mat-primary .mat-checkbox-background{background-color:#135f7f}.mat-checkbox-indeterminate.mat-accent .mat-checkbox-background,.mat-checkbox-checked.mat-accent .mat-checkbox-background{background-color:#006841}.mat-checkbox-indeterminate.mat-warn .mat-checkbox-background,.mat-checkbox-checked.mat-warn .mat-checkbox-background{background-color:#8e3e52}.mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background,.mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background{background-color:#b0b0b0}.mat-checkbox-disabled:not(.mat-checkbox-checked) .mat-checkbox-frame{border-color:#b0b0b0}.mat-checkbox-disabled .mat-checkbox-label{color:rgba(0,0,0,0.54)}@media (-ms-high-contrast: active){.mat-checkbox-disabled{opacity:0.5}}@media (-ms-high-contrast: active){.mat-checkbox-background{background:none}}.mat-checkbox .mat-ripple-element{background-color:#000}.mat-checkbox-checked:not(.mat-checkbox-disabled).mat-primary .mat-ripple-element,.mat-checkbox:active:not(.mat-checkbox-disabled).mat-primary .mat-ripple-element{background:#135f7f}.mat-checkbox-checked:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element,.mat-checkbox:active:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element{background:#006841}.mat-checkbox-checked:not(.mat-checkbox-disabled).mat-warn .mat-ripple-element,.mat-checkbox:active:not(.mat-checkbox-disabled).mat-warn .mat-ripple-element{background:#8e3e52}.mat-chip.mat-standard-chip{background-color:#e0e0e0;color:rgba(0,0,0,0.87)}.mat-chip.mat-standard-chip .mat-chip-remove{color:rgba(0,0,0,0.87);opacity:0.4}.mat-chip.mat-standard-chip:not(.mat-chip-disabled):active{box-shadow:0px 3px 3px -2px rgba(0,0,0,0.2),0px 3px 4px 0px rgba(0,0,0,0.14),0px 1px 8px 0px rgba(0,0,0,0.12)}.mat-chip.mat-standard-chip:not(.mat-chip-disabled) .mat-chip-remove:hover{opacity:0.54}.mat-chip.mat-standard-chip.mat-chip-disabled{opacity:0.4}.mat-chip.mat-standard-chip::after{background:#000}.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary{background-color:#135f7f;color:#fff}.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary .mat-chip-remove{color:#fff;opacity:0.4}.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary .mat-ripple-element{background:rgba(255,255,255,0.1)}.mat-chip.mat-standard-chip.mat-chip-selected.mat-warn{background-color:#8e3e52;color:#fff}.mat-chip.mat-standard-chip.mat-chip-selected.mat-warn .mat-chip-remove{color:#fff;opacity:0.4}.mat-chip.mat-standard-chip.mat-chip-selected.mat-warn .mat-ripple-element{background:rgba(255,255,255,0.1)}.mat-chip.mat-standard-chip.mat-chip-selected.mat-accent{background-color:#006841;color:#fff}.mat-chip.mat-standard-chip.mat-chip-selected.mat-accent .mat-chip-remove{color:#fff;opacity:0.4}.mat-chip.mat-standard-chip.mat-chip-selected.mat-accent .mat-ripple-element{background:rgba(255,255,255,0.1)}.mat-table{background:#fff}.mat-table thead,.mat-table tbody,.mat-table tfoot,mat-header-row,mat-row,mat-footer-row,[mat-header-row],[mat-row],[mat-footer-row],.mat-table-sticky{background:inherit}mat-row,mat-header-row,mat-footer-row,th.mat-header-cell,td.mat-cell,td.mat-footer-cell{border-bottom-color:rgba(0,0,0,0.12)}.mat-header-cell{color:rgba(0,0,0,0.54)}.mat-cell,.mat-footer-cell{color:rgba(0,0,0,0.87)}.mat-calendar-arrow{border-top-color:rgba(0,0,0,0.54)}.mat-datepicker-toggle,.mat-datepicker-content .mat-calendar-next-button,.mat-datepicker-content .mat-calendar-previous-button{color:rgba(0,0,0,0.54)}.mat-calendar-table-header{color:rgba(0,0,0,0.38)}.mat-calendar-table-header-divider::after{background:rgba(0,0,0,0.12)}.mat-calendar-body-label{color:rgba(0,0,0,0.54)}.mat-calendar-body-cell-content{color:rgba(0,0,0,0.87);border-color:transparent}.mat-calendar-body-disabled>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){color:rgba(0,0,0,0.38)}.mat-calendar-body-cell:not(.mat-calendar-body-disabled):hover>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.cdk-program-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){background-color:rgba(0,0,0,0.04)}.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,0.38)}.mat-calendar-body-disabled>.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,0.18)}.mat-calendar-body-selected{background-color:#135f7f;color:#fff}.mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(19,95,127,0.4)}.mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px #fff}.mat-datepicker-content{box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12);background-color:#fff;color:rgba(0,0,0,0.87)}.mat-datepicker-content.mat-accent .mat-calendar-body-selected{background-color:#006841;color:#fff}.mat-datepicker-content.mat-accent .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(0,104,65,0.4)}.mat-datepicker-content.mat-accent .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px #fff}.mat-datepicker-content.mat-warn .mat-calendar-body-selected{background-color:#8e3e52;color:#fff}.mat-datepicker-content.mat-warn .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(142,62,82,0.4)}.mat-datepicker-content.mat-warn .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px #fff}.mat-datepicker-content-touch{box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-datepicker-toggle-active{color:#135f7f}.mat-datepicker-toggle-active.mat-accent{color:#006841}.mat-datepicker-toggle-active.mat-warn{color:#8e3e52}.mat-dialog-container{box-shadow:0px 11px 15px -7px rgba(0,0,0,0.2),0px 24px 38px 3px rgba(0,0,0,0.14),0px 9px 46px 8px rgba(0,0,0,0.12);background:#fff;color:rgba(0,0,0,0.87)}.mat-divider{border-top-color:rgba(0,0,0,0.12)}.mat-divider-vertical{border-right-color:rgba(0,0,0,0.12)}.mat-expansion-panel{background:#fff;color:rgba(0,0,0,0.87)}.mat-expansion-panel:not([class*='mat-elevation-z']){box-shadow:0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)}.mat-action-row{border-top-color:rgba(0,0,0,0.12)}.mat-expansion-panel .mat-expansion-panel-header.cdk-keyboard-focused:not([aria-disabled='true']),.mat-expansion-panel .mat-expansion-panel-header.cdk-program-focused:not([aria-disabled='true']),.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:hover:not([aria-disabled='true']){background:rgba(0,0,0,0.04)}@media (hover: none){.mat-expansion-panel:not(.mat-expanded):not([aria-disabled='true']) .mat-expansion-panel-header:hover{background:#fff}}.mat-expansion-panel-header-title{color:rgba(0,0,0,0.87)}.mat-expansion-panel-header-description,.mat-expansion-indicator::after{color:rgba(0,0,0,0.54)}.mat-expansion-panel-header[aria-disabled='true']{color:rgba(0,0,0,0.26)}.mat-expansion-panel-header[aria-disabled='true'] .mat-expansion-panel-header-title,.mat-expansion-panel-header[aria-disabled='true'] .mat-expansion-panel-header-description{color:inherit}.mat-form-field-label{color:rgba(0,0,0,0.6)}.mat-hint{color:rgba(0,0,0,0.6)}.mat-form-field.mat-focused .mat-form-field-label{color:#135f7f}.mat-form-field.mat-focused .mat-form-field-label.mat-accent{color:#006841}.mat-form-field.mat-focused .mat-form-field-label.mat-warn{color:#8e3e52}.mat-focused .mat-form-field-required-marker{color:#006841}.mat-form-field-ripple{background-color:rgba(0,0,0,0.87)}.mat-form-field.mat-focused .mat-form-field-ripple{background-color:#135f7f}.mat-form-field.mat-focused .mat-form-field-ripple.mat-accent{background-color:#006841}.mat-form-field.mat-focused .mat-form-field-ripple.mat-warn{background-color:#8e3e52}.mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid) .mat-form-field-infix::after{color:#135f7f}.mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid).mat-accent .mat-form-field-infix::after{color:#006841}.mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid).mat-warn .mat-form-field-infix::after{color:#8e3e52}.mat-form-field.mat-form-field-invalid .mat-form-field-label{color:#8e3e52}.mat-form-field.mat-form-field-invalid .mat-form-field-label.mat-accent,.mat-form-field.mat-form-field-invalid .mat-form-field-label .mat-form-field-required-marker{color:#8e3e52}.mat-form-field.mat-form-field-invalid .mat-form-field-ripple,.mat-form-field.mat-form-field-invalid .mat-form-field-ripple.mat-accent{background-color:#8e3e52}.mat-error{color:#8e3e52}.mat-form-field-appearance-legacy .mat-form-field-label{color:rgba(0,0,0,0.54)}.mat-form-field-appearance-legacy .mat-hint{color:rgba(0,0,0,0.54)}.mat-form-field-appearance-legacy .mat-form-field-underline{background-color:rgba(0,0,0,0.42)}.mat-form-field-appearance-legacy.mat-form-field-disabled .mat-form-field-underline{background-image:linear-gradient(to right, rgba(0,0,0,0.42) 0%, rgba(0,0,0,0.42) 33%, transparent 0%);background-size:4px 100%;background-repeat:repeat-x}.mat-form-field-appearance-standard .mat-form-field-underline{background-color:rgba(0,0,0,0.42)}.mat-form-field-appearance-standard.mat-form-field-disabled .mat-form-field-underline{background-image:linear-gradient(to right, rgba(0,0,0,0.42) 0%, rgba(0,0,0,0.42) 33%, transparent 0%);background-size:4px 100%;background-repeat:repeat-x}.mat-form-field-appearance-fill .mat-form-field-flex{background-color:rgba(0,0,0,0.04)}.mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-flex{background-color:rgba(0,0,0,0.02)}.mat-form-field-appearance-fill .mat-form-field-underline::before{background-color:rgba(0,0,0,0.42)}.mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-label{color:rgba(0,0,0,0.38)}.mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-underline::before{background-color:transparent}.mat-form-field-appearance-outline .mat-form-field-outline{color:rgba(0,0,0,0.12)}.mat-form-field-appearance-outline .mat-form-field-outline-thick{color:rgba(0,0,0,0.87)}.mat-form-field-appearance-outline.mat-focused .mat-form-field-outline-thick{color:#135f7f}.mat-form-field-appearance-outline.mat-focused.mat-accent .mat-form-field-outline-thick{color:#006841}.mat-form-field-appearance-outline.mat-focused.mat-warn .mat-form-field-outline-thick{color:#8e3e52}.mat-form-field-appearance-outline.mat-form-field-invalid.mat-form-field-invalid .mat-form-field-outline-thick{color:#8e3e52}.mat-form-field-appearance-outline.mat-form-field-disabled .mat-form-field-label{color:rgba(0,0,0,0.38)}.mat-form-field-appearance-outline.mat-form-field-disabled .mat-form-field-outline{color:rgba(0,0,0,0.06)}.mat-icon.mat-primary{color:#135f7f}.mat-icon.mat-accent{color:#006841}.mat-icon.mat-warn{color:#8e3e52}.mat-form-field-type-mat-native-select .mat-form-field-infix::after{color:rgba(0,0,0,0.54)}.mat-input-element:disabled,.mat-form-field-type-mat-native-select.mat-form-field-disabled .mat-form-field-infix::after{color:rgba(0,0,0,0.38)}.mat-input-element{caret-color:#135f7f}.mat-input-element::placeholder{color:rgba(0,0,0,0.42)}.mat-input-element::-moz-placeholder{color:rgba(0,0,0,0.42)}.mat-input-element::-webkit-input-placeholder{color:rgba(0,0,0,0.42)}.mat-input-element:-ms-input-placeholder{color:rgba(0,0,0,0.42)}.mat-accent .mat-input-element{caret-color:#006841}.mat-warn .mat-input-element,.mat-form-field-invalid .mat-input-element{caret-color:#8e3e52}.mat-form-field-type-mat-native-select.mat-form-field-invalid .mat-form-field-infix::after{color:#8e3e52}.mat-list-base .mat-list-item{color:rgba(0,0,0,0.87)}.mat-list-base .mat-list-option{color:rgba(0,0,0,0.87)}.mat-list-base .mat-subheader{color:rgba(0,0,0,0.54)}.mat-list-item-disabled{background-color:#eee}.mat-list-option:hover,.mat-list-option:focus,.mat-nav-list .mat-list-item:hover,.mat-nav-list .mat-list-item:focus,.mat-action-list .mat-list-item:hover,.mat-action-list .mat-list-item:focus{background:rgba(0,0,0,0.04)}.mat-menu-panel{background:#fff}.mat-menu-panel:not([class*='mat-elevation-z']){box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)}.mat-menu-item{background:transparent;color:rgba(0,0,0,0.87)}.mat-menu-item[disabled],.mat-menu-item[disabled]::after{color:rgba(0,0,0,0.38)}.mat-menu-item .mat-icon-no-color,.mat-menu-item-submenu-trigger::after{color:rgba(0,0,0,0.54)}.mat-menu-item:hover:not([disabled]),.mat-menu-item.cdk-program-focused:not([disabled]),.mat-menu-item.cdk-keyboard-focused:not([disabled]),.mat-menu-item-highlighted:not([disabled]){background:rgba(0,0,0,0.04)}.mat-paginator{background:#fff}.mat-paginator,.mat-paginator-page-size .mat-select-trigger{color:rgba(0,0,0,0.54)}.mat-paginator-decrement,.mat-paginator-increment{border-top:2px solid rgba(0,0,0,0.54);border-right:2px solid rgba(0,0,0,0.54)}.mat-paginator-first,.mat-paginator-last{border-top:2px solid rgba(0,0,0,0.54)}.mat-icon-button[disabled] .mat-paginator-decrement,.mat-icon-button[disabled] .mat-paginator-increment,.mat-icon-button[disabled] .mat-paginator-first,.mat-icon-button[disabled] .mat-paginator-last{border-color:rgba(0,0,0,0.38)}.mat-progress-bar-background{fill:#1a80ab}.mat-progress-bar-buffer{background-color:#1a80ab}.mat-progress-bar-fill::after{background-color:#135f7f}.mat-progress-bar.mat-accent .mat-progress-bar-background{fill:#009b61}.mat-progress-bar.mat-accent .mat-progress-bar-buffer{background-color:#009b61}.mat-progress-bar.mat-accent .mat-progress-bar-fill::after{background-color:#006841}.mat-progress-bar.mat-warn .mat-progress-bar-background{fill:#b24e67}.mat-progress-bar.mat-warn .mat-progress-bar-buffer{background-color:#b24e67}.mat-progress-bar.mat-warn .mat-progress-bar-fill::after{background-color:#8e3e52}.mat-progress-spinner circle,.mat-spinner circle{stroke:#135f7f}.mat-progress-spinner.mat-accent circle,.mat-spinner.mat-accent circle{stroke:#006841}.mat-progress-spinner.mat-warn circle,.mat-spinner.mat-warn circle{stroke:#8e3e52}.mat-radio-outer-circle{border-color:rgba(0,0,0,0.54)}.mat-radio-button.mat-primary.mat-radio-checked .mat-radio-outer-circle{border-color:#135f7f}.mat-radio-button.mat-primary .mat-radio-inner-circle,.mat-radio-button.mat-primary .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.mat-radio-button.mat-primary.mat-radio-checked .mat-radio-persistent-ripple,.mat-radio-button.mat-primary:active .mat-radio-persistent-ripple{background-color:#135f7f}.mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#006841}.mat-radio-button.mat-accent .mat-radio-inner-circle,.mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.mat-radio-button.mat-accent.mat-radio-checked .mat-radio-persistent-ripple,.mat-radio-button.mat-accent:active .mat-radio-persistent-ripple{background-color:#006841}.mat-radio-button.mat-warn.mat-radio-checked .mat-radio-outer-circle{border-color:#8e3e52}.mat-radio-button.mat-warn .mat-radio-inner-circle,.mat-radio-button.mat-warn .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.mat-radio-button.mat-warn.mat-radio-checked .mat-radio-persistent-ripple,.mat-radio-button.mat-warn:active .mat-radio-persistent-ripple{background-color:#8e3e52}.mat-radio-button.mat-radio-disabled.mat-radio-checked .mat-radio-outer-circle,.mat-radio-button.mat-radio-disabled .mat-radio-outer-circle{border-color:rgba(0,0,0,0.38)}.mat-radio-button.mat-radio-disabled .mat-radio-ripple .mat-ripple-element,.mat-radio-button.mat-radio-disabled .mat-radio-inner-circle{background-color:rgba(0,0,0,0.38)}.mat-radio-button.mat-radio-disabled .mat-radio-label-content{color:rgba(0,0,0,0.38)}.mat-radio-button .mat-ripple-element{background-color:#000}.mat-select-value{color:rgba(0,0,0,0.87)}.mat-select-placeholder{color:rgba(0,0,0,0.42)}.mat-select-disabled .mat-select-value{color:rgba(0,0,0,0.38)}.mat-select-arrow{color:rgba(0,0,0,0.54)}.mat-select-panel{background:#fff}.mat-select-panel:not([class*='mat-elevation-z']){box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)}.mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple){background:rgba(0,0,0,0.12)}.mat-form-field.mat-focused.mat-primary .mat-select-arrow{color:#135f7f}.mat-form-field.mat-focused.mat-accent .mat-select-arrow{color:#006841}.mat-form-field.mat-focused.mat-warn .mat-select-arrow{color:#8e3e52}.mat-form-field .mat-select.mat-select-invalid .mat-select-arrow{color:#8e3e52}.mat-form-field .mat-select.mat-select-disabled .mat-select-arrow{color:rgba(0,0,0,0.38)}.mat-drawer-container{background-color:#fafafa;color:rgba(0,0,0,0.87)}.mat-drawer{background-color:#fff;color:rgba(0,0,0,0.87)}.mat-drawer.mat-drawer-push{background-color:#fff}.mat-drawer:not(.mat-drawer-side){box-shadow:0px 8px 10px -5px rgba(0,0,0,0.2),0px 16px 24px 2px rgba(0,0,0,0.14),0px 6px 30px 5px rgba(0,0,0,0.12)}.mat-drawer-side{border-right:solid 1px rgba(0,0,0,0.12)}.mat-drawer-side.mat-drawer-end{border-left:solid 1px rgba(0,0,0,0.12);border-right:none}[dir='rtl'] .mat-drawer-side{border-left:solid 1px rgba(0,0,0,0.12);border-right:none}[dir='rtl'] .mat-drawer-side.mat-drawer-end{border-left:none;border-right:solid 1px rgba(0,0,0,0.12)}.mat-drawer-backdrop.mat-drawer-shown{background-color:rgba(0,0,0,0.6)}.mat-slide-toggle.mat-checked .mat-slide-toggle-thumb{background-color:#006841}.mat-slide-toggle.mat-checked .mat-slide-toggle-bar{background-color:rgba(0,104,65,0.54)}.mat-slide-toggle.mat-checked .mat-ripple-element{background-color:#006841}.mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-thumb{background-color:#135f7f}.mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-bar{background-color:rgba(19,95,127,0.54)}.mat-slide-toggle.mat-primary.mat-checked .mat-ripple-element{background-color:#135f7f}.mat-slide-toggle.mat-warn.mat-checked .mat-slide-toggle-thumb{background-color:#8e3e52}.mat-slide-toggle.mat-warn.mat-checked .mat-slide-toggle-bar{background-color:rgba(142,62,82,0.54)}.mat-slide-toggle.mat-warn.mat-checked .mat-ripple-element{background-color:#8e3e52}.mat-slide-toggle:not(.mat-checked) .mat-ripple-element{background-color:#000}.mat-slide-toggle-thumb{box-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12);background-color:#fafafa}.mat-slide-toggle-bar{background-color:rgba(0,0,0,0.38)}.mat-slider-track-background{background-color:rgba(0,0,0,0.26)}.mat-primary .mat-slider-track-fill,.mat-primary .mat-slider-thumb,.mat-primary .mat-slider-thumb-label{background-color:#135f7f}.mat-primary .mat-slider-thumb-label-text{color:#fff}.mat-accent .mat-slider-track-fill,.mat-accent .mat-slider-thumb,.mat-accent .mat-slider-thumb-label{background-color:#006841}.mat-accent .mat-slider-thumb-label-text{color:#fff}.mat-warn .mat-slider-track-fill,.mat-warn .mat-slider-thumb,.mat-warn .mat-slider-thumb-label{background-color:#8e3e52}.mat-warn .mat-slider-thumb-label-text{color:#fff}.mat-slider-focus-ring{background-color:rgba(0,104,65,0.2)}.mat-slider:hover .mat-slider-track-background,.cdk-focused .mat-slider-track-background{background-color:rgba(0,0,0,0.38)}.mat-slider-disabled .mat-slider-track-background,.mat-slider-disabled .mat-slider-track-fill,.mat-slider-disabled .mat-slider-thumb{background-color:rgba(0,0,0,0.26)}.mat-slider-disabled:hover .mat-slider-track-background{background-color:rgba(0,0,0,0.26)}.mat-slider-min-value .mat-slider-focus-ring{background-color:rgba(0,0,0,0.12)}.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb-label{background-color:rgba(0,0,0,0.87)}.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb-label{background-color:rgba(0,0,0,0.26)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing) .mat-slider-thumb{border-color:rgba(0,0,0,0.26);background-color:transparent}.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused .mat-slider-thumb{border-color:rgba(0,0,0,0.38)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover.mat-slider-disabled .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused.mat-slider-disabled .mat-slider-thumb{border-color:rgba(0,0,0,0.26)}.mat-slider-has-ticks .mat-slider-wrapper::after{border-color:rgba(0,0,0,0.7)}.mat-slider-horizontal .mat-slider-ticks{background-image:repeating-linear-gradient(to right, rgba(0,0,0,0.7), rgba(0,0,0,0.7) 2px, transparent 0, transparent);background-image:-moz-repeating-linear-gradient(0.0001deg, rgba(0,0,0,0.7), rgba(0,0,0,0.7) 2px, transparent 0, transparent)}.mat-slider-vertical .mat-slider-ticks{background-image:repeating-linear-gradient(to bottom, rgba(0,0,0,0.7), rgba(0,0,0,0.7) 2px, transparent 0, transparent)}.mat-step-header.cdk-keyboard-focused,.mat-step-header.cdk-program-focused,.mat-step-header:hover{background-color:rgba(0,0,0,0.04)}@media (hover: none){.mat-step-header:hover{background:none}}.mat-step-header .mat-step-label,.mat-step-header .mat-step-optional{color:rgba(0,0,0,0.54)}.mat-step-header .mat-step-icon{background-color:rgba(0,0,0,0.54);color:#fff}.mat-step-header .mat-step-icon-selected,.mat-step-header .mat-step-icon-state-done,.mat-step-header .mat-step-icon-state-edit{background-color:#135f7f;color:#fff}.mat-step-header .mat-step-icon-state-error{background-color:transparent;color:#8e3e52}.mat-step-header .mat-step-label.mat-step-label-active{color:rgba(0,0,0,0.87)}.mat-step-header .mat-step-label.mat-step-label-error{color:#8e3e52}.mat-stepper-horizontal,.mat-stepper-vertical{background-color:#fff}.mat-stepper-vertical-line::before{border-left-color:rgba(0,0,0,0.12)}.mat-horizontal-stepper-header::before,.mat-horizontal-stepper-header::after,.mat-stepper-horizontal-line{border-top-color:rgba(0,0,0,0.12)}.mat-sort-header-arrow{color:#757575}.mat-tab-nav-bar,.mat-tab-header{border-bottom:1px solid rgba(0,0,0,0.12)}.mat-tab-group-inverted-header .mat-tab-nav-bar,.mat-tab-group-inverted-header .mat-tab-header{border-top:1px solid rgba(0,0,0,0.12);border-bottom:none}.mat-tab-label,.mat-tab-link{color:rgba(0,0,0,0.87)}.mat-tab-label.mat-tab-disabled,.mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,0.38)}.mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,0.87)}.mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,0.38)}.mat-tab-group[class*='mat-background-'] .mat-tab-header,.mat-tab-nav-bar[class*='mat-background-']{border-bottom:none;border-top:none}.mat-tab-group.mat-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(26,128,171,0.3)}.mat-tab-group.mat-primary .mat-ink-bar,.mat-tab-nav-bar.mat-primary .mat-ink-bar{background-color:#135f7f}.mat-tab-group.mat-primary.mat-background-primary .mat-ink-bar,.mat-tab-nav-bar.mat-primary.mat-background-primary .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(0,155,97,0.3)}.mat-tab-group.mat-accent .mat-ink-bar,.mat-tab-nav-bar.mat-accent .mat-ink-bar{background-color:#006841}.mat-tab-group.mat-accent.mat-background-accent .mat-ink-bar,.mat-tab-nav-bar.mat-accent.mat-background-accent .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(178,78,103,0.3)}.mat-tab-group.mat-warn .mat-ink-bar,.mat-tab-nav-bar.mat-warn .mat-ink-bar{background-color:#8e3e52}.mat-tab-group.mat-warn.mat-background-warn .mat-ink-bar,.mat-tab-nav-bar.mat-warn.mat-background-warn .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-background-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(26,128,171,0.3)}.mat-tab-group.mat-background-primary .mat-tab-header,.mat-tab-group.mat-background-primary .mat-tab-links,.mat-tab-group.mat-background-primary .mat-tab-header-pagination,.mat-tab-nav-bar.mat-background-primary .mat-tab-header,.mat-tab-nav-bar.mat-background-primary .mat-tab-links,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination{background-color:#135f7f}.mat-tab-group.mat-background-primary .mat-tab-label,.mat-tab-group.mat-background-primary .mat-tab-link,.mat-tab-nav-bar.mat-background-primary .mat-tab-label,.mat-tab-nav-bar.mat-background-primary .mat-tab-link{color:#fff}.mat-tab-group.mat-background-primary .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-primary .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-primary .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-primary .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-primary .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-primary .mat-ripple-element,.mat-tab-nav-bar.mat-background-primary .mat-ripple-element{background-color:rgba(255,255,255,0.12)}.mat-tab-group.mat-background-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(0,155,97,0.3)}.mat-tab-group.mat-background-accent .mat-tab-header,.mat-tab-group.mat-background-accent .mat-tab-links,.mat-tab-group.mat-background-accent .mat-tab-header-pagination,.mat-tab-nav-bar.mat-background-accent .mat-tab-header,.mat-tab-nav-bar.mat-background-accent .mat-tab-links,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination{background-color:#006841}.mat-tab-group.mat-background-accent .mat-tab-label,.mat-tab-group.mat-background-accent .mat-tab-link,.mat-tab-nav-bar.mat-background-accent .mat-tab-label,.mat-tab-nav-bar.mat-background-accent .mat-tab-link{color:#fff}.mat-tab-group.mat-background-accent .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-accent .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-accent .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-accent .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-accent .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-accent .mat-ripple-element,.mat-tab-nav-bar.mat-background-accent .mat-ripple-element{background-color:rgba(255,255,255,0.12)}.mat-tab-group.mat-background-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(178,78,103,0.3)}.mat-tab-group.mat-background-warn .mat-tab-header,.mat-tab-group.mat-background-warn .mat-tab-links,.mat-tab-group.mat-background-warn .mat-tab-header-pagination,.mat-tab-nav-bar.mat-background-warn .mat-tab-header,.mat-tab-nav-bar.mat-background-warn .mat-tab-links,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination{background-color:#8e3e52}.mat-tab-group.mat-background-warn .mat-tab-label,.mat-tab-group.mat-background-warn .mat-tab-link,.mat-tab-nav-bar.mat-background-warn .mat-tab-label,.mat-tab-nav-bar.mat-background-warn .mat-tab-link{color:#fff}.mat-tab-group.mat-background-warn .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-warn .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-warn .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-warn .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-warn .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-warn .mat-ripple-element,.mat-tab-nav-bar.mat-background-warn .mat-ripple-element{background-color:rgba(255,255,255,0.12)}.mat-toolbar{background:#f5f5f5;color:rgba(0,0,0,0.87)}.mat-toolbar.mat-primary{background:#135f7f;color:#fff}.mat-toolbar.mat-accent{background:#006841;color:#fff}.mat-toolbar.mat-warn{background:#8e3e52;color:#fff}.mat-toolbar .mat-form-field-underline,.mat-toolbar .mat-form-field-ripple,.mat-toolbar .mat-focused .mat-form-field-ripple{background-color:currentColor}.mat-toolbar .mat-form-field-label,.mat-toolbar .mat-focused .mat-form-field-label,.mat-toolbar .mat-select-value,.mat-toolbar .mat-select-arrow,.mat-toolbar .mat-form-field.mat-focused .mat-select-arrow{color:inherit}.mat-toolbar .mat-input-element{caret-color:currentColor}.mat-tooltip{background:rgba(97,97,97,0.9)}.mat-tree{background:#fff}.mat-tree-node,.mat-nested-tree-node{color:rgba(0,0,0,0.87)}.mat-snack-bar-container{color:rgba(255,255,255,0.7);background:#323232;box-shadow:0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)}.mat-simple-snackbar-action{color:#006841}[color=primary]{color:#135f7f}[color=secondary]{color:#F99830}[color=warn]{color:#8e3e52}[color=accent]{color:#006841}[bgcolor=primary]{background-color:#135f7f}[bgcolor=warn]{background-color:#8e3e52}[bgcolor=accent]{background-color:#006841}.jstree-proton .jstree-clicked{background:#1a80ab !important}.jstree-proton :not(.jstree-disabled).jstree-hovered{background:#1a80ab !important;box-shadow:inset 0 0 1px #135f7f !important}.jstree-proton .jstree-disabled:hover{cursor:not-allowed}.dndFile{border:dashed 5px grey;padding:10px;text-align:center;opacity:0.5;font-size:15px;font-weight:bolder;margin:20px}.dndFileHighlighted{opacity:1 !important;border:dashed 5px #135f7f !important;color:#135f7f}.cdk-textarea-autosize{min-height:18px !important} +.mat-badge-content{font-weight:600;font-size:12px;font-family:Roboto, "Helvetica Neue", sans-serif}.mat-badge-small .mat-badge-content{font-size:9px}.mat-badge-large .mat-badge-content{font-size:24px}.mat-h1,.mat-headline,.mat-typography h1{font:400 24px/32px Roboto, "Helvetica Neue", sans-serif;margin:0 0 16px}.mat-h2,.mat-title,.mat-typography h2{font:500 20px/32px Roboto, "Helvetica Neue", sans-serif;margin:0 0 16px}.mat-h3,.mat-subheading-2,.mat-typography h3{font:400 16px/28px Roboto, "Helvetica Neue", sans-serif;margin:0 0 16px}.mat-h4,.mat-subheading-1,.mat-typography h4{font:400 15px/24px Roboto, "Helvetica Neue", sans-serif;margin:0 0 16px}.mat-h5,.mat-typography h5{font:400 calc(14px * 0.83)/20px Roboto, "Helvetica Neue", sans-serif;margin:0 0 12px}.mat-h6,.mat-typography h6{font:400 calc(14px * 0.67)/20px Roboto, "Helvetica Neue", sans-serif;margin:0 0 12px}.mat-body-strong,.mat-body-2{font:500 14px/24px Roboto, "Helvetica Neue", sans-serif}.mat-body,.mat-body-1,.mat-typography{font:400 14px/20px Roboto, "Helvetica Neue", sans-serif}.mat-body p,.mat-body-1 p,.mat-typography p{margin:0 0 12px}.mat-small,.mat-caption{font:400 12px/20px Roboto, "Helvetica Neue", sans-serif}.mat-display-4,.mat-typography .mat-display-4{font:300 112px/112px Roboto, "Helvetica Neue", sans-serif;letter-spacing:-.05em;margin:0 0 56px}.mat-display-3,.mat-typography .mat-display-3{font:400 56px/56px Roboto, "Helvetica Neue", sans-serif;letter-spacing:-.02em;margin:0 0 64px}.mat-display-2,.mat-typography .mat-display-2{font:400 45px/48px Roboto, "Helvetica Neue", sans-serif;letter-spacing:-.005em;margin:0 0 64px}.mat-display-1,.mat-typography .mat-display-1{font:400 34px/40px Roboto, "Helvetica Neue", sans-serif;margin:0 0 64px}.mat-bottom-sheet-container{font:400 14px/20px Roboto, "Helvetica Neue", sans-serif}.mat-button,.mat-raised-button,.mat-icon-button,.mat-stroked-button,.mat-flat-button,.mat-fab,.mat-mini-fab{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:14px;font-weight:500}.mat-button-toggle{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-card{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-card-title{font-size:24px;font-weight:500}.mat-card-header .mat-card-title{font-size:20px}.mat-card-subtitle,.mat-card-content{font-size:14px}.mat-checkbox{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-checkbox-layout .mat-checkbox-label{line-height:24px}.mat-chip{font-size:14px;font-weight:500}.mat-chip .mat-chip-trailing-icon.mat-icon,.mat-chip .mat-chip-remove.mat-icon{font-size:18px}.mat-table{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-header-cell{font-size:12px;font-weight:500}.mat-cell,.mat-footer-cell{font-size:14px}.mat-calendar{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-calendar-body{font-size:13px}.mat-calendar-body-label,.mat-calendar-period-button{font-size:14px;font-weight:500}.mat-calendar-table-header th{font-size:11px;font-weight:400}.mat-dialog-title{font:500 20px/32px Roboto, "Helvetica Neue", sans-serif}.mat-expansion-panel-header{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:15px;font-weight:400}.mat-expansion-panel-content{font:400 14px/20px Roboto, "Helvetica Neue", sans-serif}.mat-form-field{font-size:inherit;font-weight:400;line-height:1.125;font-family:Roboto, "Helvetica Neue", sans-serif}.mat-form-field-wrapper{padding-bottom:1.34375em}.mat-form-field-prefix .mat-icon,.mat-form-field-suffix .mat-icon{font-size:150%;line-height:1.125}.mat-form-field-prefix .mat-icon-button,.mat-form-field-suffix .mat-icon-button{height:1.5em;width:1.5em}.mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field-suffix .mat-icon-button .mat-icon{height:1.125em;line-height:1.125}.mat-form-field-infix{padding:.5em 0;border-top:.84375em solid transparent}.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.34375em) scale(.75);width:133.33333%}.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.34374em) scale(.75);width:133.33334%}.mat-form-field-label-wrapper{top:-.84375em;padding-top:.84375em}.mat-form-field-label{top:1.34375em}.mat-form-field-underline{bottom:1.34375em}.mat-form-field-subscript-wrapper{font-size:75%;margin-top:.66667em;top:calc(100% - 1.79167em)}.mat-form-field-appearance-legacy .mat-form-field-wrapper{padding-bottom:1.25em}.mat-form-field-appearance-legacy .mat-form-field-infix{padding:.4375em 0}.mat-form-field-appearance-legacy.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(0.001px);-ms-transform:translateY(-1.28125em) scale(.75);width:133.33333%}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(0.00101px);-ms-transform:translateY(-1.28124em) scale(.75);width:133.33334%}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.28125em) scale(.75) perspective(100px) translateZ(0.00102px);-ms-transform:translateY(-1.28123em) scale(.75);width:133.33335%}.mat-form-field-appearance-legacy .mat-form-field-label{top:1.28125em}.mat-form-field-appearance-legacy .mat-form-field-underline{bottom:1.25em}.mat-form-field-appearance-legacy .mat-form-field-subscript-wrapper{margin-top:.54167em;top:calc(100% - 1.66667em)}@media print{.mat-form-field-appearance-legacy.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.28122em) scale(.75)}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.28121em) scale(.75)}.mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.2812em) scale(.75)}}.mat-form-field-appearance-fill .mat-form-field-infix{padding:.25em 0 .75em 0}.mat-form-field-appearance-fill .mat-form-field-label{top:1.09375em;margin-top:-.5em}.mat-form-field-appearance-fill.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,.mat-form-field-appearance-fill.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-.59375em) scale(.75);width:133.33333%}.mat-form-field-appearance-fill.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-.59374em) scale(.75);width:133.33334%}.mat-form-field-appearance-outline .mat-form-field-infix{padding:1em 0 1em 0}.mat-form-field-appearance-outline .mat-form-field-label{top:1.84375em;margin-top:-.25em}.mat-form-field-appearance-outline.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,.mat-form-field-appearance-outline.mat-form-field-can-float .mat-input-server:focus+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.59375em) scale(.75);width:133.33333%}.mat-form-field-appearance-outline.mat-form-field-can-float .mat-input-server[label]:not(:label-shown)+.mat-form-field-label-wrapper .mat-form-field-label{transform:translateY(-1.59374em) scale(.75);width:133.33334%}.mat-grid-tile-header,.mat-grid-tile-footer{font-size:14px}.mat-grid-tile-header .mat-line,.mat-grid-tile-footer .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-grid-tile-header .mat-line:nth-child(n+2),.mat-grid-tile-footer .mat-line:nth-child(n+2){font-size:12px}input.mat-input-element{margin-top:-.0625em}.mat-menu-item{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:14px;font-weight:400}.mat-paginator,.mat-paginator-page-size .mat-select-trigger{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:12px}.mat-radio-button{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-select{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-select-trigger{height:1.125em}.mat-slide-toggle-content{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-slider-thumb-label-text{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:12px;font-weight:500}.mat-stepper-vertical,.mat-stepper-horizontal{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-step-label{font-size:14px;font-weight:400}.mat-step-sub-label-error{font-weight:normal}.mat-step-label-error{font-size:14px}.mat-step-label-selected{font-size:14px;font-weight:500}.mat-tab-group{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-tab-label,.mat-tab-link{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:14px;font-weight:500}.mat-toolbar,.mat-toolbar h1,.mat-toolbar h2,.mat-toolbar h3,.mat-toolbar h4,.mat-toolbar h5,.mat-toolbar h6{font:500 20px/32px Roboto, "Helvetica Neue", sans-serif;margin:0}.mat-tooltip{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:10px;padding-top:6px;padding-bottom:6px}.mat-tooltip-handset{font-size:14px;padding-top:8px;padding-bottom:8px}.mat-list-item{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-list-option{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-list-base .mat-list-item{font-size:16px}.mat-list-base .mat-list-item .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base .mat-list-item .mat-line:nth-child(n+2){font-size:14px}.mat-list-base .mat-list-option{font-size:16px}.mat-list-base .mat-list-option .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base .mat-list-option .mat-line:nth-child(n+2){font-size:14px}.mat-list-base .mat-subheader{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:14px;font-weight:500}.mat-list-base[dense] .mat-list-item{font-size:12px}.mat-list-base[dense] .mat-list-item .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base[dense] .mat-list-item .mat-line:nth-child(n+2){font-size:12px}.mat-list-base[dense] .mat-list-option{font-size:12px}.mat-list-base[dense] .mat-list-option .mat-line{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;box-sizing:border-box}.mat-list-base[dense] .mat-list-option .mat-line:nth-child(n+2){font-size:12px}.mat-list-base[dense] .mat-subheader{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:12px;font-weight:500}.mat-option{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:16px}.mat-optgroup-label{font:500 14px/24px Roboto, "Helvetica Neue", sans-serif}.mat-simple-snackbar{font-family:Roboto, "Helvetica Neue", sans-serif;font-size:14px}.mat-simple-snackbar-action{line-height:1;font-family:inherit;font-size:inherit;font-weight:500}.mat-tree{font-family:Roboto, "Helvetica Neue", sans-serif}.mat-tree-node,.mat-nested-tree-node{font-weight:400;font-size:14px}.mat-ripple{overflow:hidden;position:relative}.mat-ripple.mat-ripple-unbounded{overflow:visible}.mat-ripple-element{position:absolute;border-radius:50%;pointer-events:none;transition:opacity,transform 0ms cubic-bezier(0, 0, 0.2, 1);transform:scale(0)}@media (-ms-high-contrast: active){.mat-ripple-element{display:none}}.cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;outline:0;-webkit-appearance:none;-moz-appearance:none}.cdk-overlay-container,.cdk-global-overlay-wrapper{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:1000;display:flex;max-width:100%;max-height:100%}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;transition:opacity 400ms cubic-bezier(0.25, 0.8, 0.25, 1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:1}@media screen and (-ms-high-contrast: active){.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:0.6}}.cdk-overlay-dark-backdrop{background:rgba(0,0,0,0.32)}.cdk-overlay-transparent-backdrop,.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{opacity:0}.cdk-overlay-connected-position-bounding-box{position:absolute;z-index:1000;display:flex;flex-direction:column;min-width:1px;min-height:1px}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}@keyframes cdk-text-field-autofill-start{/*!*/}@keyframes cdk-text-field-autofill-end{/*!*/}.cdk-text-field-autofill-monitored:-webkit-autofill{animation-name:cdk-text-field-autofill-start}.cdk-text-field-autofill-monitored:not(:-webkit-autofill){animation-name:cdk-text-field-autofill-end}textarea.cdk-textarea-autosize{resize:none}textarea.cdk-textarea-autosize-measuring{height:auto !important;overflow:hidden !important;padding:2px 0 !important;box-sizing:content-box !important}.mat-ripple-element{background-color:rgba(0,0,0,0.1)}.mat-option{color:rgba(0,0,0,0.87)}.mat-option:hover:not(.mat-option-disabled),.mat-option:focus:not(.mat-option-disabled){background:rgba(0,0,0,0.04)}.mat-option.mat-selected:not(.mat-option-multiple):not(.mat-option-disabled){background:rgba(0,0,0,0.04)}.mat-option.mat-active{background:rgba(0,0,0,0.04);color:rgba(0,0,0,0.87)}.mat-option.mat-option-disabled{color:rgba(0,0,0,0.38)}.mat-primary .mat-option.mat-selected:not(.mat-option-disabled){color:#135f7f}.mat-accent .mat-option.mat-selected:not(.mat-option-disabled){color:#006841}.mat-warn .mat-option.mat-selected:not(.mat-option-disabled){color:#8e3e52}.mat-optgroup-label{color:rgba(0,0,0,0.54)}.mat-optgroup-disabled .mat-optgroup-label{color:rgba(0,0,0,0.38)}.mat-pseudo-checkbox{color:rgba(0,0,0,0.54)}.mat-pseudo-checkbox::after{color:#fafafa}.mat-pseudo-checkbox-disabled{color:#b0b0b0}.mat-primary .mat-pseudo-checkbox-checked,.mat-primary .mat-pseudo-checkbox-indeterminate{background:#135f7f}.mat-pseudo-checkbox-checked,.mat-pseudo-checkbox-indeterminate,.mat-accent .mat-pseudo-checkbox-checked,.mat-accent .mat-pseudo-checkbox-indeterminate{background:#006841}.mat-warn .mat-pseudo-checkbox-checked,.mat-warn .mat-pseudo-checkbox-indeterminate{background:#8e3e52}.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled,.mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled{background:#b0b0b0}.mat-elevation-z0{box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-elevation-z1{box-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)}.mat-elevation-z2{box-shadow:0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)}.mat-elevation-z3{box-shadow:0px 3px 3px -2px rgba(0,0,0,0.2),0px 3px 4px 0px rgba(0,0,0,0.14),0px 1px 8px 0px rgba(0,0,0,0.12)}.mat-elevation-z4{box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)}.mat-elevation-z5{box-shadow:0px 3px 5px -1px rgba(0,0,0,0.2),0px 5px 8px 0px rgba(0,0,0,0.14),0px 1px 14px 0px rgba(0,0,0,0.12)}.mat-elevation-z6{box-shadow:0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)}.mat-elevation-z7{box-shadow:0px 4px 5px -2px rgba(0,0,0,0.2),0px 7px 10px 1px rgba(0,0,0,0.14),0px 2px 16px 1px rgba(0,0,0,0.12)}.mat-elevation-z8{box-shadow:0px 5px 5px -3px rgba(0,0,0,0.2),0px 8px 10px 1px rgba(0,0,0,0.14),0px 3px 14px 2px rgba(0,0,0,0.12)}.mat-elevation-z9{box-shadow:0px 5px 6px -3px rgba(0,0,0,0.2),0px 9px 12px 1px rgba(0,0,0,0.14),0px 3px 16px 2px rgba(0,0,0,0.12)}.mat-elevation-z10{box-shadow:0px 6px 6px -3px rgba(0,0,0,0.2),0px 10px 14px 1px rgba(0,0,0,0.14),0px 4px 18px 3px rgba(0,0,0,0.12)}.mat-elevation-z11{box-shadow:0px 6px 7px -4px rgba(0,0,0,0.2),0px 11px 15px 1px rgba(0,0,0,0.14),0px 4px 20px 3px rgba(0,0,0,0.12)}.mat-elevation-z12{box-shadow:0px 7px 8px -4px rgba(0,0,0,0.2),0px 12px 17px 2px rgba(0,0,0,0.14),0px 5px 22px 4px rgba(0,0,0,0.12)}.mat-elevation-z13{box-shadow:0px 7px 8px -4px rgba(0,0,0,0.2),0px 13px 19px 2px rgba(0,0,0,0.14),0px 5px 24px 4px rgba(0,0,0,0.12)}.mat-elevation-z14{box-shadow:0px 7px 9px -4px rgba(0,0,0,0.2),0px 14px 21px 2px rgba(0,0,0,0.14),0px 5px 26px 4px rgba(0,0,0,0.12)}.mat-elevation-z15{box-shadow:0px 8px 9px -5px rgba(0,0,0,0.2),0px 15px 22px 2px rgba(0,0,0,0.14),0px 6px 28px 5px rgba(0,0,0,0.12)}.mat-elevation-z16{box-shadow:0px 8px 10px -5px rgba(0,0,0,0.2),0px 16px 24px 2px rgba(0,0,0,0.14),0px 6px 30px 5px rgba(0,0,0,0.12)}.mat-elevation-z17{box-shadow:0px 8px 11px -5px rgba(0,0,0,0.2),0px 17px 26px 2px rgba(0,0,0,0.14),0px 6px 32px 5px rgba(0,0,0,0.12)}.mat-elevation-z18{box-shadow:0px 9px 11px -5px rgba(0,0,0,0.2),0px 18px 28px 2px rgba(0,0,0,0.14),0px 7px 34px 6px rgba(0,0,0,0.12)}.mat-elevation-z19{box-shadow:0px 9px 12px -6px rgba(0,0,0,0.2),0px 19px 29px 2px rgba(0,0,0,0.14),0px 7px 36px 6px rgba(0,0,0,0.12)}.mat-elevation-z20{box-shadow:0px 10px 13px -6px rgba(0,0,0,0.2),0px 20px 31px 3px rgba(0,0,0,0.14),0px 8px 38px 7px rgba(0,0,0,0.12)}.mat-elevation-z21{box-shadow:0px 10px 13px -6px rgba(0,0,0,0.2),0px 21px 33px 3px rgba(0,0,0,0.14),0px 8px 40px 7px rgba(0,0,0,0.12)}.mat-elevation-z22{box-shadow:0px 10px 14px -6px rgba(0,0,0,0.2),0px 22px 35px 3px rgba(0,0,0,0.14),0px 8px 42px 7px rgba(0,0,0,0.12)}.mat-elevation-z23{box-shadow:0px 11px 14px -7px rgba(0,0,0,0.2),0px 23px 36px 3px rgba(0,0,0,0.14),0px 9px 44px 8px rgba(0,0,0,0.12)}.mat-elevation-z24{box-shadow:0px 11px 15px -7px rgba(0,0,0,0.2),0px 24px 38px 3px rgba(0,0,0,0.14),0px 9px 46px 8px rgba(0,0,0,0.12)}.mat-app-background{background-color:#fafafa;color:rgba(0,0,0,0.87)}.mat-theme-loaded-marker{display:none}.mat-autocomplete-panel{background:#fff;color:rgba(0,0,0,0.87)}.mat-autocomplete-panel:not([class*='mat-elevation-z']){box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)}.mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover){background:#fff}.mat-autocomplete-panel .mat-option.mat-selected:not(.mat-active):not(:hover):not(.mat-option-disabled){color:rgba(0,0,0,0.87)}.mat-badge-content{color:#fff;background:#135f7f}@media (-ms-high-contrast: active){.mat-badge-content{outline:solid 1px;border-radius:0}}.mat-badge-accent .mat-badge-content{background:#006841;color:#fff}.mat-badge-warn .mat-badge-content{color:#fff;background:#8e3e52}.mat-badge{position:relative}.mat-badge-hidden .mat-badge-content{display:none}.mat-badge-disabled .mat-badge-content{background:#b9b9b9;color:rgba(0,0,0,0.38)}.mat-badge-content{position:absolute;text-align:center;display:inline-block;border-radius:50%;transition:transform 200ms ease-in-out;transform:scale(0.6);overflow:hidden;white-space:nowrap;text-overflow:ellipsis;pointer-events:none}.ng-animate-disabled .mat-badge-content,.mat-badge-content._mat-animation-noopable{transition:none}.mat-badge-content.mat-badge-active{transform:none}.mat-badge-small .mat-badge-content{width:16px;height:16px;line-height:16px}.mat-badge-small.mat-badge-above .mat-badge-content{top:-8px}.mat-badge-small.mat-badge-below .mat-badge-content{bottom:-8px}.mat-badge-small.mat-badge-before .mat-badge-content{left:-16px}[dir='rtl'] .mat-badge-small.mat-badge-before .mat-badge-content{left:auto;right:-16px}.mat-badge-small.mat-badge-after .mat-badge-content{right:-16px}[dir='rtl'] .mat-badge-small.mat-badge-after .mat-badge-content{right:auto;left:-16px}.mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-8px}[dir='rtl'] .mat-badge-small.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-8px}.mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-8px}[dir='rtl'] .mat-badge-small.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-8px}.mat-badge-medium .mat-badge-content{width:22px;height:22px;line-height:22px}.mat-badge-medium.mat-badge-above .mat-badge-content{top:-11px}.mat-badge-medium.mat-badge-below .mat-badge-content{bottom:-11px}.mat-badge-medium.mat-badge-before .mat-badge-content{left:-22px}[dir='rtl'] .mat-badge-medium.mat-badge-before .mat-badge-content{left:auto;right:-22px}.mat-badge-medium.mat-badge-after .mat-badge-content{right:-22px}[dir='rtl'] .mat-badge-medium.mat-badge-after .mat-badge-content{right:auto;left:-22px}.mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-11px}[dir='rtl'] .mat-badge-medium.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-11px}.mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-11px}[dir='rtl'] .mat-badge-medium.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-11px}.mat-badge-large .mat-badge-content{width:28px;height:28px;line-height:28px}.mat-badge-large.mat-badge-above .mat-badge-content{top:-14px}.mat-badge-large.mat-badge-below .mat-badge-content{bottom:-14px}.mat-badge-large.mat-badge-before .mat-badge-content{left:-28px}[dir='rtl'] .mat-badge-large.mat-badge-before .mat-badge-content{left:auto;right:-28px}.mat-badge-large.mat-badge-after .mat-badge-content{right:-28px}[dir='rtl'] .mat-badge-large.mat-badge-after .mat-badge-content{right:auto;left:-28px}.mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:-14px}[dir='rtl'] .mat-badge-large.mat-badge-overlap.mat-badge-before .mat-badge-content{left:auto;right:-14px}.mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:-14px}[dir='rtl'] .mat-badge-large.mat-badge-overlap.mat-badge-after .mat-badge-content{right:auto;left:-14px}.mat-bottom-sheet-container{box-shadow:0px 8px 10px -5px rgba(0,0,0,0.2),0px 16px 24px 2px rgba(0,0,0,0.14),0px 6px 30px 5px rgba(0,0,0,0.12);background:#fff;color:rgba(0,0,0,0.87)}.mat-button,.mat-icon-button,.mat-stroked-button{color:inherit;background:transparent}.mat-button.mat-primary,.mat-icon-button.mat-primary,.mat-stroked-button.mat-primary{color:#135f7f}.mat-button.mat-accent,.mat-icon-button.mat-accent,.mat-stroked-button.mat-accent{color:#006841}.mat-button.mat-warn,.mat-icon-button.mat-warn,.mat-stroked-button.mat-warn{color:#8e3e52}.mat-button.mat-primary[disabled],.mat-button.mat-accent[disabled],.mat-button.mat-warn[disabled],.mat-button[disabled][disabled],.mat-icon-button.mat-primary[disabled],.mat-icon-button.mat-accent[disabled],.mat-icon-button.mat-warn[disabled],.mat-icon-button[disabled][disabled],.mat-stroked-button.mat-primary[disabled],.mat-stroked-button.mat-accent[disabled],.mat-stroked-button.mat-warn[disabled],.mat-stroked-button[disabled][disabled]{color:rgba(0,0,0,0.26)}.mat-button.mat-primary .mat-button-focus-overlay,.mat-icon-button.mat-primary .mat-button-focus-overlay,.mat-stroked-button.mat-primary .mat-button-focus-overlay{background-color:#135f7f}.mat-button.mat-accent .mat-button-focus-overlay,.mat-icon-button.mat-accent .mat-button-focus-overlay,.mat-stroked-button.mat-accent .mat-button-focus-overlay{background-color:#006841}.mat-button.mat-warn .mat-button-focus-overlay,.mat-icon-button.mat-warn .mat-button-focus-overlay,.mat-stroked-button.mat-warn .mat-button-focus-overlay{background-color:#8e3e52}.mat-button[disabled] .mat-button-focus-overlay,.mat-icon-button[disabled] .mat-button-focus-overlay,.mat-stroked-button[disabled] .mat-button-focus-overlay{background-color:transparent}.mat-button .mat-ripple-element,.mat-icon-button .mat-ripple-element,.mat-stroked-button .mat-ripple-element{opacity:.1;background-color:currentColor}.mat-button-focus-overlay{background:#000}.mat-stroked-button:not([disabled]){border-color:rgba(0,0,0,0.12)}.mat-flat-button,.mat-raised-button,.mat-fab,.mat-mini-fab{color:rgba(0,0,0,0.87);background-color:#fff}.mat-flat-button.mat-primary,.mat-raised-button.mat-primary,.mat-fab.mat-primary,.mat-mini-fab.mat-primary{color:#fff}.mat-flat-button.mat-accent,.mat-raised-button.mat-accent,.mat-fab.mat-accent,.mat-mini-fab.mat-accent{color:#fff}.mat-flat-button.mat-warn,.mat-raised-button.mat-warn,.mat-fab.mat-warn,.mat-mini-fab.mat-warn{color:#fff}.mat-flat-button.mat-primary[disabled],.mat-flat-button.mat-accent[disabled],.mat-flat-button.mat-warn[disabled],.mat-flat-button[disabled][disabled],.mat-raised-button.mat-primary[disabled],.mat-raised-button.mat-accent[disabled],.mat-raised-button.mat-warn[disabled],.mat-raised-button[disabled][disabled],.mat-fab.mat-primary[disabled],.mat-fab.mat-accent[disabled],.mat-fab.mat-warn[disabled],.mat-fab[disabled][disabled],.mat-mini-fab.mat-primary[disabled],.mat-mini-fab.mat-accent[disabled],.mat-mini-fab.mat-warn[disabled],.mat-mini-fab[disabled][disabled]{color:rgba(0,0,0,0.26)}.mat-flat-button.mat-primary,.mat-raised-button.mat-primary,.mat-fab.mat-primary,.mat-mini-fab.mat-primary{background-color:#135f7f}.mat-flat-button.mat-accent,.mat-raised-button.mat-accent,.mat-fab.mat-accent,.mat-mini-fab.mat-accent{background-color:#006841}.mat-flat-button.mat-warn,.mat-raised-button.mat-warn,.mat-fab.mat-warn,.mat-mini-fab.mat-warn{background-color:#8e3e52}.mat-flat-button.mat-primary[disabled],.mat-flat-button.mat-accent[disabled],.mat-flat-button.mat-warn[disabled],.mat-flat-button[disabled][disabled],.mat-raised-button.mat-primary[disabled],.mat-raised-button.mat-accent[disabled],.mat-raised-button.mat-warn[disabled],.mat-raised-button[disabled][disabled],.mat-fab.mat-primary[disabled],.mat-fab.mat-accent[disabled],.mat-fab.mat-warn[disabled],.mat-fab[disabled][disabled],.mat-mini-fab.mat-primary[disabled],.mat-mini-fab.mat-accent[disabled],.mat-mini-fab.mat-warn[disabled],.mat-mini-fab[disabled][disabled]{background-color:rgba(0,0,0,0.12)}.mat-flat-button.mat-primary .mat-ripple-element,.mat-raised-button.mat-primary .mat-ripple-element,.mat-fab.mat-primary .mat-ripple-element,.mat-mini-fab.mat-primary .mat-ripple-element{background-color:rgba(255,255,255,0.1)}.mat-flat-button.mat-accent .mat-ripple-element,.mat-raised-button.mat-accent .mat-ripple-element,.mat-fab.mat-accent .mat-ripple-element,.mat-mini-fab.mat-accent .mat-ripple-element{background-color:rgba(255,255,255,0.1)}.mat-flat-button.mat-warn .mat-ripple-element,.mat-raised-button.mat-warn .mat-ripple-element,.mat-fab.mat-warn .mat-ripple-element,.mat-mini-fab.mat-warn .mat-ripple-element{background-color:rgba(255,255,255,0.1)}.mat-stroked-button:not([class*='mat-elevation-z']),.mat-flat-button:not([class*='mat-elevation-z']){box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-raised-button:not([class*='mat-elevation-z']){box-shadow:0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)}.mat-raised-button:not([disabled]):active:not([class*='mat-elevation-z']){box-shadow:0px 5px 5px -3px rgba(0,0,0,0.2),0px 8px 10px 1px rgba(0,0,0,0.14),0px 3px 14px 2px rgba(0,0,0,0.12)}.mat-raised-button[disabled]:not([class*='mat-elevation-z']){box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-fab:not([class*='mat-elevation-z']),.mat-mini-fab:not([class*='mat-elevation-z']){box-shadow:0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)}.mat-fab:not([disabled]):active:not([class*='mat-elevation-z']),.mat-mini-fab:not([disabled]):active:not([class*='mat-elevation-z']){box-shadow:0px 7px 8px -4px rgba(0,0,0,0.2),0px 12px 17px 2px rgba(0,0,0,0.14),0px 5px 22px 4px rgba(0,0,0,0.12)}.mat-fab[disabled]:not([class*='mat-elevation-z']),.mat-mini-fab[disabled]:not([class*='mat-elevation-z']){box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-button-toggle-standalone,.mat-button-toggle-group{box-shadow:0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)}.mat-button-toggle-standalone.mat-button-toggle-appearance-standard,.mat-button-toggle-group-appearance-standard{box-shadow:none}.mat-button-toggle{color:rgba(0,0,0,0.38)}.mat-button-toggle .mat-button-toggle-focus-overlay{background-color:rgba(0,0,0,0.12)}.mat-button-toggle-appearance-standard{color:rgba(0,0,0,0.87);background:#fff}.mat-button-toggle-appearance-standard .mat-button-toggle-focus-overlay{background-color:#000}.mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:solid 1px rgba(0,0,0,0.12)}[dir='rtl'] .mat-button-toggle-group-appearance-standard .mat-button-toggle+.mat-button-toggle{border-left:none;border-right:solid 1px rgba(0,0,0,0.12)}.mat-button-toggle-group-appearance-standard.mat-button-toggle-vertical .mat-button-toggle+.mat-button-toggle{border-left:none;border-right:none;border-top:solid 1px rgba(0,0,0,0.12)}.mat-button-toggle-checked{background-color:#e0e0e0;color:rgba(0,0,0,0.54)}.mat-button-toggle-checked.mat-button-toggle-appearance-standard{color:rgba(0,0,0,0.87)}.mat-button-toggle-disabled{color:rgba(0,0,0,0.26);background-color:#eee}.mat-button-toggle-disabled.mat-button-toggle-appearance-standard{background:#fff}.mat-button-toggle-disabled.mat-button-toggle-checked{background-color:#bdbdbd}.mat-button-toggle-standalone.mat-button-toggle-appearance-standard,.mat-button-toggle-group-appearance-standard{border:solid 1px rgba(0,0,0,0.12)}.mat-card{background:#fff;color:rgba(0,0,0,0.87)}.mat-card:not([class*='mat-elevation-z']){box-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)}.mat-card.mat-card-flat:not([class*='mat-elevation-z']){box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-card-subtitle{color:rgba(0,0,0,0.54)}.mat-checkbox-frame{border-color:rgba(0,0,0,0.54)}.mat-checkbox-checkmark{fill:#fafafa}.mat-checkbox-checkmark-path{stroke:#fafafa !important}@media (-ms-high-contrast: black-on-white){.mat-checkbox-checkmark-path{stroke:#000 !important}}.mat-checkbox-mixedmark{background-color:#fafafa}.mat-checkbox-indeterminate.mat-primary .mat-checkbox-background,.mat-checkbox-checked.mat-primary .mat-checkbox-background{background-color:#135f7f}.mat-checkbox-indeterminate.mat-accent .mat-checkbox-background,.mat-checkbox-checked.mat-accent .mat-checkbox-background{background-color:#006841}.mat-checkbox-indeterminate.mat-warn .mat-checkbox-background,.mat-checkbox-checked.mat-warn .mat-checkbox-background{background-color:#8e3e52}.mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background,.mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background{background-color:#b0b0b0}.mat-checkbox-disabled:not(.mat-checkbox-checked) .mat-checkbox-frame{border-color:#b0b0b0}.mat-checkbox-disabled .mat-checkbox-label{color:rgba(0,0,0,0.54)}@media (-ms-high-contrast: active){.mat-checkbox-disabled{opacity:0.5}}@media (-ms-high-contrast: active){.mat-checkbox-background{background:none}}.mat-checkbox .mat-ripple-element{background-color:#000}.mat-checkbox-checked:not(.mat-checkbox-disabled).mat-primary .mat-ripple-element,.mat-checkbox:active:not(.mat-checkbox-disabled).mat-primary .mat-ripple-element{background:#135f7f}.mat-checkbox-checked:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element,.mat-checkbox:active:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element{background:#006841}.mat-checkbox-checked:not(.mat-checkbox-disabled).mat-warn .mat-ripple-element,.mat-checkbox:active:not(.mat-checkbox-disabled).mat-warn .mat-ripple-element{background:#8e3e52}.mat-chip.mat-standard-chip{background-color:#e0e0e0;color:rgba(0,0,0,0.87)}.mat-chip.mat-standard-chip .mat-chip-remove{color:rgba(0,0,0,0.87);opacity:0.4}.mat-chip.mat-standard-chip:not(.mat-chip-disabled):active{box-shadow:0px 3px 3px -2px rgba(0,0,0,0.2),0px 3px 4px 0px rgba(0,0,0,0.14),0px 1px 8px 0px rgba(0,0,0,0.12)}.mat-chip.mat-standard-chip:not(.mat-chip-disabled) .mat-chip-remove:hover{opacity:0.54}.mat-chip.mat-standard-chip.mat-chip-disabled{opacity:0.4}.mat-chip.mat-standard-chip::after{background:#000}.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary{background-color:#135f7f;color:#fff}.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary .mat-chip-remove{color:#fff;opacity:0.4}.mat-chip.mat-standard-chip.mat-chip-selected.mat-primary .mat-ripple-element{background:rgba(255,255,255,0.1)}.mat-chip.mat-standard-chip.mat-chip-selected.mat-warn{background-color:#8e3e52;color:#fff}.mat-chip.mat-standard-chip.mat-chip-selected.mat-warn .mat-chip-remove{color:#fff;opacity:0.4}.mat-chip.mat-standard-chip.mat-chip-selected.mat-warn .mat-ripple-element{background:rgba(255,255,255,0.1)}.mat-chip.mat-standard-chip.mat-chip-selected.mat-accent{background-color:#006841;color:#fff}.mat-chip.mat-standard-chip.mat-chip-selected.mat-accent .mat-chip-remove{color:#fff;opacity:0.4}.mat-chip.mat-standard-chip.mat-chip-selected.mat-accent .mat-ripple-element{background:rgba(255,255,255,0.1)}.mat-table{background:#fff}.mat-table thead,.mat-table tbody,.mat-table tfoot,mat-header-row,mat-row,mat-footer-row,[mat-header-row],[mat-row],[mat-footer-row],.mat-table-sticky{background:inherit}mat-row,mat-header-row,mat-footer-row,th.mat-header-cell,td.mat-cell,td.mat-footer-cell{border-bottom-color:rgba(0,0,0,0.12)}.mat-header-cell{color:rgba(0,0,0,0.54)}.mat-cell,.mat-footer-cell{color:rgba(0,0,0,0.87)}.mat-calendar-arrow{border-top-color:rgba(0,0,0,0.54)}.mat-datepicker-toggle,.mat-datepicker-content .mat-calendar-next-button,.mat-datepicker-content .mat-calendar-previous-button{color:rgba(0,0,0,0.54)}.mat-calendar-table-header{color:rgba(0,0,0,0.38)}.mat-calendar-table-header-divider::after{background:rgba(0,0,0,0.12)}.mat-calendar-body-label{color:rgba(0,0,0,0.54)}.mat-calendar-body-cell-content{color:rgba(0,0,0,0.87);border-color:transparent}.mat-calendar-body-disabled>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){color:rgba(0,0,0,0.38)}.mat-calendar-body-cell:not(.mat-calendar-body-disabled):hover>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected),.cdk-program-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected){background-color:rgba(0,0,0,0.04)}.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,0.38)}.mat-calendar-body-disabled>.mat-calendar-body-today:not(.mat-calendar-body-selected){border-color:rgba(0,0,0,0.18)}.mat-calendar-body-selected{background-color:#135f7f;color:#fff}.mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(19,95,127,0.4)}.mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px #fff}.mat-datepicker-content{box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12);background-color:#fff;color:rgba(0,0,0,0.87)}.mat-datepicker-content.mat-accent .mat-calendar-body-selected{background-color:#006841;color:#fff}.mat-datepicker-content.mat-accent .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(0,104,65,0.4)}.mat-datepicker-content.mat-accent .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px #fff}.mat-datepicker-content.mat-warn .mat-calendar-body-selected{background-color:#8e3e52;color:#fff}.mat-datepicker-content.mat-warn .mat-calendar-body-disabled>.mat-calendar-body-selected{background-color:rgba(142,62,82,0.4)}.mat-datepicker-content.mat-warn .mat-calendar-body-today.mat-calendar-body-selected{box-shadow:inset 0 0 0 1px #fff}.mat-datepicker-content-touch{box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2),0px 0px 0px 0px rgba(0,0,0,0.14),0px 0px 0px 0px rgba(0,0,0,0.12)}.mat-datepicker-toggle-active{color:#135f7f}.mat-datepicker-toggle-active.mat-accent{color:#006841}.mat-datepicker-toggle-active.mat-warn{color:#8e3e52}.mat-dialog-container{box-shadow:0px 11px 15px -7px rgba(0,0,0,0.2),0px 24px 38px 3px rgba(0,0,0,0.14),0px 9px 46px 8px rgba(0,0,0,0.12);background:#fff;color:rgba(0,0,0,0.87)}.mat-divider{border-top-color:rgba(0,0,0,0.12)}.mat-divider-vertical{border-right-color:rgba(0,0,0,0.12)}.mat-expansion-panel{background:#fff;color:rgba(0,0,0,0.87)}.mat-expansion-panel:not([class*='mat-elevation-z']){box-shadow:0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)}.mat-action-row{border-top-color:rgba(0,0,0,0.12)}.mat-expansion-panel .mat-expansion-panel-header.cdk-keyboard-focused:not([aria-disabled='true']),.mat-expansion-panel .mat-expansion-panel-header.cdk-program-focused:not([aria-disabled='true']),.mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:hover:not([aria-disabled='true']){background:rgba(0,0,0,0.04)}@media (hover: none){.mat-expansion-panel:not(.mat-expanded):not([aria-disabled='true']) .mat-expansion-panel-header:hover{background:#fff}}.mat-expansion-panel-header-title{color:rgba(0,0,0,0.87)}.mat-expansion-panel-header-description,.mat-expansion-indicator::after{color:rgba(0,0,0,0.54)}.mat-expansion-panel-header[aria-disabled='true']{color:rgba(0,0,0,0.26)}.mat-expansion-panel-header[aria-disabled='true'] .mat-expansion-panel-header-title,.mat-expansion-panel-header[aria-disabled='true'] .mat-expansion-panel-header-description{color:inherit}.mat-form-field-label{color:rgba(0,0,0,0.6)}.mat-hint{color:rgba(0,0,0,0.6)}.mat-form-field.mat-focused .mat-form-field-label{color:#135f7f}.mat-form-field.mat-focused .mat-form-field-label.mat-accent{color:#006841}.mat-form-field.mat-focused .mat-form-field-label.mat-warn{color:#8e3e52}.mat-focused .mat-form-field-required-marker{color:#006841}.mat-form-field-ripple{background-color:rgba(0,0,0,0.87)}.mat-form-field.mat-focused .mat-form-field-ripple{background-color:#135f7f}.mat-form-field.mat-focused .mat-form-field-ripple.mat-accent{background-color:#006841}.mat-form-field.mat-focused .mat-form-field-ripple.mat-warn{background-color:#8e3e52}.mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid) .mat-form-field-infix::after{color:#135f7f}.mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid).mat-accent .mat-form-field-infix::after{color:#006841}.mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid).mat-warn .mat-form-field-infix::after{color:#8e3e52}.mat-form-field.mat-form-field-invalid .mat-form-field-label{color:#8e3e52}.mat-form-field.mat-form-field-invalid .mat-form-field-label.mat-accent,.mat-form-field.mat-form-field-invalid .mat-form-field-label .mat-form-field-required-marker{color:#8e3e52}.mat-form-field.mat-form-field-invalid .mat-form-field-ripple,.mat-form-field.mat-form-field-invalid .mat-form-field-ripple.mat-accent{background-color:#8e3e52}.mat-error{color:#8e3e52}.mat-form-field-appearance-legacy .mat-form-field-label{color:rgba(0,0,0,0.54)}.mat-form-field-appearance-legacy .mat-hint{color:rgba(0,0,0,0.54)}.mat-form-field-appearance-legacy .mat-form-field-underline{background-color:rgba(0,0,0,0.42)}.mat-form-field-appearance-legacy.mat-form-field-disabled .mat-form-field-underline{background-image:linear-gradient(to right, rgba(0,0,0,0.42) 0%, rgba(0,0,0,0.42) 33%, transparent 0%);background-size:4px 100%;background-repeat:repeat-x}.mat-form-field-appearance-standard .mat-form-field-underline{background-color:rgba(0,0,0,0.42)}.mat-form-field-appearance-standard.mat-form-field-disabled .mat-form-field-underline{background-image:linear-gradient(to right, rgba(0,0,0,0.42) 0%, rgba(0,0,0,0.42) 33%, transparent 0%);background-size:4px 100%;background-repeat:repeat-x}.mat-form-field-appearance-fill .mat-form-field-flex{background-color:rgba(0,0,0,0.04)}.mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-flex{background-color:rgba(0,0,0,0.02)}.mat-form-field-appearance-fill .mat-form-field-underline::before{background-color:rgba(0,0,0,0.42)}.mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-label{color:rgba(0,0,0,0.38)}.mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-underline::before{background-color:transparent}.mat-form-field-appearance-outline .mat-form-field-outline{color:rgba(0,0,0,0.12)}.mat-form-field-appearance-outline .mat-form-field-outline-thick{color:rgba(0,0,0,0.87)}.mat-form-field-appearance-outline.mat-focused .mat-form-field-outline-thick{color:#135f7f}.mat-form-field-appearance-outline.mat-focused.mat-accent .mat-form-field-outline-thick{color:#006841}.mat-form-field-appearance-outline.mat-focused.mat-warn .mat-form-field-outline-thick{color:#8e3e52}.mat-form-field-appearance-outline.mat-form-field-invalid.mat-form-field-invalid .mat-form-field-outline-thick{color:#8e3e52}.mat-form-field-appearance-outline.mat-form-field-disabled .mat-form-field-label{color:rgba(0,0,0,0.38)}.mat-form-field-appearance-outline.mat-form-field-disabled .mat-form-field-outline{color:rgba(0,0,0,0.06)}.mat-icon.mat-primary{color:#135f7f}.mat-icon.mat-accent{color:#006841}.mat-icon.mat-warn{color:#8e3e52}.mat-form-field-type-mat-native-select .mat-form-field-infix::after{color:rgba(0,0,0,0.54)}.mat-input-element:disabled,.mat-form-field-type-mat-native-select.mat-form-field-disabled .mat-form-field-infix::after{color:rgba(0,0,0,0.38)}.mat-input-element{caret-color:#135f7f}.mat-input-element::placeholder{color:rgba(0,0,0,0.42)}.mat-input-element::-moz-placeholder{color:rgba(0,0,0,0.42)}.mat-input-element::-webkit-input-placeholder{color:rgba(0,0,0,0.42)}.mat-input-element:-ms-input-placeholder{color:rgba(0,0,0,0.42)}.mat-accent .mat-input-element{caret-color:#006841}.mat-warn .mat-input-element,.mat-form-field-invalid .mat-input-element{caret-color:#8e3e52}.mat-form-field-type-mat-native-select.mat-form-field-invalid .mat-form-field-infix::after{color:#8e3e52}.mat-list-base .mat-list-item{color:rgba(0,0,0,0.87)}.mat-list-base .mat-list-option{color:rgba(0,0,0,0.87)}.mat-list-base .mat-subheader{color:rgba(0,0,0,0.54)}.mat-list-item-disabled{background-color:#eee}.mat-list-option:hover,.mat-list-option:focus,.mat-nav-list .mat-list-item:hover,.mat-nav-list .mat-list-item:focus,.mat-action-list .mat-list-item:hover,.mat-action-list .mat-list-item:focus{background:rgba(0,0,0,0.04)}.mat-menu-panel{background:#fff}.mat-menu-panel:not([class*='mat-elevation-z']){box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)}.mat-menu-item{background:transparent;color:rgba(0,0,0,0.87)}.mat-menu-item[disabled],.mat-menu-item[disabled]::after{color:rgba(0,0,0,0.38)}.mat-menu-item .mat-icon-no-color,.mat-menu-item-submenu-trigger::after{color:rgba(0,0,0,0.54)}.mat-menu-item:hover:not([disabled]),.mat-menu-item.cdk-program-focused:not([disabled]),.mat-menu-item.cdk-keyboard-focused:not([disabled]),.mat-menu-item-highlighted:not([disabled]){background:rgba(0,0,0,0.04)}.mat-paginator{background:#fff}.mat-paginator,.mat-paginator-page-size .mat-select-trigger{color:rgba(0,0,0,0.54)}.mat-paginator-decrement,.mat-paginator-increment{border-top:2px solid rgba(0,0,0,0.54);border-right:2px solid rgba(0,0,0,0.54)}.mat-paginator-first,.mat-paginator-last{border-top:2px solid rgba(0,0,0,0.54)}.mat-icon-button[disabled] .mat-paginator-decrement,.mat-icon-button[disabled] .mat-paginator-increment,.mat-icon-button[disabled] .mat-paginator-first,.mat-icon-button[disabled] .mat-paginator-last{border-color:rgba(0,0,0,0.38)}.mat-progress-bar-background{fill:#1a80ab}.mat-progress-bar-buffer{background-color:#1a80ab}.mat-progress-bar-fill::after{background-color:#135f7f}.mat-progress-bar.mat-accent .mat-progress-bar-background{fill:#009b61}.mat-progress-bar.mat-accent .mat-progress-bar-buffer{background-color:#009b61}.mat-progress-bar.mat-accent .mat-progress-bar-fill::after{background-color:#006841}.mat-progress-bar.mat-warn .mat-progress-bar-background{fill:#b24e67}.mat-progress-bar.mat-warn .mat-progress-bar-buffer{background-color:#b24e67}.mat-progress-bar.mat-warn .mat-progress-bar-fill::after{background-color:#8e3e52}.mat-progress-spinner circle,.mat-spinner circle{stroke:#135f7f}.mat-progress-spinner.mat-accent circle,.mat-spinner.mat-accent circle{stroke:#006841}.mat-progress-spinner.mat-warn circle,.mat-spinner.mat-warn circle{stroke:#8e3e52}.mat-radio-outer-circle{border-color:rgba(0,0,0,0.54)}.mat-radio-button.mat-primary.mat-radio-checked .mat-radio-outer-circle{border-color:#135f7f}.mat-radio-button.mat-primary .mat-radio-inner-circle,.mat-radio-button.mat-primary .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.mat-radio-button.mat-primary.mat-radio-checked .mat-radio-persistent-ripple,.mat-radio-button.mat-primary:active .mat-radio-persistent-ripple{background-color:#135f7f}.mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#006841}.mat-radio-button.mat-accent .mat-radio-inner-circle,.mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.mat-radio-button.mat-accent.mat-radio-checked .mat-radio-persistent-ripple,.mat-radio-button.mat-accent:active .mat-radio-persistent-ripple{background-color:#006841}.mat-radio-button.mat-warn.mat-radio-checked .mat-radio-outer-circle{border-color:#8e3e52}.mat-radio-button.mat-warn .mat-radio-inner-circle,.mat-radio-button.mat-warn .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.mat-radio-button.mat-warn.mat-radio-checked .mat-radio-persistent-ripple,.mat-radio-button.mat-warn:active .mat-radio-persistent-ripple{background-color:#8e3e52}.mat-radio-button.mat-radio-disabled.mat-radio-checked .mat-radio-outer-circle,.mat-radio-button.mat-radio-disabled .mat-radio-outer-circle{border-color:rgba(0,0,0,0.38)}.mat-radio-button.mat-radio-disabled .mat-radio-ripple .mat-ripple-element,.mat-radio-button.mat-radio-disabled .mat-radio-inner-circle{background-color:rgba(0,0,0,0.38)}.mat-radio-button.mat-radio-disabled .mat-radio-label-content{color:rgba(0,0,0,0.38)}.mat-radio-button .mat-ripple-element{background-color:#000}.mat-select-value{color:rgba(0,0,0,0.87)}.mat-select-placeholder{color:rgba(0,0,0,0.42)}.mat-select-disabled .mat-select-value{color:rgba(0,0,0,0.38)}.mat-select-arrow{color:rgba(0,0,0,0.54)}.mat-select-panel{background:#fff}.mat-select-panel:not([class*='mat-elevation-z']){box-shadow:0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14),0px 1px 10px 0px rgba(0,0,0,0.12)}.mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple){background:rgba(0,0,0,0.12)}.mat-form-field.mat-focused.mat-primary .mat-select-arrow{color:#135f7f}.mat-form-field.mat-focused.mat-accent .mat-select-arrow{color:#006841}.mat-form-field.mat-focused.mat-warn .mat-select-arrow{color:#8e3e52}.mat-form-field .mat-select.mat-select-invalid .mat-select-arrow{color:#8e3e52}.mat-form-field .mat-select.mat-select-disabled .mat-select-arrow{color:rgba(0,0,0,0.38)}.mat-drawer-container{background-color:#fafafa;color:rgba(0,0,0,0.87)}.mat-drawer{background-color:#fff;color:rgba(0,0,0,0.87)}.mat-drawer.mat-drawer-push{background-color:#fff}.mat-drawer:not(.mat-drawer-side){box-shadow:0px 8px 10px -5px rgba(0,0,0,0.2),0px 16px 24px 2px rgba(0,0,0,0.14),0px 6px 30px 5px rgba(0,0,0,0.12)}.mat-drawer-side{border-right:solid 1px rgba(0,0,0,0.12)}.mat-drawer-side.mat-drawer-end{border-left:solid 1px rgba(0,0,0,0.12);border-right:none}[dir='rtl'] .mat-drawer-side{border-left:solid 1px rgba(0,0,0,0.12);border-right:none}[dir='rtl'] .mat-drawer-side.mat-drawer-end{border-left:none;border-right:solid 1px rgba(0,0,0,0.12)}.mat-drawer-backdrop.mat-drawer-shown{background-color:rgba(0,0,0,0.6)}.mat-slide-toggle.mat-checked .mat-slide-toggle-thumb{background-color:#006841}.mat-slide-toggle.mat-checked .mat-slide-toggle-bar{background-color:rgba(0,104,65,0.54)}.mat-slide-toggle.mat-checked .mat-ripple-element{background-color:#006841}.mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-thumb{background-color:#135f7f}.mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-bar{background-color:rgba(19,95,127,0.54)}.mat-slide-toggle.mat-primary.mat-checked .mat-ripple-element{background-color:#135f7f}.mat-slide-toggle.mat-warn.mat-checked .mat-slide-toggle-thumb{background-color:#8e3e52}.mat-slide-toggle.mat-warn.mat-checked .mat-slide-toggle-bar{background-color:rgba(142,62,82,0.54)}.mat-slide-toggle.mat-warn.mat-checked .mat-ripple-element{background-color:#8e3e52}.mat-slide-toggle:not(.mat-checked) .mat-ripple-element{background-color:#000}.mat-slide-toggle-thumb{box-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12);background-color:#fafafa}.mat-slide-toggle-bar{background-color:rgba(0,0,0,0.38)}.mat-slider-track-background{background-color:rgba(0,0,0,0.26)}.mat-primary .mat-slider-track-fill,.mat-primary .mat-slider-thumb,.mat-primary .mat-slider-thumb-label{background-color:#135f7f}.mat-primary .mat-slider-thumb-label-text{color:#fff}.mat-accent .mat-slider-track-fill,.mat-accent .mat-slider-thumb,.mat-accent .mat-slider-thumb-label{background-color:#006841}.mat-accent .mat-slider-thumb-label-text{color:#fff}.mat-warn .mat-slider-track-fill,.mat-warn .mat-slider-thumb,.mat-warn .mat-slider-thumb-label{background-color:#8e3e52}.mat-warn .mat-slider-thumb-label-text{color:#fff}.mat-slider-focus-ring{background-color:rgba(0,104,65,0.2)}.mat-slider:hover .mat-slider-track-background,.cdk-focused .mat-slider-track-background{background-color:rgba(0,0,0,0.38)}.mat-slider-disabled .mat-slider-track-background,.mat-slider-disabled .mat-slider-track-fill,.mat-slider-disabled .mat-slider-thumb{background-color:rgba(0,0,0,0.26)}.mat-slider-disabled:hover .mat-slider-track-background{background-color:rgba(0,0,0,0.26)}.mat-slider-min-value .mat-slider-focus-ring{background-color:rgba(0,0,0,0.12)}.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing .mat-slider-thumb-label{background-color:rgba(0,0,0,0.87)}.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb,.mat-slider-min-value.mat-slider-thumb-label-showing.cdk-focused .mat-slider-thumb-label{background-color:rgba(0,0,0,0.26)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing) .mat-slider-thumb{border-color:rgba(0,0,0,0.26);background-color:transparent}.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused .mat-slider-thumb{border-color:rgba(0,0,0,0.38)}.mat-slider-min-value:not(.mat-slider-thumb-label-showing):hover.mat-slider-disabled .mat-slider-thumb,.mat-slider-min-value:not(.mat-slider-thumb-label-showing).cdk-focused.mat-slider-disabled .mat-slider-thumb{border-color:rgba(0,0,0,0.26)}.mat-slider-has-ticks .mat-slider-wrapper::after{border-color:rgba(0,0,0,0.7)}.mat-slider-horizontal .mat-slider-ticks{background-image:repeating-linear-gradient(to right, rgba(0,0,0,0.7), rgba(0,0,0,0.7) 2px, transparent 0, transparent);background-image:-moz-repeating-linear-gradient(0.0001deg, rgba(0,0,0,0.7), rgba(0,0,0,0.7) 2px, transparent 0, transparent)}.mat-slider-vertical .mat-slider-ticks{background-image:repeating-linear-gradient(to bottom, rgba(0,0,0,0.7), rgba(0,0,0,0.7) 2px, transparent 0, transparent)}.mat-step-header.cdk-keyboard-focused,.mat-step-header.cdk-program-focused,.mat-step-header:hover{background-color:rgba(0,0,0,0.04)}@media (hover: none){.mat-step-header:hover{background:none}}.mat-step-header .mat-step-label,.mat-step-header .mat-step-optional{color:rgba(0,0,0,0.54)}.mat-step-header .mat-step-icon{background-color:rgba(0,0,0,0.54);color:#fff}.mat-step-header .mat-step-icon-selected,.mat-step-header .mat-step-icon-state-done,.mat-step-header .mat-step-icon-state-edit{background-color:#135f7f;color:#fff}.mat-step-header .mat-step-icon-state-error{background-color:transparent;color:#8e3e52}.mat-step-header .mat-step-label.mat-step-label-active{color:rgba(0,0,0,0.87)}.mat-step-header .mat-step-label.mat-step-label-error{color:#8e3e52}.mat-stepper-horizontal,.mat-stepper-vertical{background-color:#fff}.mat-stepper-vertical-line::before{border-left-color:rgba(0,0,0,0.12)}.mat-horizontal-stepper-header::before,.mat-horizontal-stepper-header::after,.mat-stepper-horizontal-line{border-top-color:rgba(0,0,0,0.12)}.mat-sort-header-arrow{color:#757575}.mat-tab-nav-bar,.mat-tab-header{border-bottom:1px solid rgba(0,0,0,0.12)}.mat-tab-group-inverted-header .mat-tab-nav-bar,.mat-tab-group-inverted-header .mat-tab-header{border-top:1px solid rgba(0,0,0,0.12);border-bottom:none}.mat-tab-label,.mat-tab-link{color:rgba(0,0,0,0.87)}.mat-tab-label.mat-tab-disabled,.mat-tab-link.mat-tab-disabled{color:rgba(0,0,0,0.38)}.mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,0.87)}.mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(0,0,0,0.38)}.mat-tab-group[class*='mat-background-'] .mat-tab-header,.mat-tab-nav-bar[class*='mat-background-']{border-bottom:none;border-top:none}.mat-tab-group.mat-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(26,128,171,0.3)}.mat-tab-group.mat-primary .mat-ink-bar,.mat-tab-nav-bar.mat-primary .mat-ink-bar{background-color:#135f7f}.mat-tab-group.mat-primary.mat-background-primary .mat-ink-bar,.mat-tab-nav-bar.mat-primary.mat-background-primary .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(0,155,97,0.3)}.mat-tab-group.mat-accent .mat-ink-bar,.mat-tab-nav-bar.mat-accent .mat-ink-bar{background-color:#006841}.mat-tab-group.mat-accent.mat-background-accent .mat-ink-bar,.mat-tab-nav-bar.mat-accent.mat-background-accent .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(178,78,103,0.3)}.mat-tab-group.mat-warn .mat-ink-bar,.mat-tab-nav-bar.mat-warn .mat-ink-bar{background-color:#8e3e52}.mat-tab-group.mat-warn.mat-background-warn .mat-ink-bar,.mat-tab-nav-bar.mat-warn.mat-background-warn .mat-ink-bar{background-color:#fff}.mat-tab-group.mat-background-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-primary .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(26,128,171,0.3)}.mat-tab-group.mat-background-primary .mat-tab-header,.mat-tab-group.mat-background-primary .mat-tab-links,.mat-tab-group.mat-background-primary .mat-tab-header-pagination,.mat-tab-nav-bar.mat-background-primary .mat-tab-header,.mat-tab-nav-bar.mat-background-primary .mat-tab-links,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination{background-color:#135f7f}.mat-tab-group.mat-background-primary .mat-tab-label,.mat-tab-group.mat-background-primary .mat-tab-link,.mat-tab-nav-bar.mat-background-primary .mat-tab-label,.mat-tab-nav-bar.mat-background-primary .mat-tab-link{color:#fff}.mat-tab-group.mat-background-primary .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-primary .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-primary .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-primary .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-primary .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-primary .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-primary .mat-ripple-element,.mat-tab-nav-bar.mat-background-primary .mat-ripple-element{background-color:rgba(255,255,255,0.12)}.mat-tab-group.mat-background-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-accent .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(0,155,97,0.3)}.mat-tab-group.mat-background-accent .mat-tab-header,.mat-tab-group.mat-background-accent .mat-tab-links,.mat-tab-group.mat-background-accent .mat-tab-header-pagination,.mat-tab-nav-bar.mat-background-accent .mat-tab-header,.mat-tab-nav-bar.mat-background-accent .mat-tab-links,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination{background-color:#006841}.mat-tab-group.mat-background-accent .mat-tab-label,.mat-tab-group.mat-background-accent .mat-tab-link,.mat-tab-nav-bar.mat-background-accent .mat-tab-label,.mat-tab-nav-bar.mat-background-accent .mat-tab-link{color:#fff}.mat-tab-group.mat-background-accent .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-accent .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-accent .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-accent .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-accent .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-accent .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-accent .mat-ripple-element,.mat-tab-nav-bar.mat-background-accent .mat-ripple-element{background-color:rgba(255,255,255,0.12)}.mat-tab-group.mat-background-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-group.mat-background-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-label.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-label.cdk-program-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-link.cdk-keyboard-focused:not(.mat-tab-disabled),.mat-tab-nav-bar.mat-background-warn .mat-tab-link.cdk-program-focused:not(.mat-tab-disabled){background-color:rgba(178,78,103,0.3)}.mat-tab-group.mat-background-warn .mat-tab-header,.mat-tab-group.mat-background-warn .mat-tab-links,.mat-tab-group.mat-background-warn .mat-tab-header-pagination,.mat-tab-nav-bar.mat-background-warn .mat-tab-header,.mat-tab-nav-bar.mat-background-warn .mat-tab-links,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination{background-color:#8e3e52}.mat-tab-group.mat-background-warn .mat-tab-label,.mat-tab-group.mat-background-warn .mat-tab-link,.mat-tab-nav-bar.mat-background-warn .mat-tab-label,.mat-tab-nav-bar.mat-background-warn .mat-tab-link{color:#fff}.mat-tab-group.mat-background-warn .mat-tab-label.mat-tab-disabled,.mat-tab-group.mat-background-warn .mat-tab-link.mat-tab-disabled,.mat-tab-nav-bar.mat-background-warn .mat-tab-label.mat-tab-disabled,.mat-tab-nav-bar.mat-background-warn .mat-tab-link.mat-tab-disabled{color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-warn .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-chevron{border-color:#fff}.mat-tab-group.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron,.mat-tab-nav-bar.mat-background-warn .mat-tab-header-pagination-disabled .mat-tab-header-pagination-chevron{border-color:rgba(255,255,255,0.4)}.mat-tab-group.mat-background-warn .mat-ripple-element,.mat-tab-nav-bar.mat-background-warn .mat-ripple-element{background-color:rgba(255,255,255,0.12)}.mat-toolbar{background:#f5f5f5;color:rgba(0,0,0,0.87)}.mat-toolbar.mat-primary{background:#135f7f;color:#fff}.mat-toolbar.mat-accent{background:#006841;color:#fff}.mat-toolbar.mat-warn{background:#8e3e52;color:#fff}.mat-toolbar .mat-form-field-underline,.mat-toolbar .mat-form-field-ripple,.mat-toolbar .mat-focused .mat-form-field-ripple{background-color:currentColor}.mat-toolbar .mat-form-field-label,.mat-toolbar .mat-focused .mat-form-field-label,.mat-toolbar .mat-select-value,.mat-toolbar .mat-select-arrow,.mat-toolbar .mat-form-field.mat-focused .mat-select-arrow{color:inherit}.mat-toolbar .mat-input-element{caret-color:currentColor}.mat-tooltip{background:rgba(97,97,97,0.9)}.mat-tree{background:#fff}.mat-tree-node,.mat-nested-tree-node{color:rgba(0,0,0,0.87)}.mat-snack-bar-container{color:rgba(255,255,255,0.7);background:#323232;box-shadow:0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12)}.mat-simple-snackbar-action{color:#006841}[color=primary]{color:#135f7f}[color=secondary]{color:#F99830}[color=warn]{color:#8e3e52}[color=accent]{color:#006841}[bgcolor=primary]{background-color:#135f7f}[bgcolor=warn]{background-color:#8e3e52}[bgcolor=accent]{background-color:#006841}.jstree-proton .jstree-clicked{background:#1a80ab !important}.jstree-proton :not(.jstree-disabled).jstree-hovered{background:#1a80ab !important;box-shadow:inset 0 0 1px #135f7f !important}.jstree-proton .jstree-disabled:hover{cursor:not-allowed}.dndFile{border:dashed 5px grey;padding:10px;text-align:center;opacity:0.5;font-size:15px;font-weight:bolder;margin:20px}.dndFileHighlighted{opacity:1 !important;border:dashed 5px #135f7f !important;color:#135f7f}.cdk-textarea-autosize{min-height:18px !important} diff --git a/src/frontend/plugins/onlyoffice-api-js/onlyoffice-viewer.component.ts b/src/frontend/plugins/onlyoffice-api-js/onlyoffice-viewer.component.ts index 71fe10e15f75bdc13d3bd507eb79b83b67bea554..68812944551b638e600395119733270e851d8647 100644 --- a/src/frontend/plugins/onlyoffice-api-js/onlyoffice-viewer.component.ts +++ b/src/frontend/plugins/onlyoffice-api-js/onlyoffice-viewer.component.ts @@ -13,8 +13,9 @@ import { Subject, of } from 'rxjs'; import { catchError, tap, filter } from 'rxjs/operators'; import { LANG } from '../../app/translate.component'; import { ConfirmComponent } from '../modal/confirm.component'; -import { MatDialogRef, MatDialog, MatSidenav } from '@angular/material'; +import { MatDialogRef, MatDialog } from '@angular/material'; import { NotificationService } from '../../app/notification.service'; +import { HeaderService } from '../../service/header.service.js'; declare var DocsAPI: any; declare function $j(selector: any): any; @@ -34,8 +35,6 @@ export class EcplOnlyofficeViewerComponent implements OnInit, AfterViewInit { @Input() file: any = {}; @Input() params: any = {}; - @Input() sidenavLeft: MatSidenav = null; - @Output() triggerAfterUpdatedDoc = new EventEmitter<string>(); @Output() triggerCloseEditor = new EventEmitter<string>(); @Output() triggerModifiedDocument = new EventEmitter<string>(); @@ -80,7 +79,7 @@ export class EcplOnlyofficeViewerComponent implements OnInit, AfterViewInit { } } - constructor(public http: HttpClient, public dialog: MatDialog, private notify: NotificationService) { } + constructor(public http: HttpClient, public dialog: MatDialog, private notify: NotificationService, public headerService: HeaderService) { } quit() { this.dialogRef = this.dialog.open(ConfirmComponent, { panelClass: 'maarch-modal', autoFocus: false, disableClose: true, data: { title: this.lang.close, msg: this.lang.confirmCloseEditor } }); @@ -95,10 +94,8 @@ export class EcplOnlyofficeViewerComponent implements OnInit, AfterViewInit { } closeEditor() { - console.log('close'); - - if (this.sidenavLeft !== null) { - this.sidenavLeft.open(); + if (this.headerService.sideNavLeft !== null) { + this.headerService.sideNavLeft.open(); } $j("iframe[name='frameEditor']").css("position", "initial"); this.fullscreenMode = false; @@ -313,13 +310,13 @@ export class EcplOnlyofficeViewerComponent implements OnInit, AfterViewInit { $j("iframe[name='frameEditor']").css("left", "0px"); if (!this.fullscreenMode) { - if (this.sidenavLeft !== null) { - this.sidenavLeft.close(); + if (this.headerService.sideNavLeft !== null) { + this.headerService.sideNavLeft.close(); } $j("iframe[name='frameEditor']").css("position", "fixed"); } else { - if (this.sidenavLeft !== null) { - this.sidenavLeft.open(); + if (this.headerService.sideNavLeft !== null) { + this.headerService.sideNavLeft.open(); } $j("iframe[name='frameEditor']").css("position", "initial"); } diff --git a/src/frontend/service/app.guard.ts b/src/frontend/service/app.guard.ts index 0788ba0fb2c0f122f9a49ced7547f5c0eafe96da..62aabb6e73683a4598f63cbf1490e52aa7a4ea84 100644 --- a/src/frontend/service/app.guard.ts +++ b/src/frontend/service/app.guard.ts @@ -21,13 +21,11 @@ export class AppGuard implements CanActivate { canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean { // TO DO : CAN BE REMOVE AFTER FULL V2 localStorage.setItem('PreviousV2Route', state.url); - - if (route.url.filter((url: any) => url == 'administration').length > 0) { - this.headerService.hideSideBar = true; - //this.headerService.sideNavLeft.close(); + this.headerService.resetSideNavSelection(); + if (route.url.filter((url: any) => url == 'administration').length > 0) { + this.headerService.sideBarAdmin = true; } else { - this.headerService.hideSideBar = false; - this.headerService.resetSideNavSelection(); + this.headerService.sideBarAdmin = false; } if (this.headerService.user.id === undefined) { diff --git a/src/frontend/service/header.service.ts b/src/frontend/service/header.service.ts index 190aa5b78ecb00c26a886fe98b7be1b805c5f0a0..35353d5c345e3f2a11afefb641fb11c9458ff988 100755 --- a/src/frontend/service/header.service.ts +++ b/src/frontend/service/header.service.ts @@ -1,16 +1,24 @@ -import { Injectable } from '@angular/core'; +import { Injectable, ComponentFactoryResolver, Injector, ApplicationRef, ViewContainerRef, TemplateRef } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { LANG } from '../app/translate.component'; import { tap, catchError, map } from 'rxjs/operators'; import { of } from 'rxjs'; import { MatSidenav } from '@angular/material'; import { FoldersService } from '../app/folder/folders.service'; +import { DomPortalHost, TemplatePortal } from '@angular/cdk/portal'; @Injectable() export class HeaderService { - hideSideBar: boolean = false; + sideBarForm: boolean = false; + sideBarAdmin: boolean = false; + + showhHeaderPanel: boolean = true; + showMenuShortcut: boolean = true; + showMenuNav: boolean = true; + sideNavLeft: MatSidenav = null; - defaultSideNavLeft: MatSidenav = null; + sideBarButton: any = null; + currentBasketInfo: any = { ownerId: 0, groupId: 0, @@ -25,9 +33,14 @@ export class HeaderService { nbResourcesFollowed: number = 0; base64: string = null; + private portalHost: DomPortalHost; + constructor( public http: HttpClient, public foldersService: FoldersService, + private componentFactoryResolver: ComponentFactoryResolver, + private injector: Injector, + private appRef: ApplicationRef, ) { } loadHeader() { @@ -89,16 +102,51 @@ export class HeaderService { } resetSideNavSelection() { - if (this.defaultSideNavLeft !== undefined) { - this.sideNavLeft = this.defaultSideNavLeft; - this.sideNavLeft.open(); this.currentBasketInfo = { ownerId: 0, groupId: 0, basketId: '' }; this.foldersService.setFolder({ id: 0 }); - } + this.sideBarForm = false; + this.showhHeaderPanel = true; + this.showMenuShortcut = true; + this.showMenuNav = true; + this.sideBarAdmin = false; + this.sideBarButton = null; + } + + injectInSideBarLeft(template: TemplateRef<any>, viewContainerRef: ViewContainerRef, id: string = 'adminMenu', mode: string = '') { + + if (mode === 'form') { + this.sideBarForm = true; + this.showhHeaderPanel = true; + this.showMenuShortcut = false; + this.showMenuNav = false; + this.sideBarAdmin = true; + } else { + this.showhHeaderPanel = true; + this.showMenuShortcut = true; + this.showMenuNav = true; + } + + // Create a portalHost from a DOM element + this.portalHost = new DomPortalHost( + document.querySelector(`#${id}`), + this.componentFactoryResolver, + this.appRef, + this.injector + ); + + // Create a template portal + const templatePortal = new TemplatePortal( + template, + viewContainerRef, + { $implicit: 'Bob' }, + ); + + // Attach portal to host + this.portalHost.attach(templatePortal); } }