add document info service

This commit is contained in:
Dan Percic 2021-11-25 20:21:47 +02:00
parent 608c43cfe1
commit 94482dc35d
8 changed files with 116 additions and 53 deletions

View File

@ -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<DocumentInfoDialogComponent>,
@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);
}

View File

@ -6,8 +6,9 @@
icon="iqser:edit"
tooltipPosition="before"
></iqser-circle-button>
<iqser-circle-button
(action)="closeDocumentInfoView.emit()"
(action)="documentInfoService.hide()"
[tooltip]="'file-preview.tabs.document-info.close' | translate"
icon="iqser:close"
tooltipPosition="before"
@ -17,9 +18,9 @@
<div class="right-content" iqserHasScrollbar>
<div class="section">
<div *ngFor="let attr of fileAttributesConfig?.fileAttributeConfigs" class="attribute">
<div *ngFor="let attr of fileAttributes$ | async" class="attribute">
<div class="small-label">{{ attr.label }}:</div>
<div>{{ (file.fileAttributes?.attributeIdToValue)[attr.id] || '-' }}</div>
<div>{{ attr.value || '-' }}</div>
</div>
</div>
@ -28,18 +29,22 @@
<mat-icon svgIcon="red:folder"></mat-icon>
<span>{{ 'file-preview.tabs.document-info.details.dossier' | translate: { dossierName: dossier.dossierName } }}</span>
</div>
<div>
<mat-icon svgIcon="iqser:document"></mat-icon>
<span>{{ 'file-preview.tabs.document-info.details.pages' | translate: { pages: file.numberOfPages } }}</span>
</div>
<div>
<mat-icon svgIcon="red:calendar"></mat-icon>
<span>{{ 'file-preview.tabs.document-info.details.created-on' | translate: { date: file.added | date: 'mediumDate' } }}</span>
</div>
<div *ngIf="dossier.dueDate">
<mat-icon svgIcon="red:lightning"></mat-icon>
<span>{{ 'file-preview.tabs.document-info.details.due' | translate: { date: dossier.dueDate | date: 'mediumDate' } }}</span>
</div>
<div>
<mat-icon svgIcon="red:template"></mat-icon>
{{ dossierTemplateName }}

View File

@ -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() {

View File

@ -20,8 +20,6 @@
<redaction-file-actions
#fileActions
(ocredFile)="ocredFile()"
(toggleViewDocumentInfo)="toggleViewDocumentInfo()"
[activeDocumentInfo]="viewDocumentInfo"
[file]="file"
type="file-preview"
></redaction-file-actions>
@ -81,15 +79,15 @@
<div class="right-container">
<iqser-empty-state
*ngIf="file.excluded && !viewDocumentInfo && excludedPagesService.hidden$ | async"
*ngIf="file.excluded && (documentInfoService.hidden$ | async) && excludedPagesService.hidden$ | async"
[horizontalPadding]="40"
[text]="'file-preview.tabs.is-excluded' | translate"
icon="red:needs-work"
></iqser-empty-state>
<redaction-document-info
(closeDocumentInfoView)="viewDocumentInfo = false"
*ngIf="viewDocumentInfo"
*ngIf="viewDocumentInfo$ | async"
[dossier]="dossier"
[file]="fileData.file"
></redaction-document-info>

View File

@ -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<boolean>;
readonly dossier$: Observable<Dossier>;
readonly showExcludedPages$: Observable<boolean>;
readonly viewDocumentInfo$: Observable<boolean>;
readonly file$: Observable<File>;
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[]) {

View File

@ -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<boolean>;
readonly hidden$: Observable<boolean>;
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],
}));
}
}

View File

@ -62,9 +62,9 @@
></redaction-file-download-btn>
<iqser-circle-button
(action)="toggleViewDocumentInfo.emit()"
*ngIf="showDocumentInfo"
[attr.aria-expanded]="activeDocumentInfo"
(action)="documentInfoService.toggle()"
*ngIf="documentInfoService"
[attr.aria-expanded]="documentInfoService.shown$ | async"
[tooltip]="'file-preview.document-info' | translate"
icon="red:status-info"
tooltipPosition="below"
@ -72,7 +72,7 @@
<iqser-circle-button
(action)="excludedPagesService.toggle()"
*ngIf="excludedPagesService && showExcludePages"
*ngIf="excludedPagesService"
[attr.aria-expanded]="excludedPagesService.shown$ | async"
[showDot]="!!file.excludedPages?.length"
[tooltip]="'file-preview.exclude-pages' | translate"

View File

@ -24,6 +24,7 @@ import { ReanalysisService } from '@services/reanalysis.service';
import { Router } from '@angular/router';
import { ExcludedPagesService } from '../../../screens/file-preview-screen/services/excluded-pages.service';
import { tap } from 'rxjs/operators';
import { DocumentInfoService } from '../../../screens/file-preview-screen/services/document-info.service';
@Component({
selector: 'redaction-file-actions',
@ -36,7 +37,6 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
readonly currentUser = this._userService.currentUser;
@Input() file: File;
@Input() activeDocumentInfo: boolean;
@Input() @Required() type: 'file-preview' | 'dossier-overview-list' | 'dossier-overview-workflow';
@Output() readonly ocredFile = new EventEmitter<void>();
@ -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<void>();
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() {