Commit 35d35558 authored by PECQUOT's avatar PECQUOT

[enh] move column selection popup in actions column header

[fix] mix resizable behavior with draggable column
[enh] double-click on column resizer fit the width
parent b28eda9a
......@@ -16,8 +16,6 @@ const routes: Routes = [
children: [
{
path: 'SamplingEquipment',
// component: SamplingEquipmentTable,
// canDeactivate: [ComponentDirtyGuard],
loadChildren: () => import('./sampling-equipment/sampling-equipment.module').then(m => m.SamplingEquipmentModule)
},
{
......
......@@ -3,7 +3,6 @@ import {TranslateModule} from "@ngx-translate/core";
import {RouterModule, Routes} from "@angular/router";
import {SamplingEquipmentTable} from "@app/referential/sampling-equipment/sampling-equipment.table";
import {ComponentDirtyGuard} from "@app/shared/table/component-dirty.guard";
import {QuadrigeSharedModule} from "@app/shared/quadrige.shared.module";
import {QuadrigeCoreModule} from "@app/core/quadrige.core.module";
const routes: Routes = [
......
.mat-expansion-panel {
margin-bottom: 5px;
.form-container {
mat-form-field {
width: 100%;
.datetime-md {
padding: 0 !important;
}
}
}
mat-action-row {
ion-label {
line-height: 36px;
}
}
}
.mat-table {
.mat-column-size {
......
......@@ -57,16 +57,19 @@ export class SamplingEquipmentTable extends ReferentialTable<SamplingEquipment,
ngOnInit() {
super.ngOnInit();
this.searchFields = ['REFERENTIAL.ID', 'REFERENTIAL.NAME'].map(value => this.translate.instant(value)).join(', ');
// Unit combo
const unitAttributes = ['name', 'label'];
const unitAttributes = ['name', 'label', 'id'];
this.registerAutocompleteField('unit', {
service: this.referentialService,
attributes: unitAttributes,
columnNames: ['REFERENTIAL.NAME', 'REFERENTIAL.UNIT.SYMBOL'],
columnNames: ['REFERENTIAL.NAME', 'REFERENTIAL.UNIT.SYMBOL', 'REFERENTIAL.ID'],
columnSizes: unitAttributes.map(attr => {
switch (attr) {
case 'name': return 8;
case 'label': return 4;
case 'label': return 3;
case 'id': return 1;
default: return undefined;
}
}),
......@@ -82,8 +85,4 @@ export class SamplingEquipmentTable extends ReferentialTable<SamplingEquipment,
this.submitFilter();
}
drop(event: CdkDragDrop<string[]>) {
const offset = RESERVED_START_COLUMNS.length;
moveItemInArray(this.columns, event.previousIndex + offset, event.currentIndex + offset);
}
}
......@@ -11,7 +11,7 @@
<button mat-icon-button class="hidden-xs hidden-sm hidden-mobile"
*ngIf="canEdit"
[title]="'COMMON.BTN_ADD'|translate"
(click)="addRow()" >
(click)="addRow()">
<mat-icon>add</mat-icon>
</button>
<button mat-icon-button color="light" [title]="'COMMON.BTN_REFRESH'|translate"
......@@ -34,22 +34,17 @@
<button mat-icon-button
class="hidden-xs hidden-sm"
*ngIf="canEdit" [title]="'COMMON.BTN_DELETE'|translate"
(click)="deleteSelection($event)" >
(click)="deleteSelection($event)">
<mat-icon>delete</mat-icon>
</button>
</ng-template>
<div class="toolbar-spacer"></div>
<button mat-icon-button [title]=" 'COMMON.DISPLAYED_COLUMNS'|translate" (click)="openSelectColumnsModal($event)">
<mat-icon>more_vert</mat-icon>
</button>
</mat-toolbar-row>
</mat-toolbar>
<!-- search -->
<mat-expansion-panel #filterExpansionPanel class="ion-no-padding">
<mat-expansion-panel #filterExpansionPanel class="ion-no-padding filter-panel">
<form class="form-container ion-padding-top" [formGroup]="filterForm" (ngSubmit)="submitFilter()">
<ion-grid>
......@@ -73,7 +68,7 @@
<ion-col size="2">
<!-- status -->
<mat-form-field>
<mat-select formControlName="statusId" [placeholder]="'REFERENTIAL.STATUS'|translate" >
<mat-select formControlName="statusId" [placeholder]="'REFERENTIAL.STATUS'|translate">
<mat-option [value]="null"><i><span translate>COMMON.EMPTY_OPTION</span></i></mat-option>
<mat-option *ngFor="let item of statusList" [value]="item.id">
<ion-icon [name]="item.icon"></ion-icon>
......@@ -97,8 +92,7 @@
<!-- Counter -->
<ion-label [hidden]="(loadingSubject|async) || filterForm.dirty" [color]="resultsLength === 0 && 'danger'"
class="ion-padding">
{{ (resultsLength ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT') | translate: {count: (resultsLength |
numberFormat)} }}
{{ (resultsLength ? 'COMMON.RESULT_COUNT' : 'COMMON.NO_RESULT') | translate: {count: (resultsLength | numberFormat)} }}
</ion-label>
<div class="toolbar-spacer"></div>
......@@ -119,179 +113,184 @@
<ion-label color="danger" class="error" [innerHTML]="error|translate"></ion-label>
</ion-item>
<mat-table #table [dataSource]="dataSource" class="trips-table" matSort matSortActive="id" matSortDirection="asc"
matSortDisableClear [trackBy]="trackByFn">
<ng-container matColumnDef="select">
<mat-header-cell class="hidden-xs hidden-sm" *matHeaderCellDef [class.cdk-visually-hidden]="!canEdit">
<mat-checkbox (change)="$event ? masterToggle() : null" [checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()">
</mat-checkbox>
</mat-header-cell>
<mat-cell class="hidden-xs hidden-sm" *matCellDef="let row" [class.cdk-visually-hidden]="!canEdit">
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? selection.toggle(row) : null" [checked]="selection.isSelected(row)">
</mat-checkbox>
</mat-cell>
</ng-container>
<!-- Id/code column -->
<ng-container matColumnDef="id">
<mat-header-cell class="hidden-xs hidden-sm" *matHeaderCellDef mat-sort-header>
<app-loading-spinner [loading]="loadingSubject|async">
<ion-label translate>{{idLabel$|async}}</ion-label>
</app-loading-spinner>
</mat-header-cell>
<mat-cell class="hidden-xs hidden-sm" *matCellDef="let row">
<mat-form-field *ngIf="idEditable; else readOnlyId" floatLabel="never">
<input matInput [formControl]="row.validator.controls['id']" [placeholder]="idLabel$|async|translate"
[appAutofocus]="row.id == -1 && row.editing"
[readonly]="!row.editing">
<mat-error *ngIf="row.validator.controls['id'].hasError('required')" translate>ERROR.FIELD_REQUIRED</mat-error>
</mat-form-field>
<ng-template #readOnlyId>
<ion-label>{{ row.currentData?.id }}</ion-label>
</ng-template>
</mat-cell>
</ng-container>
<!-- Name column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header>
<span translate>REFERENTIAL.NAME</span>
</mat-header-cell>
<mat-cell *matCellDef="let row" [class.mat-form-field-disabled]="!row.editing">
<mat-form-field floatLabel="never">
<input matInput [formControl]="row.validator.controls['name']" [placeholder]="'REFERENTIAL.NAME'|translate"
[appAutofocus]="row.id == -1 && row.editing"
[readonly]="!row.editing">
<mat-error *ngIf="row.validator.controls['name'].hasError('required')" translate>ERROR.FIELD_REQUIRED</mat-error>
</mat-form-field>
</mat-cell>
</ng-container>
<!-- Label column -->
<ng-container matColumnDef="label">
<mat-header-cell *matHeaderCellDef mat-sort-header>
<span translate>REFERENTIAL.LABEL</span>
</mat-header-cell>
<mat-cell *matCellDef="let row">
<mat-form-field floatLabel="never">
<input matInput [formControl]="row.validator.controls['label']" [placeholder]="'REFERENTIAL.LABEL'|translate"
[readonly]="!row.editing">
<mat-error *ngIf="row.validator.controls['label'].hasError('required')" translate>ERROR.FIELD_REQUIRED</mat-error>
</mat-form-field>
</mat-cell>
</ng-container>
<!-- Description column -->
<ng-container matColumnDef="description">
<mat-header-cell *matHeaderCellDef mat-sort-header>
<span translate>REFERENTIAL.DESCRIPTION</span>
</mat-header-cell>
<mat-cell *matCellDef="let row">
<mat-form-field floatLabel="never">
<input matInput [formControl]="row.validator.controls['description']" [placeholder]="'REFERENTIAL.DESCRIPTION'|translate"
[readonly]="!row.editing">
<mat-error *ngIf="row.validator.controls['description'].hasError('required')" translate>ERROR.FIELD_REQUIRED</mat-error>
</mat-form-field>
</mat-cell>
</ng-container>
<!-- Comment column -->
<ng-container matColumnDef="comments">
<mat-header-cell *matHeaderCellDef class="hidden-xs hidden-sm">
<span translate>REFERENTIAL.COMMENTS</span>
</mat-header-cell>
<mat-cell *matCellDef="let row" class="hidden-xs hidden-sm" >
<button mat-icon-button
(click)="openCommentModal($event, row)"
[title]="row.validator.controls.comments.value != null ? row.validator.controls.comments.value : ''">
<ion-icon [color]="row.validator.controls.comments.value ? 'tertiary' : 'medium'" name="chatbox" slot="icon-only"></ion-icon>
</button>
</mat-cell>
</ng-container>
<!-- Status column -->
<ng-container matColumnDef="status">
<mat-header-cell *matHeaderCellDef mat-sort-header>
<span translate>REFERENTIAL.STATUS</span>
</mat-header-cell>
<mat-cell *matCellDef="let row" [class.mat-form-field-disabled]="!row.editing">
<mat-form-field floatLabel="never">
<ion-icon matPrefix *ngIf="row.validator.controls.statusId.value >= 0" [name]="statusById[row.validator.controls.statusId.value]?.icon"></ion-icon>
<mat-select [formControl]="row.validator.controls.statusId" [placeholder]="'REFERENTIAL.STATUS'|translate">
<mat-select-trigger>
<div class="table-container">
<table mat-table #table [dataSource]="dataSource"
matSort matSortActive="id" matSortDirection="asc" matSortDisableClear [trackBy]="trackByFn"
cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="drop($event)"
>
<ng-container matColumnDef="select" [sticky]="canEdit">
<th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]="!canEdit">
<mat-checkbox (change)="$event ? masterToggle() : null" [checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row" [class.cdk-visually-hidden]="!canEdit">
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? selection.toggle(row) : null" [checked]="selection.isSelected(row)">
</mat-checkbox>
</td>
</ng-container>
<!-- Id/code column -->
<ng-container matColumnDef="id" sticky>
<th mat-header-cell *matHeaderCellDef>
<app-loading-spinner [loading]="loadingSubject|async">
<span mat-sort-header><ion-label translate>{{idLabel$|async}}</ion-label></span>
</app-loading-spinner>
</th>
<td mat-cell *matCellDef="let row">
<mat-form-field *ngIf="idEditable; else readOnlyId" floatLabel="never">
<input matInput [formControl]="row.validator.controls['id']" [placeholder]="idLabel$|async|translate"
[appAutofocus]="row.id == -1 && row.editing"
[readonly]="!row.editing">
<mat-error *ngIf="row.validator.controls['id'].hasError('required')" translate>ERROR.FIELD_REQUIRED</mat-error>
</mat-form-field>
<ng-template #readOnlyId>
<ion-label>{{ row.currentData?.id }}</ion-label>
</ng-template>
</td>
</ng-container>
<!-- Name column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef cdkDrag resizable>
<span mat-sort-header><ion-label translate>REFERENTIAL.NAME</ion-label></span>
</th>
<td mat-cell *matCellDef="let row" [class.mat-form-field-disabled]="!row.editing">
<mat-form-field floatLabel="never">
<input matInput [formControl]="row.validator.controls['name']" [placeholder]="'REFERENTIAL.NAME'|translate"
[appAutofocus]="row.id == -1 && row.editing"
[readonly]="!row.editing">
<mat-error *ngIf="row.validator.controls['name'].hasError('required')" translate>ERROR.FIELD_REQUIRED</mat-error>
</mat-form-field>
</td>
</ng-container>
<!-- Label column -->
<ng-container matColumnDef="label">
<th mat-header-cell *matHeaderCellDef cdkDrag resizable>
<span mat-sort-header><ion-label translate>REFERENTIAL.LABEL</ion-label></span>
</th>
<td mat-cell *matCellDef="let row">
<mat-form-field floatLabel="never">
<input matInput [formControl]="row.validator.controls['label']" [placeholder]="'REFERENTIAL.LABEL'|translate"
[readonly]="!row.editing">
<mat-error *ngIf="row.validator.controls['label'].hasError('required')" translate>ERROR.FIELD_REQUIRED</mat-error>
</mat-form-field>
</td>
</ng-container>
<!-- Description column -->
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef cdkDrag resizable>
<span mat-sort-header><ion-label translate>REFERENTIAL.DESCRIPTION</ion-label></span>
</th>
<td mat-cell *matCellDef="let row">
<mat-form-field floatLabel="never">
<input matInput [formControl]="row.validator.controls['description']" [placeholder]="'REFERENTIAL.DESCRIPTION'|translate"
[readonly]="!row.editing">
<mat-error *ngIf="row.validator.controls['description'].hasError('required')" translate>ERROR.FIELD_REQUIRED</mat-error>
</mat-form-field>
</td>
</ng-container>
<!-- Comment column -->
<ng-container matColumnDef="comments">
<th mat-header-cell *matHeaderCellDef cdkDrag>
<span><ion-label translate>REFERENTIAL.COMMENTS</ion-label></span>
</th>
<td mat-cell *matCellDef="let row">
<button mat-icon-button
(click)="openCommentModal($event, row)"
[title]="row.validator.controls.comments.value != null ? row.validator.controls.comments.value : ''">
<ion-icon [color]="row.validator.controls.comments.value ? 'tertiary' : 'medium'" name="chatbox" slot="icon-only"></ion-icon>
</button>
</td>
</ng-container>
<!-- Status column -->
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef cdkDrag>
<span mat-sort-header><ion-label translate>REFERENTIAL.STATUS</ion-label></span>
</th>
<td mat-cell *matCellDef="let row" [class.mat-form-field-disabled]="!row.editing">
<mat-form-field floatLabel="never">
<ion-icon matPrefix *ngIf="row.validator.controls.statusId.value >= 0" [name]="statusById[row.validator.controls.statusId.value]?.icon"></ion-icon>
<mat-select [formControl]="row.validator.controls.statusId" [placeholder]="'REFERENTIAL.STATUS'|translate">
<mat-select-trigger>
<span *ngIf="row.validator.controls.statusId.value >= 0">
{{ statusById[row.validator.controls.statusId.value]?.label | translate}}</span>
</mat-select-trigger>
<mat-option *ngFor="let item of statusList" [value]="item.id">
<ion-icon [name]="item.icon"></ion-icon>
{{ item.label |translate }}
</mat-option>
</mat-select>
<mat-error *ngIf="row.validator.controls.statusId.hasError('required')" translate>ERROR.FIELD_REQUIRED</mat-error>
</mat-form-field>
</mat-cell>
</ng-container>
<!-- CreationDate column -->
<ng-container matColumnDef="creationDate">
<mat-header-cell *matHeaderCellDef mat-sort-header class="mat-cell-date-time">
<span translate>REFERENTIAL.CREATION_DATE</span>
</mat-header-cell>
<mat-cell *matCellDef="let row" class="mat-cell-date-time">
{{ row.currentData.creationDate | dateFormat: {time: true} }}
</mat-cell>
</ng-container>
<!-- UpdateDate column -->
<ng-container matColumnDef="updateDate">
<mat-header-cell *matHeaderCellDef mat-sort-header class="mat-cell-date-time">
<span translate>REFERENTIAL.UPDATE_DATE</span>
</mat-header-cell>
<mat-cell *matCellDef="let row" class="mat-cell-date-time">
{{ row.currentData.updateDate | dateFormat: {time: true} }}
</mat-cell>
</ng-container>
<!-- Actions buttons column -->
<ng-container matColumnDef="actions">
<mat-header-cell *matHeaderCellDef [hidden]="!inlineEdition">
<span></span>
</mat-header-cell>
<mat-cell *matCellDef="let row" [hidden]="!inlineEdition">
<!-- undo or delete -->
<button mat-icon-button color="light"
*ngIf="row.validator.invalid"
[title]="(row.id !== -1 ? 'COMMON.BTN_UNDO': 'COMMON.BTN_DELETE')|translate"
(click)="cancelOrDelete($event, row)">
<mat-icon *ngIf="row.id !== -1">undo</mat-icon>
<mat-icon *ngIf="row.id === -1">delete_outline</mat-icon>
</button>
<!-- validate -->
<button mat-icon-button color="light" *ngIf="row.validator.valid && row.id !== -1"
[title]="'COMMON.BTN_VALIDATE'|translate"
(click)="confirmEditCreate($event, row)">
<mat-icon>check</mat-icon>
</button>
<!-- add -->
<button mat-icon-button color="light" *ngIf="row.validator.valid && row.id === -1"
[title]="'COMMON.BTN_ADD'|translate"
(click)="confirmAndAddRow($event, row)">
<mat-icon>add</mat-icon>
</button>
</mat-cell>
</ng-container>
</mat-select-trigger>
<mat-option *ngFor="let item of statusList" [value]="item.id">
<ion-icon [name]="item.icon"></ion-icon>
{{ item.label |translate }}
</mat-option>
</mat-select>
<mat-error *ngIf="row.validator.controls.statusId.hasError('required')" translate>ERROR.FIELD_REQUIRED</mat-error>
</mat-form-field>
</td>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"
[class.mat-row-error]="row.validator.invalid"
[class.mat-row-disabled]="!row.editing"
[class.mat-row-dirty]="row.validator.dirty"
(click)="clickRow($event, row)"></mat-row>
</mat-table>
<!-- CreationDate column -->
<ng-container matColumnDef="creationDate">
<th mat-header-cell *matHeaderCellDef class="mat-cell-date-time" cdkDrag>
<span mat-sort-header><ion-label translate>REFERENTIAL.CREATION_DATE</ion-label></span>
</th>
<td mat-cell *matCellDef="let row" class="mat-cell-date-time">
{{ row.currentData.creationDate | dateFormat: {time: true} }}
</td>
</ng-container>
<!-- UpdateDate column -->
<ng-container matColumnDef="updateDate">
<th mat-header-cell *matHeaderCellDef class="mat-cell-date-time" cdkDrag>
<span mat-sort-header><ion-label translate>REFERENTIAL.UPDATE_DATE</ion-label></span>
</th>
<td mat-cell *matCellDef="let row" class="mat-cell-date-time">
{{ row.currentData.updateDate | dateFormat: {time: true} }}
</td>
</ng-container>
<!-- Actions buttons column -->
<ng-container matColumnDef="actions" stickyEnd>
<th mat-header-cell *matHeaderCellDef [hidden]="!inlineEdition">
<button mat-icon-button [title]=" 'COMMON.DISPLAYED_COLUMNS'|translate" (click)="openSelectColumnsModal($event)">
<mat-icon>more_vert</mat-icon>
</button>
</th>
<td mat-cell *matCellDef="let row" [hidden]="!inlineEdition">
<!-- undo or delete -->
<button mat-icon-button color="light"
*ngIf="row.validator.invalid"
[title]="(row.id !== -1 ? 'COMMON.BTN_UNDO': 'COMMON.BTN_DELETE')|translate"
(click)="cancelOrDelete($event, row)">
<mat-icon *ngIf="row.id !== -1">undo</mat-icon>
<mat-icon *ngIf="row.id === -1">delete_outline</mat-icon>
</button>
<!-- validate -->
<button mat-icon-button color="light" *ngIf="row.validator.valid && row.id !== -1"
[title]="'COMMON.BTN_VALIDATE'|translate"
(click)="confirmEditCreate($event, row)">
<mat-icon>check</mat-icon>
</button>
<!-- add -->
<button mat-icon-button color="light" *ngIf="row.validator.valid && row.id === -1"
[title]="'COMMON.BTN_ADD'|translate"
(click)="confirmAndAddRow($event, row)">
<mat-icon>add</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"
[class.mat-row-error]="row.validator.invalid"
[class.mat-row-disabled]="!row.editing"
[class.mat-row-dirty]="row.validator.dirty"
[class.mat-row-status-disabled]="row.validator.controls.statusId?.value === 0"
(click)="clickRow($event, row)"></tr>
</table>
</div>
<!-- Paginator -->
<ion-row class="ion-no-padding">
......@@ -321,3 +320,4 @@
<ion-icon name="add"></ion-icon>
</ion-fab-button>
</ion-fab>
.mat-expansion-panel {
margin-bottom: 5px;
.form-container {
mat-form-field {
width: 100%;
.datetime-md {
padding: 0 !important;
}
}
}
mat-action-row {
ion-label {
line-height: 36px;
}
}
}
.mat-table {
.mat-column-id {
max-width: 100px;
padding-left: 0;
}
.mat-column-label {
min-width: 50px;
max-width: 150px;
}
.mat-column-status {
max-width: 150px;
}
.mat-column-comments {
max-width: 90px;
}
mat-header-cell.hidden,
mat-cell.hidden {
visibility: hidden;
display: none;
}
}
import {ChangeDetectorRef, Directive, Injector} from '@angular/core';
import {AccountService, AppTable, AppValidatorService, DefaultStatusList, EntitiesTableDataSource, isNotNilOrBlank, LocalSettingsService, Referential} from "sumaris-lib";
import {AccountService, AppTable, AppValidatorService, DefaultStatusList, EntitiesTableDataSource, isNotNilOrBlank, LocalSettingsService, Referential, RESERVED_START_COLUMNS} from "sumaris-lib";
import {BaseReferentialFilter, ReferentialFilter} from "@app/referential/model/referential.model";
import {ActivatedRoute, Router} from "@angular/router";
import {ModalController, Platform, PopoverController} from "@ionic/angular";
......@@ -12,6 +12,7 @@ import {BehaviorSubject} from "rxjs";
import {debounceTime, filter} from "rxjs/operators";
import {CanLeave} from "@app/shared/table/component-dirty.guard";
import {CommentModal} from "@app/shared/comment/comment.modal";
import {CdkDragDrop, moveItemInArray} from "@angular/cdk/drag-drop";
@Directive()
......@@ -177,4 +178,10 @@ export abstract class ReferentialTable<E extends Referential<E> = Referential,
}
drop(event: CdkDragDrop<string[]>) {
const offset = RESERVED_START_COLUMNS.length;
moveItemInArray(this.displayedColumns, event.previousIndex + offset, event.currentIndex + offset);
// todo save columns position
}
}
......@@ -7,14 +7,23 @@ import {Component, HostBinding} from "@angular/core";
})
export class ResizableComponent {
@HostBinding("style.width.px")
width: number | null = null;
private debug = false;
@HostBinding("style.min-width.px")
minWidth: number | null = null;
@HostBinding("style.width")
width: string | null = null;
@HostBinding("style.min-width")
minWidth: string | null = null;
onResize(width: number) {
this.width = width;
this.minWidth = width;
if (this.debug) console.info(`resize:${width}`);
this.width = width + 'px';
this.minWidth = width + 'px';
}
onFit() {
if (this.debug) console.info('fit');
this.width = 'auto';
this.minWidth = null;
}
}
import {DOCUMENT} from "@angular/common";
import {Directive, ElementRef, Inject, Output} from "@angular/core";