move table header to common lib

This commit is contained in:
Dan Percic 2021-08-10 19:53:13 +03:00
parent 7e66364b88
commit c99d6cda8d
33 changed files with 42 additions and 245 deletions

View File

@ -3,13 +3,13 @@
<div class="red-content-inner">
<div class="content-container">
<redaction-table-header
<iqser-table-header
[bulkActions]="bulkActions"
[hasEmptyColumn]="true"
[selectionEnabled]="true"
[tableColumnConfigs]="tableColumnConfigs"
[tableHeaderLabel]="tableHeaderLabel"
></redaction-table-header>
></iqser-table-header>
<redaction-empty-state
*ngIf="entitiesService.noData$ | async"

View File

@ -1,10 +1,10 @@
<redaction-table-header
<iqser-table-header
[bulkActions]="bulkActions"
[selectionEnabled]="true"
[hasEmptyColumn]="true"
[tableColumnConfigs]="tableColumnConfigs"
[tableHeaderLabel]="tableHeaderLabel"
></redaction-table-header>
></iqser-table-header>
<redaction-empty-state
*ngIf="entitiesService.noData$ | async"

View File

@ -8,7 +8,7 @@ iqser-table-column-name::ng-deep > div {
}
}
redaction-table-header::ng-deep .header-item {
iqser-table-header::ng-deep .header-item {
padding: 0 24px 0 10px;
box-shadow: none;
border-top: 1px solid $separator;

View File

@ -86,7 +86,7 @@
</div>
</div>
<div class="table-header" redactionSyncWidth="table-item">
<div class="table-header" iqserSyncWidth="table-item">
<iqser-table-column-name
[label]="'audit-screen.table-col-names.message' | translate"
column="message"

View File

@ -20,11 +20,11 @@
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
<div class="content-container">
<redaction-table-header
<iqser-table-header
[hasEmptyColumn]="true"
[tableColumnConfigs]="tableColumnConfigs"
[tableHeaderLabel]="tableHeaderLabel"
></redaction-table-header>
></iqser-table-header>
<cdk-virtual-scroll-viewport [itemSize]="80" redactionHasScrollbar>
<div *cdkVirtualFor="let color of sortedDisplayedEntities$ | async; trackBy: trackByPrimaryKey" class="table-item">

View File

@ -20,13 +20,13 @@
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
<div class="content-container">
<redaction-table-header
<iqser-table-header
[bulkActions]="bulkActions"
[selectionEnabled]="true"
[hasEmptyColumn]="true"
[tableColumnConfigs]="tableColumnConfigs"
[tableHeaderLabel]="tableHeaderLabel"
></redaction-table-header>
></iqser-table-header>
<redaction-empty-state
(action)="openAddEditDictionaryDialog()"

View File

@ -1,7 +1,7 @@
@import '../../../../../assets/styles/variables';
@import '../../../../../assets/styles/red-mixins';
redaction-table-header::ng-deep .header-item {
iqser-table-header::ng-deep .header-item {
padding-right: 16px;
}

View File

@ -20,13 +20,13 @@
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
<div class="content-container">
<redaction-table-header
<iqser-table-header
[bulkActions]="bulkActions"
[selectionEnabled]="true"
[hasEmptyColumn]="true"
[tableColumnConfigs]="tableColumnConfigs"
[tableHeaderLabel]="tableHeaderLabel"
></redaction-table-header>
></iqser-table-header>
<redaction-empty-state
(action)="openAddEditAttributeDialog($event)"

View File

@ -8,7 +8,7 @@
<div class="red-content-inner">
<div class="content-container">
<redaction-table-header
<iqser-table-header
[bulkActions]="bulkActions"
[selectionEnabled]="true"
[tableColumnConfigs]="tableColumnConfigs"
@ -29,7 +29,7 @@
icon="red:plus"
></iqser-icon-button>
</div>
</redaction-table-header>
</iqser-table-header>
<redaction-empty-state
*ngIf="entitiesService.noData$ | async"

View File

@ -20,13 +20,13 @@
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
<div class="content-container">
<redaction-table-header
<iqser-table-header
[bulkActions]="bulkActions"
[selectionEnabled]="true"
[hasEmptyColumn]="true"
[tableColumnConfigs]="tableColumnConfigs"
[tableHeaderLabel]="tableHeaderLabel"
></redaction-table-header>
></iqser-table-header>
<redaction-empty-state
*ngIf="entitiesService.noData$ | async"

View File

@ -5,7 +5,7 @@
justify-content: flex-end;
}
redaction-table-header::ng-deep .header-item {
iqser-table-header::ng-deep .header-item {
padding: 0 24px 0 10px;
}

View File

@ -7,10 +7,9 @@ import { saveAs } from 'file-saver';
import { ComponentHasChanges } from '@guards/can-deactivate.guard';
import { ActivatedRoute } from '@angular/router';
import { AppStateService } from '@state/app-state.service';
import { Debounce } from '../../../../utils/debounce';
import { Debounce, IconButtonTypes } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { LoadingService } from '../../../../services/loading.service';
import { IconButtonTypes } from '@iqser/common-ui';
import { LoadingService } from '@services/loading.service';
import ICodeEditor = monaco.editor.ICodeEditor;
import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;
import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions;

View File

@ -5,12 +5,12 @@
<div class="red-content-inner">
<div class="content-container">
<redaction-table-header
<iqser-table-header
[bulkActions]="bulkActions"
[selectionEnabled]="true"
[tableColumnConfigs]="tableColumnConfigs"
[tableHeaderLabel]="tableHeaderLabel"
></redaction-table-header>
></iqser-table-header>
<redaction-empty-state
*ngIf="entitiesService.noData$ | async"

View File

@ -33,13 +33,13 @@
<div class="red-content-inner">
<div [class.extended]="collapsedDetails" class="content-container">
<redaction-table-header
<iqser-table-header
[bulkActions]="bulkActions"
[selectionEnabled]="true"
[hasEmptyColumn]="true"
[tableColumnConfigs]="tableColumnConfigs"
[tableHeaderLabel]="tableHeaderLabel"
></redaction-table-header>
></iqser-table-header>
<redaction-empty-state *ngIf="noMatch$ | async" [text]="'user-listing.no-match.title' | translate"></redaction-empty-state>

View File

@ -5,15 +5,14 @@ import { AppStateService } from '@state/app-state.service';
import { environment } from '@environments/environment';
import { HttpClient } from '@angular/common/http';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Debounce } from '@utils/debounce';
import { Debounce, IconButtonTypes } from '@iqser/common-ui';
import { WatermarkControllerService, WatermarkModelRes } from '@redaction/red-ui-http';
import { Toaster } from '@services/toaster.service';
import { ActivatedRoute } from '@angular/router';
import { BASE_HREF } from '../../../../tokens';
import { stampPDFPage } from '../../../../utils/page-stamper';
import { stampPDFPage } from '@utils/page-stamper';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { LoadingService } from '../../../../services/loading.service';
import { IconButtonTypes } from '@iqser/common-ui';
import { LoadingService } from '@services/loading.service';
export const DEFAULT_WATERMARK: WatermarkModelRes = {
text: null,

View File

@ -15,12 +15,11 @@ import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
import scrollIntoView from 'scroll-into-view-if-needed';
import { Debounce } from '@utils/debounce';
import { CircleButtonTypes, Debounce, IconButtonTypes, NestedFilter } from '@iqser/common-ui';
import { FileDataModel } from '@models/file/file-data.model';
import { CommentsComponent } from '../comments/comments.component';
import { PermissionsService } from '@services/permissions.service';
import { WebViewerInstance } from '@pdftron/webviewer';
import { CircleButtonTypes, IconButtonTypes, NestedFilter } from '@iqser/common-ui';
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];

View File

@ -8,10 +8,7 @@
<div class="red-content-inner">
<div class="content-container">
<redaction-table-header
[tableColumnConfigs]="tableColumnConfigs"
[tableHeaderLabel]="tableHeaderLabel"
></redaction-table-header>
<iqser-table-header [tableColumnConfigs]="tableColumnConfigs" [tableHeaderLabel]="tableHeaderLabel"></iqser-table-header>
<redaction-empty-state
(action)="openAddDossierDialog()"

View File

@ -69,10 +69,12 @@ export class DossierListingScreenComponent
class: 'flex-end'
}
];
dossiersChartData: DoughnutChartConfig[] = [];
documentsChartData: DoughnutChartConfig[] = [];
protected readonly _primaryKey = 'dossierName';
private _lastScrollPosition: number;
@ViewChild('needsWorkTemplate', { read: TemplateRef, static: true })
private readonly _needsWorkTemplate: TemplateRef<any>;
@ViewChild(CdkVirtualScrollViewport)

