From bab46d80592c22753274d9f5eb3563bd962f4cc3 Mon Sep 17 00:00:00 2001 From: descamps <descamps@cines.fr> Date: Tue, 15 Jun 2021 16:04:27 +0200 Subject: [PATCH] =?UTF-8?q?KDE=20-=2015/06/2021=20-=20Ajout=20directive=20?= =?UTF-8?q?pour=20centrer=20menu=20item=20=C3=A0=20partir=20du=20bouton?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../center-matmenu.directive.spec.ts | 10 ++ .../center-matmenu.directive.ts | 111 ++++++++++++++++++ .../file-tree-metadata.component.html | 31 ++--- .../pastis/src/app/shared/shared.module.ts | 31 ++--- 4 files changed, 155 insertions(+), 28 deletions(-) create mode 100644 ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/center-matmenu.directive.spec.ts create mode 100644 ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/center-matmenu.directive.ts diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/center-matmenu.directive.spec.ts b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/center-matmenu.directive.spec.ts new file mode 100644 index 000000000..6445ba9eb --- /dev/null +++ b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/center-matmenu.directive.spec.ts @@ -0,0 +1,10 @@ +import { CenterMatmenuDirective } from './center-matmenu.directive'; + +describe('CenterMatmenuDirective', () => { + it('should create an instance', () => { + let directive: CenterMatmenuDirective; + // @ts-ignore + directive = new CenterMatmenuDirective(); + expect(directive).toBeTruthy(); + }); +}); diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/center-matmenu.directive.ts b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/center-matmenu.directive.ts new file mode 100644 index 000000000..57d6e5452 --- /dev/null +++ b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/center-matmenu.directive.ts @@ -0,0 +1,111 @@ +import {Directive, ElementRef, HostListener, Input, Renderer2} from '@angular/core'; +import {FlexibleConnectedPositionStrategy, OverlayConfig, OverlayRef} from '@angular/cdk/overlay' +import {MatMenuPanel, MatMenuTrigger} from "@angular/material/menu"; + +@Directive({ + selector: '[center-mat-menu]' +}) +export class CenterMatmenuDirective { + overlayRef: OverlayRef; + overlayConf: OverlayConfig; + dropDown: HTMLElement; + overlayPositionBox: HTMLElement; + menu: MatMenuPanel; + button: HTMLElement; + buttonWidth: number; + buttonLeft: number; + buttonBottom: number; + arrowDiv: HTMLDivElement; + + @Input('center-mat-menu') private menuTrigger: MatMenuTrigger; + + constructor(private _menuButton: ElementRef, private _renderer: Renderer2) { + } + + + + @HostListener('click', ['$event']) + // @ts-ignore + onclick(e) { + console.log("cliquer ?") + this._setVariables(); + //menu not opened by keyboard down arrow, have to set this so MatMenuTrigger knows the menu was opened with a mouse click + this.menuTrigger['_openedBy'] = e.button === 0 ? 'mouse' : null; + + this._overrideMatMenu(); + + this.dropDown = this.overlayRef.overlayElement.children[0].children[0] as HTMLElement; + this.overlayPositionBox = this.overlayRef.hostElement; + + setTimeout(() => { + this._styleDropDown(this.dropDown); + this._setOverlayPosition(this.dropDown, this.overlayPositionBox); + this._openMenu(); + }) + } + + private _setVariables() { + const config = this.menuTrigger['_getOverlayConfig'](); + this.menuTrigger['_overlayRef'] = this.menuTrigger['_overlay'].create(config); + this.overlayRef = this.menuTrigger['_overlayRef']; + this.overlayConf = this.overlayRef.getConfig(); + this.overlayRef.keydownEvents().subscribe(); + this.menu = this.menuTrigger.menu; + this._setButtonVars(); + } + + private _setButtonVars() { + this.button = this._menuButton.nativeElement; + this.buttonWidth = this.button.getBoundingClientRect().width; + this.buttonLeft = this.button.getBoundingClientRect().left; + this.buttonBottom = this.button.getBoundingClientRect().bottom; + } + + private _overrideMatMenu() { + console.log(this.overlayConf) + let strat = this.overlayConf.positionStrategy as FlexibleConnectedPositionStrategy; + this.menuTrigger['_setPosition'](strat); + strat.positionChanges.subscribe(() => { + this._setButtonVars(); + this._setOverlayPosition(this.dropDown, this.overlayPositionBox); + }) + this.overlayConf.hasBackdrop = this.menu.hasBackdrop == null ? + !this.menuTrigger.triggersSubmenu() : this.menu.hasBackdrop; + this.overlayRef.attach(this.menuTrigger['_getPortal']()); + + if (this.menu.lazyContent) { + this.menu.lazyContent.attach() + } + + // @ts-ignore + this.menuTrigger['_closeSubscription'] = this.menuTrigger['_menuClosingActions']().subscribe(() => { + this.menuTrigger.closeMenu(); + setTimeout(() => { + this._renderer.removeChild(this.button, this.arrowDiv); + }, 75) + + }); + this.menuTrigger['_initMenu'](); + } + + private _styleDropDown(dropDown: HTMLElement) { + this.arrowDiv = this._renderer.createElement('div'); + this._renderer.addClass(this.arrowDiv, 'dialog-arrow'); + this._renderer.appendChild(this.button, this.arrowDiv); + this._renderer.setStyle(this.arrowDiv, 'left', (this.buttonWidth / 2) - 10 + 'px') + this._renderer.setStyle(this._renderer.parentNode(dropDown), 'transform-origin', 'center top 0px'); + } + + private _setOverlayPosition(dropDown: HTMLElement, overlayPositionBox: HTMLElement) { + let dropDownleft = ((this.buttonWidth / 2 + this.buttonLeft) - dropDown.offsetWidth / 2); + + this._renderer.setStyle(overlayPositionBox, 'top', this.buttonBottom + 1 + 'px'); + this._renderer.setStyle(overlayPositionBox, 'left', dropDownleft + 'px'); + this._renderer.setStyle(overlayPositionBox, 'height', '100%'); + } + + private _openMenu() { + // @ts-ignore + this.menuTrigger.menu['_startAnimation'](); + } +} diff --git a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.html b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.html index b80937ed9..6c547a3c6 100644 --- a/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.html +++ b/ui/ui-frontend/projects/pastis/src/app/profile/edit-profile/file-tree-metadata/file-tree-metadata.component.html @@ -149,8 +149,22 @@ <ng-container matColumnDef="menuoption"> <th mat-header-cell *matHeaderCellDef class="pastis-font-table-header pastis-col"></th> <td mat-cell *matCellDef="let element;index as i" class="pastis-metadata-table-col-small"> - <mat-menu #menu="matMenu" [overlapTrigger]="false" class="pastis-menu-item-vitam" - yPosition="below"> + <button id="menuBtn" *ngIf="isRowHovered(element.id)" mat-icon-button [center-mat-menu]="menuTrigger" + (click)="onButtonClicked(element.id,$event)" disableRipple="true" + [ngClass]="{'pastis-btn-metadata-options-active': isButtonClicked(element.id,matDataSource.data[rowIndex]), + 'pastis-btn-metadata-options': !isButtonClicked(element.id,matDataSource.data[rowIndex]) }"> + <mat-icon + [ngClass]="{'pastis-ico-menu-active': isButtonClicked(element.id,matDataSource.data[rowIndex]), + 'pastis-ico-menu-inactive': !isButtonClicked(element.id,matDataSource.data[rowIndex])}"> + {{isButtonClicked(element.id, matDataSource.data[rowIndex]) ? 'close' : 'more_horiz'}} + </mat-icon> + </button> + + <div #menuTrigger="matMenuTrigger" [matMenuTriggerFor]="menu" (menuOpened)="rowIndex = i" + (menuClosed)="rowIndex = 100"> + + + <mat-menu #menu="matMenu" [overlapTrigger]="false" class="pastis-menu-item-vitam"> <!-- Dupliquer--> <button mat-menu-item> <mat-icon style="color:#757575">filter_none</mat-icon> @@ -175,18 +189,7 @@ <span class="text normal">Supprimer</span> </button> </mat-menu> - <button id="menuBtn" *ngIf="isRowHovered(element.id)" mat-icon-button [matMenuTriggerFor]="menu" - (click)="onButtonClicked(element.id,$event)" disableRipple="true" (menuOpened)="rowIndex = i" - (menuClosed)="rowIndex = 100" - [ngClass]="{'pastis-btn-metadata-options-active': isButtonClicked(element.id,matDataSource.data[rowIndex]), - 'pastis-btn-metadata-options': !isButtonClicked(element.id,matDataSource.data[rowIndex]) }"> - <mat-icon - [ngClass]="{'pastis-ico-menu-active': isButtonClicked(element.id,matDataSource.data[rowIndex]), - 'pastis-ico-menu-inactive': !isButtonClicked(element.id,matDataSource.data[rowIndex])}"> - {{isButtonClicked(element.id, matDataSource.data[rowIndex]) ? 'close' : 'more_horiz'}} - </mat-icon> - </button> - + </div> </td> </ng-container> diff --git a/ui/ui-frontend/projects/pastis/src/app/shared/shared.module.ts b/ui/ui-frontend/projects/pastis/src/app/shared/shared.module.ts index b76852e3d..615b7722c 100644 --- a/ui/ui-frontend/projects/pastis/src/app/shared/shared.module.ts +++ b/ui/ui-frontend/projects/pastis/src/app/shared/shared.module.ts @@ -1,25 +1,25 @@ /* -Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020) +Copyright © CINES - Centre Informatique National pour l'Enseignement Supérieur (2020) [dad@cines.fr] -This software is a computer program whose purpose is to provide -a web application to create, edit, import and export archive +This software is a computer program whose purpose is to provide +a web application to create, edit, import and export archive profiles based on the french SEDA standard (https://redirect.francearchives.fr/seda/). This software is governed by the CeCILL-C license under French law and -abiding by the rules of distribution of free software. You can use, +abiding by the rules of distribution of free software. You can use, modify and/ or redistribute the software under the terms of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following URL -"http://www.cecill.info". +"http://www.cecill.info". As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors have only limited -liability. +liability. In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or reproducing the @@ -28,9 +28,9 @@ that may mean that it is complicated to manipulate, and that also therefore means that it is reserved for developers and experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the software's suitability as regards their -requirements in conditions enabling the security of their systems and/or -data to be ensured and, more generally, to use and operate it in the -same conditions as regards security. +requirements in conditions enabling the security of their systems and/or +data to be ensured and, more generally, to use and operate it in the +same conditions as regards security. The fact that you are presently reading this means that you have had knowledge of the CeCILL-C license and that you accept its terms. @@ -48,6 +48,7 @@ import { PastisToggleButtonComponent } from './pastis-toggle-button/pastis-toggl import { PastisNoticeToggleButtonComponent } from './pastis-notice-toggle-button/pastis-notice-toggle-button.component'; import {MatSlideToggleModule} from '@angular/material/slide-toggle'; import { PortalModule } from '@angular/cdk/portal'; +import {CenterMatmenuDirective} from "../profile/edit-profile/file-tree-metadata/center-matmenu.directive"; @NgModule({ declarations: [ @@ -55,9 +56,10 @@ import { PortalModule } from '@angular/cdk/portal'; PastisUnderConstructionComponent, PastisToggleButtonComponent, PastisNoticeToggleButtonComponent, - PastisDialogConfirmComponent - - + PastisDialogConfirmComponent, + CenterMatmenuDirective + + ], imports: [CommonModule, FormsModule, @@ -65,7 +67,7 @@ import { PortalModule } from '@angular/cdk/portal'; PastisMaterialModule, MatSlideToggleModule, PortalModule - + ], entryComponents: [PastisDialogConfirmComponent, PastisUnderConstructionComponent], @@ -76,7 +78,8 @@ import { PortalModule } from '@angular/cdk/portal'; PastisMaterialModule, PastisToggleButtonComponent, PastisNoticeToggleButtonComponent, - PastisDialogConfirmComponent + PastisDialogConfirmComponent, + CenterMatmenuDirective ], }) export class SharedModule {} -- GitLab