diff --git a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts index fcc31eeb0..b50535f0a 100644 --- a/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/rules/rules-screen.component.ts @@ -7,13 +7,13 @@ 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 } from '../../../../utils/debounce'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { LoadingService } from '../../../../services/loading.service'; +import { IconButtonTypes } from '@iqser/common-ui'; import ICodeEditor = monaco.editor.ICodeEditor; import IModelDeltaDecoration = monaco.editor.IModelDeltaDecoration; import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions; -import { IconButtonTypes } from '@iqser/common-ui'; @Component({ selector: 'redaction-rules-screen', @@ -81,7 +81,7 @@ export class RulesScreenComponent extends ComponentHasChanges implements OnInit (window as any).monaco.editor.setTheme('redaction'); } - @debounce() + @Debounce() codeEditorTextChanged() { const newDecorations = this.currentLines.filter(entry => this._isNew(entry)).map(entry => this._makeDecorationFor(entry)); diff --git a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts index b7ffe527a..b27a16217 100644 --- a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen.component.ts @@ -5,7 +5,7 @@ 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 } from '@utils/debounce'; import { WatermarkControllerService, WatermarkModelRes } from '@redaction/red-ui-http'; import { Toaster } from '@services/toaster.service'; import { ActivatedRoute } from '@angular/router'; @@ -70,7 +70,7 @@ export class WatermarkScreenComponent implements OnInit { this._loadWatermark(); } - @debounce() + @Debounce() async configChanged() { await this._drawWatermark(); } diff --git a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts index 57034f992..022589698 100644 --- a/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts +++ b/apps/red-ui/src/app/modules/dossier/components/file-workload/file-workload.component.ts @@ -15,12 +15,12 @@ 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 { Debounce } from '@utils/debounce'; 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, NestedFilter, IconButtonTypes } from '@iqser/common-ui'; +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']; @@ -142,7 +142,7 @@ export class FileWorkloadComponent { this._changeDetectorRef.detectChanges(); } - @debounce(0) + @Debounce(0) filtersChanged(filters: { primary: NestedFilter[]; secondary?: NestedFilter[] }) { this.displayedAnnotations = this._annotationProcessingService.filterAndGroupAnnotations( this._annotations, @@ -222,7 +222,7 @@ export class FileWorkloadComponent { } } - @debounce() + @Debounce() scrollToSelectedAnnotation() { if (!this.selectedAnnotations || this.selectedAnnotations.length === 0 || !this._annotationsElement) { return; diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts index d19f81fe7..56a7d8a1d 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.ts @@ -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 { Debounce } from '@utils/debounce'; import { MatDialogRef, MatDialogState } from '@angular/material/dialog'; import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; @@ -588,7 +588,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribeComponent impleme } } - @debounce() + @Debounce() private _scrollViews() { this._workloadComponent?.scrollQuickNavigation(); this._workloadComponent?.scrollAnnotations(); diff --git a/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts b/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts index 25b62057a..cb72ea82b 100644 --- a/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts +++ b/apps/red-ui/src/app/modules/shared/base/base-listing.component.ts @@ -1,6 +1,7 @@ -import { Component, Injector, OnDestroy } from '@angular/core'; +import { Directive, Injector, OnDestroy } from '@angular/core'; import { AutoUnsubscribeComponent, + Bind, EntitiesService, FilterService, KeysOf, @@ -14,7 +15,7 @@ import { distinctUntilChanged, map, switchMap } from 'rxjs/operators'; export const DefaultListingServices = [FilterService, SearchService, EntitiesService, SortingService] as const; -@Component({ template: '' }) +@Directive() export abstract class BaseListingComponent extends AutoUnsubscribeComponent implements OnDestroy { readonly filterService = this._injector.get(FilterService); readonly searchService = this._injector.get>(SearchService); @@ -34,7 +35,6 @@ export abstract class BaseListingComponent extends AutoUnsubsc protected constructor(protected readonly _injector: Injector) { super(); - this.trackByPrimaryKey = this.trackByPrimaryKey.bind(this); setTimeout(() => this.setInitialConfig()); } @@ -83,6 +83,7 @@ export abstract class BaseListingComponent extends AutoUnsubsc return this.entitiesService.isSelected(entity); } + @Bind() trackByPrimaryKey(index: number, item: T) { return item[this._primaryKey]; } diff --git a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts index 61740c678..dcd6d3b29 100644 --- a/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/dictionary-manager/dictionary-manager.component.ts @@ -1,7 +1,7 @@ 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 } from '@utils/debounce'; import { Observable } from 'rxjs'; import { map, take } from 'rxjs/operators'; import { DossierWrapper } from '@state/model/dossier.wrapper'; @@ -128,7 +128,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { this.searchChanged(''); } - @debounce() + @Debounce() searchChanged(text: string) { this.searchText = text.toLowerCase(); this.findMatches = this._getMatches(this.searchText); @@ -138,7 +138,7 @@ export class DictionaryManagerComponent implements OnChanges, OnInit { this.nextSearchMatch(); } - @debounce() + @Debounce() codeEditorTextChanged() { const newDecorations = this.currentEntries.filter(entry => this._isNew(entry)).map(entry => this._getDecoration(entry)); diff --git a/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/utils/filter-utils.ts b/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/utils/filter-utils.ts index 857084eda..a99cc03f1 100644 --- a/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/utils/filter-utils.ts +++ b/apps/red-ui/src/app/modules/shared/components/filters/popup-filter/utils/filter-utils.ts @@ -1,8 +1,7 @@ import { FileStatusWrapper } from '@models/file/file-status.wrapper'; import { DossierWrapper } from '@state/model/dossier.wrapper'; import { PermissionsService } from '@services/permissions.service'; -import { handleCheckedValue } from '@iqser/common-ui'; -import { NestedFilter } from '@iqser/common-ui'; +import { handleCheckedValue, NestedFilter } from '@iqser/common-ui'; export function handleFilterDelta(oldFilters: NestedFilter[], newFilters: NestedFilter[], allFilters: NestedFilter[]) { const newFiltersDelta = {}; @@ -81,10 +80,7 @@ export const annotationFilterChecker = ( } }; -export const dossierStatusChecker = (dw: DossierWrapper, filter: NestedFilter) => { - console.log(dw, filter); - return dw.hasStatus(filter.key); -}; +export const dossierStatusChecker = (dw: DossierWrapper, filter: NestedFilter) => dw.hasStatus(filter.key); export const dossierMemberChecker = (dw: DossierWrapper, filter: NestedFilter) => dw.hasMember(filter.key); diff --git a/apps/red-ui/src/app/modules/shared/directives/sync-width.directive.ts b/apps/red-ui/src/app/modules/shared/directives/sync-width.directive.ts index 9b4b9e8f8..123f88eb1 100644 --- a/apps/red-ui/src/app/modules/shared/directives/sync-width.directive.ts +++ b/apps/red-ui/src/app/modules/shared/directives/sync-width.directive.ts @@ -1,5 +1,5 @@ import { AfterViewInit, Directive, ElementRef, HostListener, Input, OnDestroy } from '@angular/core'; -import { debounce } from '@utils/debounce'; +import { Debounce } from '@utils/debounce'; @Directive({ selector: '[redactionSyncWidth]', @@ -22,7 +22,7 @@ export class SyncWidthDirective implements AfterViewInit, OnDestroy { clearInterval(this._interval); } - @debounce(10) + @Debounce(10) matchWidth() { const headerItems = this._elementRef.nativeElement.children; const tableRows = document.getElementsByClassName(this.redactionSyncWidth); diff --git a/apps/red-ui/src/app/utils/custom-route-reuse.strategy.ts b/apps/red-ui/src/app/utils/custom-route-reuse.strategy.ts index d41a1190f..cfc0e50be 100644 --- a/apps/red-ui/src/app/utils/custom-route-reuse.strategy.ts +++ b/apps/red-ui/src/app/utils/custom-route-reuse.strategy.ts @@ -1,5 +1,5 @@ import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router'; -import { debounce } from './debounce'; +import { Debounce } from './debounce'; export interface OnAttach { ngOnAttach(previousRoute: ActivatedRouteSnapshot); @@ -69,12 +69,12 @@ export class CustomRouteReuseStrategy implements RouteReuseStrategy { .join(''); } - @debounce() + @Debounce() private _onAttach(instance: OnAttach, previousRoute?: ActivatedRouteSnapshot) { instance.ngOnAttach(previousRoute); } - @debounce() + @Debounce() private _onDetach(instance: OnDetach) { instance.ngOnDetach(); } diff --git a/apps/red-ui/src/app/utils/debounce.ts b/apps/red-ui/src/app/utils/debounce.ts index af56c8df1..47fd1a269 100644 --- a/apps/red-ui/src/app/utils/debounce.ts +++ b/apps/red-ui/src/app/utils/debounce.ts @@ -1,4 +1,4 @@ -export function debounce(delay: number = 300): MethodDecorator { +export function Debounce(delay: number = 300): MethodDecorator { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { let timeout = null; diff --git a/apps/red-ui/src/app/utils/dialog-helper.ts b/apps/red-ui/src/app/utils/dialog-helper.ts deleted file mode 100644 index 653b86897..000000000 --- a/apps/red-ui/src/app/utils/dialog-helper.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { MatDialogConfig } from '@angular/material/dialog'; -import { Overlay, OverlayConfig } from '@angular/cdk/overlay'; - -export class DialogHelper { - static _MARGIN = '16px'; - - static generateDialogConfig(injectionData?: any | null): MatDialogConfig { - const viewPortWidth = window.innerWidth; - if (viewPortWidth < 600) { - return DialogHelper.generateFullScreenDialogConfig(injectionData); - } - - const conf = new MatDialogConfig(); - conf.position = { top: '100px' }; - conf.maxWidth = '90vw'; - conf.maxHeight = '88vh'; - if (injectionData) { - conf.data = injectionData; - } - return conf; - } - - static generateMediumDialogConfig(injectionData?: any | null): MatDialogConfig { - const conf = new MatDialogConfig(); - conf.width = '60vw'; - conf.maxHeight = '88vh'; - conf.maxWidth = '90vw'; - if (injectionData) { - conf.data = injectionData; - } - return conf; - } - - static generateLargeDialogConfig(injectionData?: any | null): MatDialogConfig { - const conf = new MatDialogConfig(); - conf.height = '90vh'; - conf.width = '90vw'; - conf.maxWidth = '90vw'; - if (injectionData) { - conf.data = injectionData; - } - return conf; - } - - static generateFullScreenDialogConfig(injectionData?: any | null): MatDialogConfig { - const conf = new MatDialogConfig(); - conf.height = '100vh'; - conf.width = '100vw'; - conf.maxWidth = '100vw'; - if (injectionData) { - conf.data = injectionData; - } - return conf; - } - - static generateFileDropConfig(overlay: Overlay): OverlayConfig { - const config = new OverlayConfig(); - config.hasBackdrop = true; - config.backdropClass = 'dark-backdrop'; - config.panelClass = 'gin-file-upload-dialog-panel'; - config.scrollStrategy = overlay.scrollStrategies.block(); - config.positionStrategy = overlay.position().global().centerHorizontally().centerVertically(); - return config; - } - - static generateUploadStatusConfig(overlay: Overlay): OverlayConfig { - const config = new OverlayConfig(); - config.hasBackdrop = false; - config.positionStrategy = overlay.position().global().bottom(DialogHelper._MARGIN).right(DialogHelper._MARGIN); - return config; - } -} diff --git a/apps/red-ui/src/app/utils/page-stamper.ts b/apps/red-ui/src/app/utils/page-stamper.ts index 16611e565..5ee3d14b3 100644 --- a/apps/red-ui/src/app/utils/page-stamper.ts +++ b/apps/red-ui/src/app/utils/page-stamper.ts @@ -1,5 +1,5 @@ import { hexToRgb } from './functions'; -import { environment } from '../../environments/environment'; +import { environment } from '@environments/environment'; import { PDFNet } from '@pdftron/webviewer'; import PDFDoc = PDFNet.PDFDoc; diff --git a/apps/red-ui/src/app/utils/sync-scroll.ts b/apps/red-ui/src/app/utils/sync-scroll.ts deleted file mode 100644 index 51a462699..000000000 --- a/apps/red-ui/src/app/utils/sync-scroll.ts +++ /dev/null @@ -1,61 +0,0 @@ -export function syncScroll(elements: HTMLElement[]) { - // clearing existing listeners - for (const element of elements) { - element.removeEventListener('scroll', (element).scrollSync); - } - - // setting-up the new listeners - for (let idx = 0; idx < elements.length; ) { - const loopElement: any = elements[idx++]; - - loopElement.eX = loopElement.eY = 0; - - (el => { - el['addEventListener']( - 'scroll', - (el.scrollSync = () => { - let scrollX = el['scrollLeft']; - let scrollY = el['scrollTop']; - - const xRate = scrollX / (el['scrollWidth'] - el['clientWidth']); - const yRate = scrollY / (el['scrollHeight'] - el['clientHeight']); - - const updateX = scrollX !== el.eX; - const updateY = scrollY !== el.eY; - - let otherEl, - i = 0; - - el.eX = scrollX; - el.eY = scrollY; - - for (; i < elements.length; ) { - otherEl = elements[i++]; - if (otherEl !== el) { - if ( - updateX && - Math.round( - otherEl['scrollLeft'] - - (scrollX = otherEl.eX = Math.round(xRate * (otherEl['scrollWidth'] - otherEl['clientWidth']))) - ) - ) { - otherEl['scrollLeft'] = scrollX; - } - - if ( - updateY && - Math.round( - otherEl['scrollTop'] - - (scrollY = otherEl.eY = Math.round(yRate * (otherEl['scrollHeight'] - otherEl['clientHeight']))) - ) - ) { - otherEl['scrollTop'] = scrollY; - } - } - } - }), - 0 - ); - })(loopElement); - } -} diff --git a/apps/red-ui/src/app/utils/uuid-helper.ts b/apps/red-ui/src/app/utils/uuid-helper.ts deleted file mode 100644 index 3cd05d407..000000000 --- a/apps/red-ui/src/app/utils/uuid-helper.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* eslint-disable */ -const lut = []; -for (let i = 0; i < 256; i++) { - lut[i] = (i < 16 ? '0' : '') + i.toString(16); -} - -export function isUUID(uuid: string) { - return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(uuid); -} - -export function UUID() { - const d0 = (Math.random() * 0xffffffff) | 0; - const d1 = (Math.random() * 0xffffffff) | 0; - const d2 = (Math.random() * 0xffffffff) | 0; - const d3 = (Math.random() * 0xffffffff) | 0; - return ( - lut[d0 & 0xff] + - lut[(d0 >> 8) & 0xff] + - lut[(d0 >> 16) & 0xff] + - lut[(d0 >> 24) & 0xff] + - '-' + - lut[d1 & 0xff] + - lut[(d1 >> 8) & 0xff] + - '-' + - lut[((d1 >> 16) & 0x0f) | 0x40] + - lut[(d1 >> 24) & 0xff] + - '-' + - lut[(d2 & 0x3f) | 0x80] + - lut[(d2 >> 8) & 0xff] + - '-' + - lut[(d2 >> 16) & 0xff] + - lut[(d2 >> 24) & 0xff] + - lut[d3 & 0xff] + - lut[(d3 >> 8) & 0xff] + - lut[(d3 >> 16) & 0xff] + - lut[(d3 >> 24) & 0xff] - ); -} - -/* eslint-enable */ diff --git a/libs/common-ui b/libs/common-ui index f1e8d9011..c552ed2e2 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit f1e8d9011cff19f684d4681ee2cce3e3e980c3c3 +Subproject commit c552ed2e21d3df6fbcfe842ae85ac5a75006ab85