View File

@ -36,12 +36,12 @@
<div class="red-content-inner">
<div [class.extended]="collapsedDetails" class="content-container">
<redaction-table-header
<iqser-table-header
[bulkActions]="bulkActions"
[selectionEnabled]="true"
[tableColumnConfigs]="tableColumnConfigs"
[tableHeaderLabel]="tableHeaderLabel"
></redaction-table-header>
></iqser-table-header>
<redaction-empty-state
(action)="fileInput.click()"

View File

@ -3,7 +3,7 @@ import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from
import { AppStateService } from '@state/app-state.service';
import { Annotations, WebViewerInstance } from '@pdftron/webviewer';
import { PdfViewerComponent } from '../../components/pdf-viewer/pdf-viewer.component';
import { Debounce } from '@utils/debounce';
import { AutoUnsubscribe, CircleButtonTypes, Debounce, NestedFilter, processFilters } from '@iqser/common-ui';
import { MatDialogRef, MatDialogState } from '@angular/material/dialog';
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
@ -33,7 +33,6 @@ import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
import { LoadingService } from '@services/loading.service';
import { stampPDFPage } from '@utils/page-stamper';
import { TranslateService } from '@ngx-translate/core';
import { AutoUnsubscribe, CircleButtonTypes, NestedFilter, processFilters } from '@iqser/common-ui';
import { fileStatusTranslations } from '../../translations/file-status-translations';
import { handleFilterDelta } from '@shared/components/filters/popup-filter/utils/filter-utils';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';

