add document info service
This commit is contained in:
parent
608c43cfe1
commit
94482dc35d
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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 }}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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[]) {
|
||||
|
||||
@ -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],
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -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"
|
||||
|
||||
@ -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() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user