From 94482dc35dbaf95abbca365611412b5670920eb0 Mon Sep 17 00:00:00 2001 From: Dan Percic Date: Thu, 25 Nov 2021 20:21:47 +0200 Subject: [PATCH] add document info service --- .../document-info-dialog.component.ts | 8 ++- .../document-info.component.html | 11 +++- .../document-info/document-info.component.ts | 38 +++++------- .../file-preview-screen.component.html | 8 +-- .../file-preview-screen.component.ts | 27 ++++++--- .../services/document-info.service.ts | 60 +++++++++++++++++++ .../file-actions/file-actions.component.html | 8 +-- .../file-actions/file-actions.component.ts | 9 +-- 8 files changed, 116 insertions(+), 53 deletions(-) create mode 100644 apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/document-info.service.ts diff --git a/apps/red-ui/src/app/modules/dossier/dialogs/document-info-dialog/document-info-dialog.component.ts b/apps/red-ui/src/app/modules/dossier/dialogs/document-info-dialog/document-info-dialog.component.ts index fe136cdaf..b18ead053 100644 --- a/apps/red-ui/src/app/modules/dossier/dialogs/document-info-dialog/document-info-dialog.component.ts +++ b/apps/red-ui/src/app/modules/dossier/dialogs/document-info-dialog/document-info-dialog.component.ts @@ -1,9 +1,10 @@ import { Component, Inject, OnInit } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; -import { Dossier, IFile, IFileAttributeConfig } from '@red/domain'; +import { Dossier, File, IFileAttributeConfig } from '@red/domain'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { FileAttributesService } from '@services/entity-services/file-attributes.service'; import { DossiersService } from '@services/entity-services/dossiers.service'; +import { FilesService } from '@services/entity-services/files.service'; @Component({ templateUrl: './document-info-dialog.component.html', @@ -19,8 +20,9 @@ export class DocumentInfoDialogComponent implements OnInit { private readonly _dossiersService: DossiersService, private readonly _formBuilder: FormBuilder, private readonly _fileAttributesService: FileAttributesService, + private readonly _filesService: FilesService, public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: IFile, + @Inject(MAT_DIALOG_DATA) readonly data: File, ) { this._dossier = this._dossiersService.find(this.data.dossierId); } @@ -38,7 +40,7 @@ export class DocumentInfoDialogComponent implements OnInit { ...this.form.getRawValue(), }; await this._fileAttributesService.setFileAttributes({ attributeIdToValue }, this.data.dossierId, this.data.fileId).toPromise(); - this.data.fileAttributes = { attributeIdToValue }; + this._filesService.reload(this.data.dossierId, this.data.fileId); this.dialogRef.close(true); } diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/document-info/document-info.component.html b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/document-info/document-info.component.html index feb858389..f5f1120fe 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/document-info/document-info.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/document-info/document-info.component.html @@ -6,8 +6,9 @@ icon="iqser:edit" tooltipPosition="before" > +
-
+
{{ attr.label }}:
-
{{ (file.fileAttributes?.attributeIdToValue)[attr.id] || '-' }}
+
{{ attr.value || '-' }}
@@ -28,18 +29,22 @@ {{ 'file-preview.tabs.document-info.details.dossier' | translate: { dossierName: dossier.dossierName } }}
+
{{ 'file-preview.tabs.document-info.details.pages' | translate: { pages: file.numberOfPages } }}
+
{{ 'file-preview.tabs.document-info.details.created-on' | translate: { date: file.added | date: 'mediumDate' } }}
+
{{ 'file-preview.tabs.document-info.details.due' | translate: { date: dossier.dueDate | date: 'mediumDate' } }}
+
{{ dossierTemplateName }} diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/document-info/document-info.component.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/document-info/document-info.component.ts index d6e0afe6d..5f8ba1fde 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/document-info/document-info.component.ts +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/components/document-info/document-info.component.ts @@ -1,45 +1,39 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { File, IFileAttributesConfig } from '@red/domain'; +import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; +import { Dossier, File } from '@red/domain'; import { DossiersDialogService } from '../../../../services/dossiers-dialog.service'; import { AutoUnsubscribe } from '@iqser/common-ui'; -import { FileAttributesService } from '@services/entity-services/file-attributes.service'; -import { DossiersService } from '@services/entity-services/dossiers.service'; import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service'; +import { DocumentInfoService } from '../../services/document-info.service'; +import { Observable } from 'rxjs'; @Component({ - selector: 'redaction-document-info', + selector: 'redaction-document-info [file] [dossier]', templateUrl: './document-info.component.html', styleUrls: ['./document-info.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class DocumentInfoComponent extends AutoUnsubscribe implements OnInit { @Input() file: File; - @Output() readonly closeDocumentInfoView = new EventEmitter(); + @Input() dossier: Dossier; - fileAttributesConfig: IFileAttributesConfig; + fileAttributes$: Observable<{ label: string; value: string }[]>; + dossierTemplateName: string; constructor( - private readonly _dossiersService: DossiersService, private readonly _dossierTemplatesService: DossierTemplatesService, - private readonly _fileAttributesService: FileAttributesService, private readonly _dialogService: DossiersDialogService, + readonly documentInfoService: DocumentInfoService, ) { super(); } - get dossier() { - return this._dossiersService.find(this.file.dossierId); - } - - get dossierTemplateName(): string { - return this._dossierTemplatesService.find(this.dossier.dossierTemplateId).name; - } - ngOnInit(): void { - this.fileAttributesConfig = this._fileAttributesService.getFileAttributeConfig(this.dossier.dossierTemplateId); - - this.addSubscription = this._dossierTemplatesService.entityChanged$.subscribe(() => { - this.fileAttributesConfig = this._fileAttributesService.getFileAttributeConfig(this.dossier.dossierTemplateId); - }); + this.dossierTemplateName = this._dossierTemplatesService.find(this.dossier.dossierTemplateId).name; + this.fileAttributes$ = this.documentInfoService.fileAttributes$( + this.file.fileId, + this.file.dossierId, + this.dossier.dossierTemplateId, + ); } edit() { diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html index bdcaf2315..b4a428960 100644 --- a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/file-preview-screen.component.html @@ -20,8 +20,6 @@ @@ -81,15 +79,15 @@
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 052ddc0fb..973b17056 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 @@ -54,6 +54,7 @@ import { WatermarkService } from '@shared/services/watermark.service'; import { ExcludedPagesService } from './services/excluded-pages.service'; import { ViewModeService } from './services/view-mode.service'; import { MultiSelectService } from './services/multi-select.service'; +import { DocumentInfoService } from './services/document-info.service'; import Annotation = Core.Annotations.Annotation; import PDFNet = Core.PDFNet; @@ -62,7 +63,7 @@ const ALL_HOTKEY_ARRAY = ['Escape', 'F', 'f']; @Component({ templateUrl: './file-preview-screen.component.html', styleUrls: ['./file-preview-screen.component.scss'], - providers: [FilterService, ExcludedPagesService, ViewModeService, MultiSelectService], + providers: [FilterService, ExcludedPagesService, ViewModeService, MultiSelectService, DocumentInfoService], changeDetection: ChangeDetectionStrategy.OnPush, }) export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnInit, OnDestroy, OnAttach, OnDetach { @@ -76,13 +77,13 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni selectedAnnotations: AnnotationWrapper[]; hideSkipped = false; displayPDFViewer = false; - viewDocumentInfo = false; @ViewChild(PdfViewerComponent) readonly viewerComponent: PdfViewerComponent; @ViewChild('fileActions') fileActions: FileActionsComponent; readonly dossierId: string; readonly canPerformAnnotationActions$: Observable; readonly dossier$: Observable; readonly showExcludedPages$: Observable; + readonly viewDocumentInfo$: Observable; readonly file$: Observable; readonly fileId: string; private _instance: WebViewerInstance; @@ -119,6 +120,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni readonly excludedPagesService: ExcludedPagesService, readonly viewModeService: ViewModeService, readonly multiSelectService: MultiSelectService, + readonly documentInfoService: DocumentInfoService, ) { super(); this.dossierId = _activatedRoute.snapshot.paramMap.get('dossierId'); @@ -131,6 +133,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni shareLast(), ); this.showExcludedPages$ = this._showExcludedPages$; + this.viewDocumentInfo$ = this._viewDocumentInfo$; this.canPerformAnnotationActions$ = this._canPerformAnnotationActions$; document.documentElement.addEventListener('fullscreenchange', () => { @@ -156,6 +159,18 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni return this.viewModeService.isStandard ? currentPage : currentPage % 2 === 0 ? currentPage / 2 : (currentPage + 1) / 2; } + private get _viewDocumentInfo$() { + return this.documentInfoService.shown$.pipe( + tap(value => { + if (value) { + this.multiSelectService.deactivate(); + this.excludedPagesService.hide(); + } + }), + shareDistinctLast(), + ); + } + private get _showExcludedPages$() { return this.excludedPagesService.shown$.pipe(tap(() => this._disableMultiSelectAndDocumentInfo())); } @@ -415,12 +430,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni this._reloadFileOnReanalysis = true; } - toggleViewDocumentInfo(): void { - this.viewDocumentInfo = true; - this.multiSelectService.deactivate(); - this.excludedPagesService.hide(); - } - closeFullScreen() { if (!!document.fullscreenElement && document.exitFullscreen) { document.exitFullscreen().then(); @@ -458,7 +467,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni private _disableMultiSelectAndDocumentInfo(): void { this.multiSelectService.deactivate(); - this.viewDocumentInfo = false; + this.documentInfoService.hide(); } private _setHiddenPropertyToNewAnnotations(newAnnotations: AnnotationWrapper[], oldAnnotations: AnnotationWrapper[]) { diff --git a/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/document-info.service.ts b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/document-info.service.ts new file mode 100644 index 000000000..1b0651f8a --- /dev/null +++ b/apps/red-ui/src/app/modules/dossier/screens/file-preview-screen/services/document-info.service.ts @@ -0,0 +1,60 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, merge, Observable } from 'rxjs'; +import { shareDistinctLast } from '@iqser/common-ui'; +import { filter, map, startWith, withLatestFrom } from 'rxjs/operators'; +import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service'; +import { FileAttributesService } from '@services/entity-services/file-attributes.service'; +import { FilesMapService } from '@services/entity-services/files-map.service'; +import { File, IFileAttributeConfig } from '@red/domain'; + +@Injectable() +export class DocumentInfoService { + readonly shown$: Observable; + readonly hidden$: Observable; + private readonly _show$ = new BehaviorSubject(false); + + constructor( + private readonly _dossierTemplatesService: DossierTemplatesService, + private readonly _fileAttributesService: FileAttributesService, + private readonly _filesMapService: FilesMapService, + ) { + this.shown$ = this._show$.asObservable().pipe(shareDistinctLast()); + this.hidden$ = this.shown$.pipe( + map(value => !value), + shareDistinctLast(), + ); + } + + fileAttributes$(fileId: string, dossierId: string, dossierTemplateId: string) { + const getAttributes = () => this._fileAttributesService.getFileAttributeConfig(dossierTemplateId).fileAttributeConfigs; + const dossierTemplateChange$ = this._dossierTemplatesService.entityChanged$.pipe( + filter(template => template.dossierTemplateId === dossierTemplateId), + ); + const fileChange$ = this._filesMapService.watch$(dossierId, fileId); + return merge(dossierTemplateChange$, fileChange$).pipe( + map(getAttributes), + startWith(getAttributes()), + withLatestFrom(fileChange$), + map(values => this._toAttributes(...values)), + ); + } + + show() { + this._show$.next(true); + } + + hide() { + this._show$.next(false); + } + + toggle() { + this._show$.next(!this._show$.value); + } + + private _toAttributes(attributes: IFileAttributeConfig[], file: File) { + return attributes.map(attr => ({ + label: attr.label, + value: file?.fileAttributes?.attributeIdToValue[attr.id], + })); + } +} diff --git a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html index 766eac5a7..2b5988d53 100644 --- a/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html +++ b/apps/red-ui/src/app/modules/dossier/shared/components/file-actions/file-actions.component.html @@ -62,9 +62,9 @@ > (); @@ -54,8 +54,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, showUnderApproval: boolean; showApprove: boolean; canToggleAnalysis: boolean; - showExcludePages: boolean; - showDocumentInfo: boolean; showStatusBar: boolean; showOpenDocument: boolean; analysisForced: boolean; @@ -64,10 +62,10 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, isDossierOverviewWorkflow = false; isFilePreview = false; tooltipPosition: IqserTooltipPosition; - @Output() readonly toggleViewDocumentInfo = new EventEmitter(); constructor( @Optional() readonly excludedPagesService: ExcludedPagesService, + @Optional() readonly documentInfoService: DocumentInfoService, private readonly _permissionsService: PermissionsService, private readonly _dossiersService: DossiersService, private readonly _dialogService: DossiersDialogService, @@ -223,9 +221,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy, this.isDossierOverview; this.showOpenDocument = this.file.canBeOpened && this.isDossierOverviewWorkflow; - - this.showExcludePages = this.isFilePreview; - this.showDocumentInfo = this.isFilePreview; } private async _setFileApproved() {