View File

@ -10,10 +10,7 @@
<div class="red-content-inner">
<div class="content-container">
<redaction-table-header
[tableColumnConfigs]="tableColumnConfigs"
[tableHeaderLabel]="tableHeaderLabel"
></redaction-table-header>
<iqser-table-header [tableColumnConfigs]="tableColumnConfigs" [tableHeaderLabel]="tableHeaderLabel"></iqser-table-header>
<redaction-empty-state
*ngIf="searchResult.length === 0"

View File

@ -1,12 +1,11 @@
import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
import { DictionaryControllerService } from '@redaction/red-ui-http';
import { AppStateService } from '@state/app-state.service';
import { Debounce } from '@utils/debounce';
import { Debounce, IconButtonTypes } from '@iqser/common-ui';
import { Observable } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { DossierWrapper } from '@state/model/dossier.wrapper';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { IconButtonTypes } from '@iqser/common-ui';
import ICodeEditor = monaco.editor.ICodeEditor;
import IDiffEditor = monaco.editor.IDiffEditor;
import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration;

View File

@ -1,42 +0,0 @@
<div [class.selection-enabled]="selectionEnabled" class="header-item">
<iqser-round-checkbox
(click)="entitiesService.selectAll()"
*ngIf="selectionEnabled"
[active]="entitiesService.areAllSelected$ | async"
[indeterminate]="entitiesService.notAllSelected$ | async"
></iqser-round-checkbox>
<span class="all-caps-label">
{{ tableHeaderLabel | translate: { length: (entitiesService.displayedLength$ | async) } }}
</span>
<ng-container [ngTemplateOutlet]="bulkActions"></ng-container>
<iqser-quick-filters *ngIf="quickFilters$ | async as quickFilters" [quickFilters]="quickFilters"></iqser-quick-filters>
<!-- Custom content-->
<ng-content></ng-content>
</div>
<div
[class.no-data]="entitiesService.noData$ | async"
[class.selection-enabled]="selectionEnabled"
class="table-header"
redactionSyncWidth="table-item"
>
<div *ngIf="selectionEnabled" class="select-oval-placeholder"></div>
<iqser-table-column-name
*ngFor="let config of tableColumnConfigs"
[class]="config.class"
[sortByKey]="config.sortByKey"
[label]="config.label | translate"
[leftIcon]="config.leftIcon"
[rightIconTooltip]="config.rightIconTooltip"
[rightIcon]="config.rightIcon"
></iqser-table-column-name>
<div *ngIf="hasEmptyColumn"></div>
<div class="scrollbar-placeholder"></div>
</div>

View File

@ -1,21 +0,0 @@
import { ChangeDetectionStrategy, Component, Input, TemplateRef } from '@angular/core';
import { EntitiesService, FilterService, Required, TableColumnConfig } from '@iqser/common-ui';
import { map } from 'rxjs/operators';
@Component({
selector: 'redaction-table-header',
templateUrl: './table-header.component.html',
styleUrls: ['./table-header.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class TableHeaderComponent<T extends object> {
@Input() @Required() tableHeaderLabel: string;
@Input() @Required() tableColumnConfigs: TableColumnConfig<T>[];
@Input() hasEmptyColumn = false;
@Input() selectionEnabled = false;
@Input() bulkActions: TemplateRef<any>;
readonly quickFilters$ = this.filterService.getFilterModels$('quickFilters').pipe(map(filters => new Set(filters)));
constructor(readonly entitiesService: EntitiesService<T>, readonly filterService: FilterService) {}
}

View File

@ -1,76 +0,0 @@
import { AfterViewInit, Directive, ElementRef, HostListener, Input, OnDestroy } from '@angular/core';
import { Debounce } from '@utils/debounce';
@Directive({
selector: '[redactionSyncWidth]',
exportAs: 'redactionSyncWidth'
})
export class SyncWidthDirective implements AfterViewInit, OnDestroy {
@Input()
redactionSyncWidth: string;
private _interval: number;
constructor(private readonly _elementRef: ElementRef) {}
ngAfterViewInit(): void {
this._interval = setInterval(() => {
this.matchWidth();
}, 1000);
}
ngOnDestroy(): void {
clearInterval(this._interval);
}
@Debounce(10)
matchWidth() {
const headerItems = this._elementRef.nativeElement.children;
const tableRows = this._elementRef.nativeElement.parentElement.parentElement.getElementsByClassName(this.redactionSyncWidth);
if (!tableRows || !tableRows.length) {
return;
}
this._elementRef.nativeElement.setAttribute('synced', true);
const { tableRow, length } = this._sampleRow(tableRows);
const hasExtraColumns = headerItems.length !== length ? 1 : 0;
for (let idx = 0; idx < length - hasExtraColumns - 1; ++idx) {
if (headerItems[idx]) {
headerItems[idx].style.width = `${tableRow.children[idx].getBoundingClientRect().width}px`;
headerItems[idx].style.minWidth = `${tableRow.children[idx].getBoundingClientRect().width}px`;
}
}
for (let idx = length - hasExtraColumns - 1; idx < headerItems.length; ++idx) {
if (headerItems[idx]) {
headerItems[idx].style.minWidth = `0`;
}
}
}
@HostListener('window:resize')
onResize() {
this.matchWidth();
}
private _sampleRow(tableRows: HTMLCollectionOf<Element>): {
tableRow: Element;
length: number;
} {
let length = 0;
let tableRow: Element;
for (let idx = 0; idx < tableRows.length; ++idx) {
const row = tableRows.item(idx);
if (row.children.length > length) {
length = row.children.length;
tableRow = row;
}
}
return { tableRow, length };
}
}

View File

@ -1,7 +1,6 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FullPageLoadingIndicatorComponent } from './components/full-page-loading-indicator/full-page-loading-indicator.component';
import { TranslateModule } from '@ngx-translate/core';
import { InitialsAvatarComponent } from './components/initials-avatar/initials-avatar.component';
import { ScrollingModule } from '@angular/cdk/scrolling';
import { PaginationComponent } from './components/pagination/pagination.component';
@ -13,7 +12,6 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AnnotationIconComponent } from './components/annotation-icon/annotation-icon.component';
import { SimpleDoughnutChartComponent } from './components/simple-doughnut-chart/simple-doughnut-chart.component';
import { StatusBarComponent } from './components/status-bar/status-bar.component';
import { SyncWidthDirective } from './directives/sync-width.directive';
import { HasScrollbarDirective } from './directives/has-scrollbar.directive';
import { DictionaryAnnotationIconComponent } from './components/dictionary-annotation-icon/dictionary-annotation-icon.component';
import { HiddenActionComponent } from './components/hidden-action/hidden-action.component';
@ -32,14 +30,12 @@ import { AssignUserDropdownComponent } from './components/assign-user-dropdown/a
import { InputWithActionComponent } from '@shared/components/input-with-action/input-with-action.component';
import { PageHeaderComponent } from './components/page-header/page-header.component';
import { DatePipe } from '@shared/pipes/date.pipe';
import { TableHeaderComponent } from './components/table-header/table-header.component';
const buttons = [FileDownloadBtnComponent, UserButtonComponent];
const components = [
FullPageLoadingIndicatorComponent,
InitialsAvatarComponent,
TableHeaderComponent,
PaginationComponent,
InputWithActionComponent,
AnnotationIconComponent,
@ -59,14 +55,14 @@ const components = [
...buttons
];
const utils = [DatePipe, SyncWidthDirective, HasScrollbarDirective, NavigateLastDossiersScreenDirective];
const utils = [DatePipe, HasScrollbarDirective, NavigateLastDossiersScreenDirective];
const modules = [MatConfigModule, TranslateModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule, CommonUiModule];
const modules = [MatConfigModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule, CommonUiModule];
@NgModule({
declarations: [...components, ...utils, TableHeaderComponent],
declarations: [...components, ...utils],
imports: [CommonModule, ...modules, MonacoEditorModule],
exports: [...modules, ...components, ...utils, TableHeaderComponent],
exports: [...modules, ...components, ...utils],
providers: [
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
{

View File

@ -1,5 +1,5 @@
import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router';
import { Debounce } from './debounce';
import { Debounce } from '@iqser/common-ui';
export interface OnAttach {
ngOnAttach(previousRoute: ActivatedRouteSnapshot);

View File

@ -1,14 +0,0 @@
export function Debounce(delay: number = 300): MethodDecorator {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
let timeout = null;
const original = descriptor.value;
descriptor.value = function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => original.apply(this, args), delay);
};
return descriptor;
};
}

View File

@ -1,31 +0,0 @@
@import 'variables';
@import 'red-mixins';
.header-item {
background-color: $grey-6;
height: 50px;
padding: 0 24px;
display: flex;
align-items: center;
z-index: 1;
border-bottom: 1px solid $separator;
box-sizing: border-box;
> *:not(:last-child) {
margin-right: 10px;
}
.actions {
display: flex;
align-items: center;
justify-content: flex-end;
> *:not(:last-child) {
margin-right: 16px;
}
}
&.selection-enabled {
padding-left: 10px;
}
}

View File

@ -123,8 +123,3 @@ cdk-virtual-scroll-viewport {
}
}
}
.scrollbar-placeholder {
width: 11px;
padding: 0 !important;
}

View File

@ -18,7 +18,6 @@
@import 'red-controls';
@import 'red-toasts';
@import 'red-tooltips';
@import 'red-grid';
@import 'red-breadcrumbs';
@import 'red-editor';
@import 'red-slider';

@ -1 +1 @@
Subproject commit f0c440876402cb4f603583537eca36f9038cc6fa
Subproject commit 7e9b28a10c7b226dcab54354c6e7f1d8ccebc0c6