FileStatusWrapper => File
This commit is contained in:
parent
0222d01e5d
commit
11f804c526
@ -1,5 +1,5 @@
|
||||
import { RedactionChangeLog, RedactionLog, ViewedPages } from '@redaction/red-ui-http';
|
||||
import { FileStatusWrapper } from './file-status.wrapper';
|
||||
import { File } from './file';
|
||||
import { AnnotationWrapper } from './annotation.wrapper';
|
||||
import { RedactionLogEntryWrapper } from './redaction-log-entry.wrapper';
|
||||
import { ViewMode } from './view-mode';
|
||||
@ -13,7 +13,7 @@ export class AnnotationData {
|
||||
|
||||
export class FileDataModel {
|
||||
constructor(
|
||||
public fileStatus: FileStatusWrapper,
|
||||
public file: File,
|
||||
public fileData: Blob,
|
||||
public redactionLog: RedactionLog,
|
||||
public redactionChangeLog: RedactionChangeLog,
|
||||
@ -29,7 +29,7 @@ export class FileDataModel {
|
||||
const entries: RedactionLogEntryWrapper[] = this._convertData();
|
||||
let allAnnotations = entries
|
||||
.map(entry => AnnotationWrapper.fromData(entry))
|
||||
.filter(ann => !this.fileStatus.excludedPages.includes(ann.pageNumber));
|
||||
.filter(ann => !this.file.excludedPages.includes(ann.pageNumber));
|
||||
|
||||
if (!areDevFeaturesEnabled) {
|
||||
allAnnotations = allAnnotations.filter(annotation => !annotation.isFalsePositive);
|
||||
|
||||
@ -1,106 +0,0 @@
|
||||
import { IListable } from '@iqser/common-ui';
|
||||
import { FileAttributesConfig, FileStatus } from '@redaction/red-ui-http';
|
||||
import { StatusSorter } from '@utils/sorters/status-sorter';
|
||||
|
||||
const processingStatuses = [
|
||||
FileStatus.StatusEnum.REPROCESS,
|
||||
FileStatus.StatusEnum.FULLREPROCESS,
|
||||
FileStatus.StatusEnum.OCRPROCESSING,
|
||||
FileStatus.StatusEnum.INDEXING,
|
||||
FileStatus.StatusEnum.PROCESSING
|
||||
] as const;
|
||||
|
||||
export class FileStatusWrapper implements FileStatus, IListable {
|
||||
readonly added = this.fileStatus.added;
|
||||
readonly allManualRedactionsApplied = this.fileStatus.allManualRedactionsApplied;
|
||||
readonly analysisDuration = this.fileStatus.analysisDuration;
|
||||
readonly analysisRequired = this.fileStatus.analysisRequired && !this.fileStatus.excluded;
|
||||
readonly approvalDate = this.fileStatus.approvalDate;
|
||||
readonly currentReviewer = this.fileStatus.currentReviewer;
|
||||
readonly dictionaryVersion = this.fileStatus.dictionaryVersion;
|
||||
readonly dossierDictionaryVersion = this.fileStatus.dossierDictionaryVersion;
|
||||
readonly dossierId = this.fileStatus.dossierId;
|
||||
readonly excluded = this.fileStatus.excluded;
|
||||
readonly fileAttributes = this.fileStatus.fileAttributes;
|
||||
readonly fileId = this.fileStatus.fileId;
|
||||
readonly filename = this.fileStatus.filename;
|
||||
readonly hasAnnotationComments = this.fileStatus.hasAnnotationComments;
|
||||
readonly hasHints = this.fileStatus.hasHints;
|
||||
readonly hasImages = this.fileStatus.hasImages;
|
||||
readonly hasRedactions = this.fileStatus.hasRedactions;
|
||||
readonly hasUpdates = this.fileStatus.hasUpdates;
|
||||
readonly lastOCRTime = this.fileStatus.lastOCRTime;
|
||||
readonly lastProcessed = this.fileStatus.lastProcessed;
|
||||
readonly lastReviewer = this.fileStatus.lastReviewer;
|
||||
readonly lastUpdated = this.fileStatus.lastUpdated;
|
||||
readonly lastUploaded = this.fileStatus.lastUploaded;
|
||||
readonly legalBasisVersion = this.fileStatus.legalBasisVersion;
|
||||
readonly numberOfAnalyses = this.fileStatus.numberOfAnalyses;
|
||||
readonly numberOfPages = this.fileStatus.numberOfPages;
|
||||
readonly rulesVersion = this.fileStatus.rulesVersion;
|
||||
readonly status = this._status;
|
||||
readonly uploader = this.fileStatus.uploader;
|
||||
readonly excludedPages = this.fileStatus.excludedPages;
|
||||
readonly hasSuggestions = this.fileStatus.hasSuggestions;
|
||||
readonly dossierTemplateId = this.fileStatus.dossierTemplateId;
|
||||
|
||||
primaryAttribute: string;
|
||||
lastOpened: boolean;
|
||||
|
||||
constructor(readonly fileStatus: FileStatus, public reviewerName: string, fileAttributesConfig?: FileAttributesConfig) {
|
||||
if (fileAttributesConfig) {
|
||||
const primary = fileAttributesConfig.fileAttributeConfigs?.find(c => c.primaryAttribute);
|
||||
if (primary && fileStatus.fileAttributes?.attributeIdToValue) {
|
||||
this.primaryAttribute = fileStatus.fileAttributes?.attributeIdToValue[primary.id];
|
||||
}
|
||||
|
||||
if (!this.primaryAttribute) {
|
||||
// Fallback here
|
||||
this.primaryAttribute = '-';
|
||||
}
|
||||
}
|
||||
if (!this.fileAttributes || !this.fileAttributes.attributeIdToValue) {
|
||||
this.fileAttributes = { attributeIdToValue: {} };
|
||||
}
|
||||
}
|
||||
|
||||
readonly statusSort = StatusSorter[this.status];
|
||||
readonly pages = this._pages;
|
||||
readonly cacheIdentifier = btoa(this.lastUploaded + this.lastOCRTime);
|
||||
|
||||
readonly hintsOnly = this.hasHints && !this.hasRedactions;
|
||||
readonly hasNone = !this.hasRedactions && !this.hasHints && !this.hasSuggestions;
|
||||
|
||||
readonly isUnassigned = !this.currentReviewer;
|
||||
readonly isError = this.status === FileStatus.StatusEnum.ERROR;
|
||||
readonly isProcessing = processingStatuses.includes(this.status);
|
||||
readonly isApproved = this.status === FileStatus.StatusEnum.APPROVED;
|
||||
readonly isPending = this.status === FileStatus.StatusEnum.UNPROCESSED;
|
||||
readonly isUnderReview = this.status === FileStatus.StatusEnum.UNDERREVIEW;
|
||||
readonly isUnderApproval = this.status === FileStatus.StatusEnum.UNDERAPPROVAL;
|
||||
readonly canBeApproved = !this.analysisRequired && !this.hasSuggestions;
|
||||
readonly canBeOpened = !this.isError && !this.isPending;
|
||||
readonly isWorkable = !this.isProcessing && this.canBeOpened;
|
||||
readonly canBeOCRed = !this.excluded && !this.lastOCRTime && ['UNASSIGNED', 'UNDER_REVIEW', 'UNDER_APPROVAL'].includes(this.status);
|
||||
|
||||
get id(): string {
|
||||
return this.fileId;
|
||||
}
|
||||
|
||||
get searchKey(): string {
|
||||
return this.filename;
|
||||
}
|
||||
|
||||
private get _pages() {
|
||||
if (this.fileStatus.status === 'ERROR') {
|
||||
return -1;
|
||||
}
|
||||
return this.fileStatus.numberOfPages ? this.fileStatus.numberOfPages : 0;
|
||||
}
|
||||
|
||||
private get _status(): FileStatus.StatusEnum {
|
||||
return this.fileStatus.status === FileStatus.StatusEnum.REPROCESS || this.fileStatus.status === FileStatus.StatusEnum.FULLREPROCESS
|
||||
? FileStatus.StatusEnum.PROCESSING
|
||||
: this.fileStatus.status;
|
||||
}
|
||||
}
|
||||
138
apps/red-ui/src/app/models/file/file.ts
Normal file
138
apps/red-ui/src/app/models/file/file.ts
Normal file
@ -0,0 +1,138 @@
|
||||
import { IListable } from '@iqser/common-ui';
|
||||
import { FileAttributes, FileAttributesConfig, FileStatus, FileStatuses, IFile, List } from '@redaction/red-ui-http';
|
||||
import { StatusSorter } from '@utils/sorters/status-sorter';
|
||||
|
||||
const processingStatuses: List<FileStatus> = [
|
||||
FileStatuses.REPROCESS,
|
||||
FileStatuses.FULLREPROCESS,
|
||||
FileStatuses.OCR_PROCESSING,
|
||||
FileStatuses.INDEXING,
|
||||
FileStatuses.PROCESSING
|
||||
] as const;
|
||||
|
||||
export class File implements IFile, IListable {
|
||||
readonly added: string;
|
||||
readonly allManualRedactionsApplied: boolean;
|
||||
readonly analysisDuration: number;
|
||||
readonly analysisRequired: boolean;
|
||||
readonly approvalDate: string;
|
||||
readonly currentReviewer: string;
|
||||
readonly dictionaryVersion: number;
|
||||
readonly dossierDictionaryVersion: number;
|
||||
readonly dossierId: string;
|
||||
readonly excluded: boolean;
|
||||
readonly fileAttributes: FileAttributes;
|
||||
readonly fileId: string;
|
||||
readonly filename: string;
|
||||
readonly hasAnnotationComments: boolean;
|
||||
readonly hasHints: boolean;
|
||||
readonly hasImages: boolean;
|
||||
readonly hasRedactions: boolean;
|
||||
readonly hasUpdates: boolean;
|
||||
readonly lastOCRTime: string;
|
||||
readonly lastProcessed: string;
|
||||
readonly lastReviewer: string;
|
||||
readonly lastUpdated: string;
|
||||
readonly lastUploaded: string;
|
||||
readonly legalBasisVersion: number;
|
||||
readonly numberOfAnalyses: number;
|
||||
readonly numberOfPages: number;
|
||||
readonly rulesVersion: number;
|
||||
readonly status: FileStatus;
|
||||
readonly uploader: string;
|
||||
readonly excludedPages: number[];
|
||||
readonly hasSuggestions: boolean;
|
||||
readonly dossierTemplateId: string;
|
||||
|
||||
primaryAttribute: string;
|
||||
lastOpened: boolean;
|
||||
readonly statusSort: number;
|
||||
readonly cacheIdentifier: string;
|
||||
readonly hintsOnly: boolean;
|
||||
readonly hasNone: boolean;
|
||||
readonly isUnassigned: boolean;
|
||||
readonly isError: boolean;
|
||||
readonly isProcessing: boolean;
|
||||
readonly isApproved: boolean;
|
||||
readonly isPending: boolean;
|
||||
readonly isUnderReview: boolean;
|
||||
readonly isUnderApproval: boolean;
|
||||
readonly canBeApproved: boolean;
|
||||
readonly canBeOpened: boolean;
|
||||
readonly isWorkable: boolean;
|
||||
readonly canBeOCRed: boolean;
|
||||
|
||||
constructor(file: IFile, public reviewerName: string, fileAttributesConfig?: FileAttributesConfig) {
|
||||
this.added = file.added;
|
||||
this.allManualRedactionsApplied = file.allManualRedactionsApplied;
|
||||
this.analysisDuration = file.analysisDuration;
|
||||
this.analysisRequired = file.analysisRequired && !file.excluded;
|
||||
this.approvalDate = file.approvalDate;
|
||||
this.currentReviewer = file.currentReviewer;
|
||||
this.dictionaryVersion = file.dictionaryVersion;
|
||||
this.dossierDictionaryVersion = file.dossierDictionaryVersion;
|
||||
this.dossierId = file.dossierId;
|
||||
this.excluded = file.excluded;
|
||||
this.fileAttributes = file.fileAttributes;
|
||||
this.fileId = file.fileId;
|
||||
this.filename = file.filename;
|
||||
this.hasAnnotationComments = file.hasAnnotationComments;
|
||||
this.hasHints = file.hasHints;
|
||||
this.hasImages = file.hasImages;
|
||||
this.hasRedactions = file.hasRedactions;
|
||||
this.hasUpdates = file.hasUpdates;
|
||||
this.lastOCRTime = file.lastOCRTime;
|
||||
this.lastProcessed = file.lastProcessed;
|
||||
this.lastReviewer = file.lastReviewer;
|
||||
this.lastUpdated = file.lastUpdated;
|
||||
this.lastUploaded = file.lastUploaded;
|
||||
this.legalBasisVersion = file.legalBasisVersion;
|
||||
this.numberOfAnalyses = file.numberOfAnalyses;
|
||||
this.status = ['REPROCESS', 'FULLREPROCESS'].includes(file.status) ? FileStatuses.PROCESSING : file.status;
|
||||
this.isError = this.status === FileStatuses.ERROR;
|
||||
this.numberOfPages = this.isError ? -1 : file.numberOfPages ?? 0;
|
||||
this.rulesVersion = file.rulesVersion;
|
||||
this.uploader = file.uploader;
|
||||
this.excludedPages = file.excludedPages;
|
||||
this.hasSuggestions = file.hasSuggestions;
|
||||
this.dossierTemplateId = file.dossierTemplateId;
|
||||
|
||||
this.statusSort = StatusSorter[this.status];
|
||||
this.cacheIdentifier = btoa(this.lastUploaded + this.lastOCRTime);
|
||||
this.hintsOnly = this.hasHints && !this.hasRedactions;
|
||||
this.hasNone = !this.hasRedactions && !this.hasHints && !this.hasSuggestions;
|
||||
this.isUnassigned = !this.currentReviewer;
|
||||
this.isProcessing = processingStatuses.includes(this.status);
|
||||
this.isApproved = this.status === FileStatuses.APPROVED;
|
||||
this.isPending = this.status === FileStatuses.UNPROCESSED;
|
||||
this.isUnderReview = this.status === FileStatuses.UNDER_REVIEW;
|
||||
this.isUnderApproval = this.status === FileStatuses.UNDER_APPROVAL;
|
||||
this.canBeApproved = !this.analysisRequired && !this.hasSuggestions;
|
||||
this.canBeOpened = !this.isError && !this.isPending;
|
||||
this.isWorkable = !this.isProcessing && this.canBeOpened;
|
||||
this.canBeOCRed = !this.excluded && !this.lastOCRTime && ['UNASSIGNED', 'UNDER_REVIEW', 'UNDER_APPROVAL'].includes(this.status);
|
||||
|
||||
if (fileAttributesConfig) {
|
||||
const primary = fileAttributesConfig.fileAttributeConfigs?.find(c => c.primaryAttribute);
|
||||
if (primary && file.fileAttributes?.attributeIdToValue) {
|
||||
this.primaryAttribute = file.fileAttributes?.attributeIdToValue[primary.id];
|
||||
}
|
||||
|
||||
if (!this.primaryAttribute) {
|
||||
// Fallback here
|
||||
this.primaryAttribute = '-';
|
||||
}
|
||||
}
|
||||
if (!this.fileAttributes || !this.fileAttributes.attributeIdToValue) {
|
||||
this.fileAttributes = { attributeIdToValue: {} };
|
||||
}
|
||||
}
|
||||
|
||||
get id(): string {
|
||||
return this.fileId;
|
||||
}
|
||||
|
||||
get searchKey(): string {
|
||||
return this.filename;
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@ import { Component, EventEmitter, Output } from '@angular/core';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { FileManagementControllerService, ReanalysisControllerService } from '@redaction/red-ui-http';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { FileActionService } from '../../services/file-action.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||
@ -19,8 +19,7 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
export class DossierOverviewBulkActionsComponent {
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
|
||||
@Output()
|
||||
reload = new EventEmitter();
|
||||
@Output() readonly reload = new EventEmitter();
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
@ -31,14 +30,14 @@ export class DossierOverviewBulkActionsComponent {
|
||||
private readonly _fileActionService: FileActionService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _entitiesService: EntitiesService<FileStatusWrapper>
|
||||
private readonly _entitiesService: EntitiesService<File>
|
||||
) {}
|
||||
|
||||
get dossier() {
|
||||
return this._appStateService?.activeDossier;
|
||||
}
|
||||
|
||||
get selectedFiles(): FileStatusWrapper[] {
|
||||
get selectedFiles(): File[] {
|
||||
return this._entitiesService.selected;
|
||||
}
|
||||
|
||||
@ -91,21 +90,18 @@ export class DossierOverviewBulkActionsComponent {
|
||||
return this.selectedFiles.reduce((acc, file) => acc && file.canBeOCRed, true);
|
||||
}
|
||||
|
||||
get fileStatuses() {
|
||||
return this.selectedFiles.map(file => file.fileStatus.status);
|
||||
get files() {
|
||||
return this.selectedFiles.map(file => file.status);
|
||||
}
|
||||
|
||||
// Under review
|
||||
get canSetToUnderReview() {
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canSetUnderReview(file), true);
|
||||
}
|
||||
|
||||
// Under approval
|
||||
get canSetToUnderApproval() {
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canSetUnderApproval(file), true);
|
||||
}
|
||||
|
||||
// Approve
|
||||
get isReadyForApproval() {
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.isReadyForApproval(file), true);
|
||||
}
|
||||
@ -114,7 +110,6 @@ export class DossierOverviewBulkActionsComponent {
|
||||
return this.selectedFiles.reduce((acc, file) => acc && file.canBeApproved, true);
|
||||
}
|
||||
|
||||
// Undo approval
|
||||
get canUndoApproval() {
|
||||
return this.selectedFiles.reduce((acc, file) => acc && this._permissionsService.canUndoApproval(file), true);
|
||||
}
|
||||
@ -156,7 +151,7 @@ export class DossierOverviewBulkActionsComponent {
|
||||
this._assignFiles('approver', true);
|
||||
} else {
|
||||
this._performBulkAction(
|
||||
this._fileActionService.setFileUnderApproval(this.selectedFiles, this._appStateService.activeDossier.approverIds[0])
|
||||
this._fileActionService.setFilesUnderApproval(this.selectedFiles, this._appStateService.activeDossier.approverIds[0])
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -169,11 +164,11 @@ export class DossierOverviewBulkActionsComponent {
|
||||
}
|
||||
|
||||
ocr() {
|
||||
this._performBulkAction(this._fileActionService.ocrFile(this.selectedFiles));
|
||||
this._performBulkAction(this._fileActionService.ocrFiles(this.selectedFiles));
|
||||
}
|
||||
|
||||
setToUnderReview() {
|
||||
this._performBulkAction(this._fileActionService.setFileUnderReview(this.selectedFiles));
|
||||
this._performBulkAction(this._fileActionService.setFilesUnderReview(this.selectedFiles));
|
||||
}
|
||||
|
||||
approveDocuments() {
|
||||
@ -187,11 +182,11 @@ export class DossierOverviewBulkActionsComponent {
|
||||
question: _('confirmation-dialog.approve-multiple-files.question')
|
||||
}),
|
||||
() => {
|
||||
this._performBulkAction(this._fileActionService.setFileApproved(this.selectedFiles));
|
||||
this._performBulkAction(this._fileActionService.setFilesApproved(this.selectedFiles));
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this._performBulkAction(this._fileActionService.setFileApproved(this.selectedFiles));
|
||||
this._performBulkAction(this._fileActionService.setFilesApproved(this.selectedFiles));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import { FileAttributesConfig } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||
import { AutoUnsubscribe } from '@iqser/common-ui';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-document-info',
|
||||
@ -11,7 +11,7 @@ import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
styleUrls: ['./document-info.component.scss']
|
||||
})
|
||||
export class DocumentInfoComponent extends AutoUnsubscribe implements OnInit {
|
||||
@Input() file: FileStatusWrapper;
|
||||
@Input() file: File;
|
||||
@Output() closeDocumentInfoView = new EventEmitter();
|
||||
|
||||
fileAttributesConfig: FileAttributesConfig;
|
||||
|
||||
@ -7,8 +7,8 @@
|
||||
<ng-container *ngTemplateOutlet="actions"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #actions redactionLongPress (longPress)="forceReanalysisAction($event)">
|
||||
<div *ngIf="fileStatus" class="file-actions">
|
||||
<ng-template #actions (longPress)="forceReanalysisAction($event)" redactionLongPress>
|
||||
<div *ngIf="file" class="file-actions">
|
||||
<iqser-circle-button
|
||||
(action)="openDocument()"
|
||||
*ngIf="showOpenDocument"
|
||||
@ -48,7 +48,7 @@
|
||||
<!-- download redacted file-->
|
||||
<redaction-file-download-btn
|
||||
[dossier]="appStateService.activeDossier"
|
||||
[file]="fileStatus"
|
||||
[file]="file"
|
||||
[tooltipClass]="'small'"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[type]="buttonType"
|
||||
@ -67,7 +67,7 @@
|
||||
(action)="toggleExcludePages()"
|
||||
*ngIf="showExcludePages"
|
||||
[attr.aria-expanded]="activeExcludePages"
|
||||
[showDot]="!!fileStatus.excludedPages?.length"
|
||||
[showDot]="!!file.excludedPages?.length"
|
||||
[tooltip]="'file-preview.exclude-pages' | translate"
|
||||
icon="red:exclude-pages"
|
||||
tooltipPosition="below"
|
||||
@ -99,9 +99,7 @@
|
||||
*ngIf="showApprove"
|
||||
[disabled]="!fileStatus.canBeApproved"
|
||||
[tooltipPosition]="tooltipPosition"
|
||||
[tooltip]="
|
||||
fileStatus.canBeApproved ? ('dossier-overview.approve' | translate) : ('dossier-overview.approve-disabled' | translate)
|
||||
"
|
||||
[tooltip]="file.canBeApproved ? ('dossier-overview.approve' | translate) : ('dossier-overview.approve-disabled' | translate)"
|
||||
[type]="buttonType"
|
||||
icon="red:approved"
|
||||
></iqser-circle-button>
|
||||
@ -150,7 +148,7 @@
|
||||
<mat-slide-toggle
|
||||
(change)="toggleAnalysis()"
|
||||
(click)="$event.stopPropagation()"
|
||||
[checked]="!fileStatus?.excluded"
|
||||
[checked]="!file?.excluded"
|
||||
[class.mr-24]="isDossierOverviewList"
|
||||
[disabled]="!canToggleAnalysis"
|
||||
[matTooltipPosition]="tooltipPosition"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { FileActionService } from '../../services/file-action.service';
|
||||
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||
@ -10,8 +10,8 @@ import { FileManagementControllerService, FileStatus } from '@redaction/red-ui-h
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { UserPreferenceService } from '../../../../services/user-preference.service';
|
||||
import { LongPressEvent } from '../../../shared/directives/long-press.directive';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { LongPressEvent } from '@shared/directives/long-press.directive';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-actions',
|
||||
@ -22,13 +22,13 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
|
||||
@Input() fileStatus: FileStatusWrapper;
|
||||
@Input() file: File;
|
||||
@Input() activeDocumentInfo: boolean;
|
||||
@Input() activeExcludePages: boolean;
|
||||
@Input() @Required() type: 'file-preview' | 'dossier-overview-list' | 'dossier-overview-workflow';
|
||||
@Output() actionPerformed = new EventEmitter<string>();
|
||||
@Output() readonly actionPerformed = new EventEmitter<string>();
|
||||
|
||||
statusBarConfig?: readonly StatusBarConfig<FileStatus.StatusEnum>[];
|
||||
statusBarConfig?: readonly StatusBarConfig<FileStatus>[];
|
||||
tooltipPosition?: 'below' | 'above';
|
||||
toggleTooltip?: string;
|
||||
assignTooltip?: string;
|
||||
@ -84,7 +84,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
return _('file-preview.toggle-analysis.only-managers');
|
||||
}
|
||||
|
||||
return this.fileStatus?.excluded ? _('file-preview.toggle-analysis.enable') : _('file-preview.toggle-analysis.disable');
|
||||
return this.file?.excluded ? _('file-preview.toggle-analysis.enable') : _('file-preview.toggle-analysis.disable');
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
@ -92,12 +92,10 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
this.fileStatus = this.appStateService.activeFile;
|
||||
}
|
||||
this._setup();
|
||||
this.addSubscription = this.appStateService.fileChanged$
|
||||
.pipe(filter(file => file.fileId === this.fileStatus?.fileId))
|
||||
.subscribe(fileStatus => {
|
||||
this.fileStatus = fileStatus;
|
||||
this._setup();
|
||||
});
|
||||
this.addSubscription = this.appStateService.fileChanged$.pipe(filter(file => file.fileId === this.file?.fileId)).subscribe(file => {
|
||||
this.file = file;
|
||||
this._setup();
|
||||
});
|
||||
|
||||
this.addSubscription = this.appStateService.dossierChanged$.subscribe(() => {
|
||||
this._setup();
|
||||
@ -127,7 +125,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
async () => {
|
||||
this._loadingService.start();
|
||||
await this._fileManagementControllerService
|
||||
.deleteFiles([this.fileStatus.fileId], this.fileStatus.dossierId)
|
||||
.deleteFiles([this.file.fileId], this.file.dossierId)
|
||||
.toPromise()
|
||||
.catch(error => {
|
||||
this._toaster.error(_('error.http.generic'), { params: error });
|
||||
@ -140,8 +138,8 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
}
|
||||
|
||||
assign($event: MouseEvent) {
|
||||
const mode = this.fileStatus.isUnderApproval ? 'approver' : 'reviewer';
|
||||
const files = [this.fileStatus];
|
||||
const mode = this.file.isUnderApproval ? 'approver' : 'reviewer';
|
||||
const files = [this.file];
|
||||
this._dialogService.openDialog('assignFile', $event, { mode, files }, () => {
|
||||
this.actionPerformed.emit('assign-reviewer');
|
||||
});
|
||||
@ -150,7 +148,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
async assignToMe($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
|
||||
await this._fileActionService.assignToMe(this.fileStatus, () => {
|
||||
await this._fileActionService.assignToMe([this.file], () => {
|
||||
this.reloadDossiers('reanalyse');
|
||||
});
|
||||
}
|
||||
@ -159,7 +157,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
if ($event) {
|
||||
$event.stopPropagation();
|
||||
}
|
||||
this.addSubscription = this._fileActionService.reanalyseFile(this.fileStatus).subscribe(() => {
|
||||
this.addSubscription = this._fileActionService.reanalyseFile(this.file).subscribe(() => {
|
||||
this.reloadDossiers('reanalyse');
|
||||
});
|
||||
}
|
||||
@ -167,9 +165,9 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
setFileUnderApproval($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
if (this.appStateService.activeDossier.approverIds.length > 1) {
|
||||
this._fileActionService.assignFile('approver', $event, this.fileStatus, () => this.reloadDossiers('assign-reviewer'), true);
|
||||
this._fileActionService.assignFile('approver', $event, this.file, () => this.reloadDossiers('assign-reviewer'), true);
|
||||
} else {
|
||||
this.addSubscription = this._fileActionService.setFileUnderApproval(this.fileStatus).subscribe(() => {
|
||||
this.addSubscription = this._fileActionService.setFilesUnderApproval([this.file]).subscribe(() => {
|
||||
this.reloadDossiers('set-under-approval');
|
||||
});
|
||||
}
|
||||
@ -177,7 +175,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
|
||||
setFileApproved($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
if (this.fileStatus.hasUpdates) {
|
||||
if (this.file.hasUpdates) {
|
||||
this._dialogService.openDialog(
|
||||
'confirm',
|
||||
$event,
|
||||
@ -196,7 +194,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
|
||||
ocrFile($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
this.addSubscription = this._fileActionService.ocrFile(this.fileStatus).subscribe(() => {
|
||||
this.addSubscription = this._fileActionService.ocrFiles([this.file]).subscribe(() => {
|
||||
this.reloadDossiers('ocr-file');
|
||||
});
|
||||
}
|
||||
@ -205,7 +203,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
this._fileActionService.assignFile(
|
||||
'reviewer',
|
||||
$event,
|
||||
this.fileStatus,
|
||||
this.file,
|
||||
() => this.reloadDossiers('assign-reviewer'),
|
||||
ignoreDialogChanges
|
||||
);
|
||||
@ -218,9 +216,9 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
}
|
||||
|
||||
async toggleAnalysis() {
|
||||
await this._fileActionService.toggleAnalysis(this.fileStatus).toPromise();
|
||||
await this._fileActionService.toggleAnalysis(this.file).toPromise();
|
||||
await this.appStateService.getFiles();
|
||||
this.actionPerformed.emit(this.fileStatus?.excluded ? 'enable-analysis' : 'disable-analysis');
|
||||
this.actionPerformed.emit(this.file?.excluded ? 'enable-analysis' : 'disable-analysis');
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
@ -231,12 +229,12 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnInit, OnD
|
||||
|
||||
forceReanalysisAction($event: LongPressEvent) {
|
||||
if (this._userPreferenceService.areDevFeaturesEnabled) {
|
||||
this.canReanalyse = $event.touchEnd ? this.permissionsService.canReanalyseFile(this.fileStatus) : true;
|
||||
this.canReanalyse = $event.touchEnd ? this.permissionsService.canReanalyseFile(this.file) : true;
|
||||
}
|
||||
}
|
||||
|
||||
private _setFileApproved() {
|
||||
this.addSubscription = this._fileActionService.setFileApproved(this.fileStatus).subscribe(() => {
|
||||
this.addSubscription = this._fileActionService.setFilesApproved([this.file]).subscribe(() => {
|
||||
this.reloadDossiers('set-approved');
|
||||
});
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@
|
||||
</div>
|
||||
<div
|
||||
(click)="scrollQuickNavLast()"
|
||||
[class.disabled]="activeViewerPage === fileData?.fileStatus?.numberOfPages"
|
||||
[class.disabled]="activeViewerPage === fileData?.file?.numberOfPages"
|
||||
[matTooltip]="'file-preview.quick-nav.jump-last' | translate"
|
||||
class="jump"
|
||||
matTooltipPosition="above"
|
||||
@ -141,7 +141,7 @@
|
||||
[verticalPadding]="40"
|
||||
icon="red:document"
|
||||
>
|
||||
<ng-container *ngIf="fileData?.fileStatus?.excludedPages?.includes(activeViewerPage)">
|
||||
<ng-container *ngIf="fileData?.file?.excludedPages?.includes(activeViewerPage)">
|
||||
{{ 'file-preview.tabs.annotations.page-is' | translate }}
|
||||
<a
|
||||
(click)="actionPerformed.emit('view-exclude-pages')"
|
||||
@ -171,15 +171,15 @@
|
||||
</ng-container>
|
||||
|
||||
<redaction-annotations-list
|
||||
[canMultiSelect]="!isReadOnly"
|
||||
[annotations]="(displayedAnnotations$ | async)?.get(activeViewerPage)"
|
||||
[selectedAnnotations]="selectedAnnotations"
|
||||
[annotationActionsTemplate]="annotationActionsTemplate"
|
||||
[(multiSelectActive)]="multiSelectActive"
|
||||
[activeViewerPage]="activeViewerPage"
|
||||
(deselectAnnotations)="deselectAnnotations.emit($event)"
|
||||
(pagesPanelActive)="pagesPanelActive = $event"
|
||||
(selectAnnotations)="selectAnnotations.emit($event)"
|
||||
(deselectAnnotations)="deselectAnnotations.emit($event)"
|
||||
[(multiSelectActive)]="multiSelectActive"
|
||||
[activeViewerPage]="activeViewerPage"
|
||||
[annotationActionsTemplate]="annotationActionsTemplate"
|
||||
[annotations]="(displayedAnnotations$ | async)?.get(activeViewerPage)"
|
||||
[canMultiSelect]="!isReadOnly"
|
||||
[selectedAnnotations]="selectedAnnotations"
|
||||
></redaction-annotations-list>
|
||||
</div>
|
||||
</ng-container>
|
||||
@ -187,7 +187,7 @@
|
||||
<redaction-page-exclusion
|
||||
(actionPerformed)="actionPerformed.emit($event)"
|
||||
*ngIf="excludePages"
|
||||
[fileStatus]="fileData.fileStatus"
|
||||
[file]="fileData.file"
|
||||
></redaction-page-exclusion>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -43,8 +43,10 @@ export class FileWorkloadComponent {
|
||||
@Output() readonly actionPerformed = new EventEmitter<string>();
|
||||
displayedPages: number[] = [];
|
||||
pagesPanelActive = true;
|
||||
readonly displayedAnnotations$ = this._displayedAnnotations$;
|
||||
@ViewChild('annotationsElement') private readonly _annotationsElement: ElementRef;
|
||||
@ViewChild('quickNavigation') private readonly _quickNavigationElement: ElementRef;
|
||||
private _annotations$ = new BehaviorSubject<AnnotationWrapper[]>([]);
|
||||
|
||||
constructor(
|
||||
private readonly _permissionsService: PermissionsService,
|
||||
@ -53,9 +55,6 @@ export class FileWorkloadComponent {
|
||||
private readonly _annotationProcessingService: AnnotationProcessingService
|
||||
) {}
|
||||
|
||||
private _annotations$ = new BehaviorSubject<AnnotationWrapper[]>([]);
|
||||
readonly displayedAnnotations$ = this._displayedAnnotations$;
|
||||
|
||||
@Input()
|
||||
set annotations(value: AnnotationWrapper[]) {
|
||||
this._annotations$.next(value);
|
||||
@ -78,7 +77,7 @@ export class FileWorkloadComponent {
|
||||
}
|
||||
|
||||
get isProcessing(): boolean {
|
||||
return this.fileData?.fileStatus?.isProcessing;
|
||||
return this.fileData?.file?.isProcessing;
|
||||
}
|
||||
|
||||
get activeAnnotations(): AnnotationWrapper[] | undefined {
|
||||
@ -93,6 +92,14 @@ export class FileWorkloadComponent {
|
||||
return this.selectedAnnotations?.length ? this.selectedAnnotations[0] : null;
|
||||
}
|
||||
|
||||
private get _displayedAnnotations$(): Observable<Map<number, AnnotationWrapper[]>> {
|
||||
const primary$ = this._filterService.getFilterModels$('primaryFilters');
|
||||
const secondary$ = this._filterService.getFilterModels$('secondaryFilters');
|
||||
return combineLatest([this._annotations$, primary$, secondary$]).pipe(
|
||||
map(([annotations, primary, secondary]) => this._filterAnnotations(annotations, primary, secondary))
|
||||
);
|
||||
}
|
||||
|
||||
private static _scrollToFirstElement(elements: HTMLElement[], mode: 'always' | 'if-needed' = 'if-needed') {
|
||||
if (elements.length > 0) {
|
||||
scrollIntoView(elements[0], {
|
||||
@ -120,19 +127,6 @@ export class FileWorkloadComponent {
|
||||
this.deselectAnnotations.emit(this.activeAnnotations);
|
||||
}
|
||||
|
||||
private _filterAnnotations(
|
||||
annotations: AnnotationWrapper[],
|
||||
primary: INestedFilter[],
|
||||
secondary: INestedFilter[] = []
|
||||
): Map<number, AnnotationWrapper[]> {
|
||||
if (!primary) {
|
||||
return;
|
||||
}
|
||||
this.displayedAnnotations = this._annotationProcessingService.filterAndGroupAnnotations(annotations, primary, secondary);
|
||||
this.displayedPages = [...this.displayedAnnotations.keys()];
|
||||
return this.displayedAnnotations;
|
||||
}
|
||||
|
||||
@HostListener('window:keyup', ['$event'])
|
||||
handleKeyEvent($event: KeyboardEvent): void {
|
||||
if (
|
||||
@ -210,7 +204,7 @@ export class FileWorkloadComponent {
|
||||
}
|
||||
|
||||
scrollQuickNavLast(): void {
|
||||
this.selectPage.emit(this.fileData.fileStatus.numberOfPages);
|
||||
this.selectPage.emit(this.fileData.file.numberOfPages);
|
||||
}
|
||||
|
||||
pageSelectedByClick($event: number): void {
|
||||
@ -232,12 +226,17 @@ export class FileWorkloadComponent {
|
||||
this.selectPage.emit(this._nextPageWithAnnotations());
|
||||
}
|
||||
|
||||
private get _displayedAnnotations$(): Observable<Map<number, AnnotationWrapper[]>> {
|
||||
const primary$ = this._filterService.getFilterModels$('primaryFilters');
|
||||
const secondary$ = this._filterService.getFilterModels$('secondaryFilters');
|
||||
return combineLatest([this._annotations$, primary$, secondary$]).pipe(
|
||||
map(([annotations, primary, secondary]) => this._filterAnnotations(annotations, primary, secondary))
|
||||
);
|
||||
private _filterAnnotations(
|
||||
annotations: AnnotationWrapper[],
|
||||
primary: INestedFilter[],
|
||||
secondary: INestedFilter[] = []
|
||||
): Map<number, AnnotationWrapper[]> {
|
||||
if (!primary) {
|
||||
return;
|
||||
}
|
||||
this.displayedAnnotations = this._annotationProcessingService.filterAndGroupAnnotations(annotations, primary, secondary);
|
||||
this.displayedPages = [...this.displayedAnnotations.keys()];
|
||||
return this.displayedAnnotations;
|
||||
}
|
||||
|
||||
private _selectFirstAnnotationOnCurrentPageIfNecessary() {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { Dossier } from '../../../../state/model/dossier';
|
||||
|
||||
@Component({
|
||||
@ -9,7 +9,7 @@ import { Dossier } from '../../../../state/model/dossier';
|
||||
styleUrls: ['./needs-work-badge.component.scss']
|
||||
})
|
||||
export class NeedsWorkBadgeComponent {
|
||||
@Input() needsWorkInput: FileStatusWrapper | Dossier;
|
||||
@Input() needsWorkInput: File | Dossier;
|
||||
|
||||
constructor(private readonly _appStateService: AppStateService) {}
|
||||
|
||||
@ -38,15 +38,15 @@ export class NeedsWorkBadgeComponent {
|
||||
}
|
||||
|
||||
get hasImages() {
|
||||
return this.needsWorkInput instanceof FileStatusWrapper && this.needsWorkInput.hasImages;
|
||||
return this.needsWorkInput instanceof File && this.needsWorkInput.hasImages;
|
||||
}
|
||||
|
||||
get hasUpdates() {
|
||||
return this.needsWorkInput instanceof FileStatusWrapper && this.needsWorkInput.hasUpdates;
|
||||
return this.needsWorkInput instanceof File && this.needsWorkInput.hasUpdates;
|
||||
}
|
||||
|
||||
get hasAnnotationComments(): boolean {
|
||||
return this.needsWorkInput instanceof FileStatusWrapper && (<any>this.needsWorkInput).hasAnnotationComments;
|
||||
return this.needsWorkInput instanceof File && (<any>this.needsWorkInput).hasAnnotationComments;
|
||||
}
|
||||
|
||||
reanalysisRequired() {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { Component, EventEmitter, Input, OnChanges, Output, ViewChild } from '@angular/core';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { PageRange, ReanalysisControllerService } from '@redaction/red-ui-http';
|
||||
import { InputWithActionComponent, Toaster, LoadingService } from '@iqser/common-ui';
|
||||
import { InputWithActionComponent, LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-page-exclusion',
|
||||
@ -11,7 +11,7 @@ import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
styleUrls: ['./page-exclusion.component.scss']
|
||||
})
|
||||
export class PageExclusionComponent implements OnChanges {
|
||||
@Input() fileStatus: FileStatusWrapper;
|
||||
@Input() file: File;
|
||||
@Output() readonly actionPerformed = new EventEmitter<string>();
|
||||
|
||||
excludedPagesRanges: PageRange[] = [];
|
||||
@ -25,7 +25,7 @@ export class PageExclusionComponent implements OnChanges {
|
||||
) {}
|
||||
|
||||
ngOnChanges(): void {
|
||||
const excludedPages = (this.fileStatus?.excludedPages || []).sort((p1, p2) => p1 - p2);
|
||||
const excludedPages = (this.file?.excludedPages || []).sort((p1, p2) => p1 - p2);
|
||||
this.excludedPagesRanges = excludedPages.reduce((ranges, page) => {
|
||||
if (!ranges.length) {
|
||||
return [{ startPage: page, endPage: page }];
|
||||
@ -60,8 +60,8 @@ export class PageExclusionComponent implements OnChanges {
|
||||
{
|
||||
pageRanges: pageRanges
|
||||
},
|
||||
this.fileStatus.dossierId,
|
||||
this.fileStatus.fileId
|
||||
this.file.dossierId,
|
||||
this.file.fileId
|
||||
)
|
||||
.toPromise();
|
||||
this._inputComponent.reset();
|
||||
@ -79,8 +79,8 @@ export class PageExclusionComponent implements OnChanges {
|
||||
{
|
||||
pageRanges: [range]
|
||||
},
|
||||
this.fileStatus.dossierId,
|
||||
this.fileStatus.fileId
|
||||
this.file.dossierId,
|
||||
this.file.fileId
|
||||
)
|
||||
.toPromise();
|
||||
this._inputComponent.reset();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<div class="page">
|
||||
<div #viewer [id]="fileStatus.fileId" class="viewer"></div>
|
||||
<div #viewer [id]="file.fileId" class="viewer"></div>
|
||||
</div>
|
||||
|
||||
<input #compareFileInput (change)="uploadFile($event.target['files'])" class="file-upload-input" type="file" />
|
||||
|
||||
@ -17,7 +17,7 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { ManualAnnotationService } from '../../services/manual-annotation.service';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { environment } from '@environments/environment';
|
||||
import { AnnotationDrawService } from '../../services/annotation-draw.service';
|
||||
import { AnnotationActionsService } from '../../services/annotation-actions.service';
|
||||
@ -43,18 +43,18 @@ import Annotation = Core.Annotations.Annotation;
|
||||
})
|
||||
export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
@Input() fileData: Blob;
|
||||
@Input() fileStatus: FileStatusWrapper;
|
||||
@Input() file: File;
|
||||
@Input() canPerformActions = false;
|
||||
@Input() annotations: AnnotationWrapper[];
|
||||
@Input() shouldDeselectAnnotationsOnPageChange = true;
|
||||
@Input() multiSelectActive: boolean;
|
||||
@Output() fileReady = new EventEmitter();
|
||||
@Output() annotationSelected = new EventEmitter<string[]>();
|
||||
@Output() manualAnnotationRequested = new EventEmitter<ManualRedactionEntryWrapper>();
|
||||
@Output() pageChanged = new EventEmitter<number>();
|
||||
@Output() keyUp = new EventEmitter<KeyboardEvent>();
|
||||
@Output() viewerReady = new EventEmitter<WebViewerInstance>();
|
||||
@Output() annotationsChanged = new EventEmitter<AnnotationWrapper>();
|
||||
@Output() readonly fileReady = new EventEmitter();
|
||||
@Output() readonly annotationSelected = new EventEmitter<string[]>();
|
||||
@Output() readonly manualAnnotationRequested = new EventEmitter<ManualRedactionEntryWrapper>();
|
||||
@Output() readonly pageChanged = new EventEmitter<number>();
|
||||
@Output() readonly keyUp = new EventEmitter<KeyboardEvent>();
|
||||
@Output() readonly viewerReady = new EventEmitter<WebViewerInstance>();
|
||||
@Output() readonly annotationsChanged = new EventEmitter<AnnotationWrapper>();
|
||||
@ViewChild('viewer', { static: true }) viewer: ElementRef;
|
||||
@ViewChild('compareFileInput', { static: true }) compareFileInput: ElementRef;
|
||||
instance: WebViewerInstance;
|
||||
@ -146,7 +146,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
compareDocument,
|
||||
mergedDocument,
|
||||
this.instance,
|
||||
this.fileStatus,
|
||||
this.file,
|
||||
() => {
|
||||
this.viewMode = 'COMPARE';
|
||||
},
|
||||
@ -188,7 +188,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
await pdfNet.initialize(environment.licenseKey ? atob(environment.licenseKey) : null);
|
||||
const currentDocument = await pdfNet.PDFDoc.createFromBuffer(await this.fileData.arrayBuffer());
|
||||
this.instance.UI.loadDocument(currentDocument, {
|
||||
filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf'
|
||||
filename: this.file ? this.file.filename : 'document.pdf'
|
||||
});
|
||||
this.instance.UI.disableElements(['closeCompareButton']);
|
||||
this.instance.UI.enableElements(['compareButton']);
|
||||
@ -571,7 +571,7 @@ export class PdfViewerComponent implements OnInit, OnChanges {
|
||||
private _loadDocument() {
|
||||
if (this.fileData) {
|
||||
this.instance.UI.loadDocument(this.fileData, {
|
||||
filename: this.fileStatus ? this.fileStatus.filename : 'document.pdf'
|
||||
filename: this.file ? this.file.filename : 'document.pdf'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,14 +5,14 @@ import { AppStateService } from '@state/app-state.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { Toaster } from '@iqser/common-ui';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { Dossier } from '../../../../state/model/dossier';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
class DialogData {
|
||||
mode: 'approver' | 'reviewer';
|
||||
dossier?: Dossier;
|
||||
files?: FileStatusWrapper[];
|
||||
files?: File[];
|
||||
ignoreChanged?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { FileAttributesControllerService, FileStatus, IFileAttributeConfig } from '@redaction/red-ui-http';
|
||||
import { FileAttributesControllerService, IFile, IFileAttributeConfig } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Dossier } from '../../../../state/model/dossier';
|
||||
import { Dossier } from '@state/model/dossier';
|
||||
|
||||
@Component({
|
||||
templateUrl: './document-info-dialog.component.html',
|
||||
@ -11,7 +11,7 @@ import { Dossier } from '../../../../state/model/dossier';
|
||||
})
|
||||
export class DocumentInfoDialogComponent implements OnInit {
|
||||
documentInfoForm: FormGroup;
|
||||
file: FileStatus;
|
||||
file: IFile;
|
||||
attributes: IFileAttributeConfig[];
|
||||
|
||||
private _dossier: Dossier;
|
||||
@ -21,7 +21,7 @@ export class DocumentInfoDialogComponent implements OnInit {
|
||||
private readonly _formBuilder: FormBuilder,
|
||||
private readonly _fileAttributesService: FileAttributesControllerService,
|
||||
public dialogRef: MatDialogRef<DocumentInfoDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: FileStatus
|
||||
@Inject(MAT_DIALOG_DATA) public data: IFile
|
||||
) {
|
||||
this.file = this.data;
|
||||
this._dossier = this._appStateService.getDossierById(this.file.dossierId);
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
SortingOrders,
|
||||
TableColumnConfig
|
||||
} from '@iqser/common-ui';
|
||||
import { FileManagementControllerService, FileStatus, StatusControllerService } from '@redaction/red-ui-http';
|
||||
import { FileManagementControllerService, IFile, StatusControllerService } from '@redaction/red-ui-http';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import * as moment from 'moment';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
@ -21,7 +21,7 @@ import { ConfirmationDialogInput, TitleColors } from '@shared/dialogs/confirmati
|
||||
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
|
||||
interface FileListItem extends FileStatus, IListable {
|
||||
interface FileListItem extends IFile, IListable {
|
||||
readonly canRestore: boolean;
|
||||
readonly restoreDate: string;
|
||||
}
|
||||
@ -156,11 +156,11 @@ export class EditDossierDeletedDocumentsComponent extends ListingComponent<FileL
|
||||
this.entitiesService.setSelected([]);
|
||||
}
|
||||
|
||||
private _toListItems(files: FileStatus[]): FileListItem[] {
|
||||
private _toListItems(files: IFile[]): FileListItem[] {
|
||||
return files.map(file => this._toListItem(file));
|
||||
}
|
||||
|
||||
private _toListItem(file: FileStatus): FileListItem {
|
||||
private _toListItem(file: IFile): FileListItem {
|
||||
const restoreDate = this._getRestoreDate(file.softDeleted);
|
||||
return {
|
||||
id: file.fileId,
|
||||
|
||||
@ -91,7 +91,7 @@
|
||||
<redaction-dossier-overview-bulk-actions (reload)="bulkActionPerformed()"></redaction-dossier-overview-bulk-actions>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #filenameTemplate let-fileStatus="entity">
|
||||
<ng-template #filenameTemplate let-file="entity">
|
||||
<div class="cell">
|
||||
<div>
|
||||
<div [class.error]="fileStatus.isError" [matTooltip]="fileStatus.filename" class="table-item-title" matTooltipPosition="above">
|
||||
@ -109,71 +109,71 @@
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #addedOnTemplate let-fileStatus="entity">
|
||||
<ng-template #addedOnTemplate let-file="entity">
|
||||
<div class="cell">
|
||||
<div [class.error]="fileStatus.isError" class="small-label">
|
||||
{{ fileStatus.added | date: 'd MMM. yyyy, hh:mm a' }}
|
||||
<div [class.error]="file.isError" class="small-label">
|
||||
{{ file.added | date: 'd MMM. yyyy, hh:mm a' }}
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #attributeTemplate let-config="extra" let-fileStatus="entity">
|
||||
<ng-template #attributeTemplate let-config="extra" let-file="entity">
|
||||
<div class="cell">
|
||||
{{ fileStatus.fileAttributes.attributeIdToValue[config.id] }}
|
||||
{{ file.fileAttributes.attributeIdToValue[config.id] }}
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #needsWorkTemplate let-fileStatus="entity">
|
||||
<ng-template #needsWorkTemplate let-file="entity">
|
||||
<!-- always show A for error-->
|
||||
<div *ngIf="fileStatus.isError" class="cell">
|
||||
<div *ngIf="file.isError" class="cell">
|
||||
<redaction-annotation-icon color="#dd4d50" label="A" type="square"></redaction-annotation-icon>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!fileStatus.isError" class="cell">
|
||||
<redaction-needs-work-badge [needsWorkInput]="fileStatus"></redaction-needs-work-badge>
|
||||
<div *ngIf="!file.isError" class="cell">
|
||||
<redaction-needs-work-badge [needsWorkInput]="file"></redaction-needs-work-badge>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #reviewerTemplate let-fileStatus="entity">
|
||||
<div *ngIf="!fileStatus.isError" class="user-column cell">
|
||||
<redaction-initials-avatar [userId]="fileStatus.currentReviewer" [withName]="true"></redaction-initials-avatar>
|
||||
<ng-template #reviewerTemplate let-file="entity">
|
||||
<div *ngIf="!file.isError" class="user-column cell">
|
||||
<redaction-initials-avatar [userId]="file.currentReviewer" [withName]="true"></redaction-initials-avatar>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #pagesTemplate let-fileStatus="entity">
|
||||
<div *ngIf="!fileStatus.isError" class="cell">
|
||||
<ng-template #pagesTemplate let-file="entity">
|
||||
<div *ngIf="!file.isError" class="cell">
|
||||
<div class="small-label stats-subtitle">
|
||||
<div>
|
||||
<mat-icon svgIcon="red:pages"></mat-icon>
|
||||
{{ fileStatus.numberOfPages }}
|
||||
{{ file.numberOfPages }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #statusTemplate let-fileStatus="entity">
|
||||
<div [class.extend-cols]="fileStatus.isError" class="status-container cell">
|
||||
<div *ngIf="fileStatus.isError" class="small-label error" translate="dossier-overview.file-listing.file-entry.file-error"></div>
|
||||
<div *ngIf="fileStatus.isPending" class="small-label" translate="dossier-overview.file-listing.file-entry.file-pending"></div>
|
||||
<ng-template #statusTemplate let-file="entity">
|
||||
<div [class.extend-cols]="file.isError" class="status-container cell">
|
||||
<div *ngIf="file.isError" class="small-label error" translate="dossier-overview.file-listing.file-entry.file-error"></div>
|
||||
<div *ngIf="file.isPending" class="small-label" translate="dossier-overview.file-listing.file-entry.file-pending"></div>
|
||||
<div
|
||||
*ngIf="fileStatus.isProcessing"
|
||||
*ngIf="file.isProcessing"
|
||||
class="small-label loading"
|
||||
translate="dossier-overview.file-listing.file-entry.file-processing"
|
||||
></div>
|
||||
<iqser-status-bar
|
||||
*ngIf="fileStatus.isWorkable"
|
||||
*ngIf="file.isWorkable"
|
||||
[configs]="[
|
||||
{
|
||||
color: fileStatus.status,
|
||||
color: file.status,
|
||||
length: 1
|
||||
}
|
||||
]"
|
||||
></iqser-status-bar>
|
||||
|
||||
<redaction-file-actions
|
||||
(actionPerformed)="actionPerformed()"
|
||||
*ngIf="!fileStatus.isProcessing"
|
||||
[fileStatus]="fileStatus"
|
||||
(actionPerformed)="calculateData()"
|
||||
*ngIf="!file.isProcessing"
|
||||
[file]="file"
|
||||
class="mr-4"
|
||||
type="dossier-overview-list"
|
||||
></redaction-file-actions>
|
||||
|
||||
@ -19,13 +19,13 @@ import { StatusOverlayService } from '@upload-download/services/status-overlay.s
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import * as moment from 'moment';
|
||||
import { DossierDetailsComponent } from '../../components/dossier-details/dossier-details.component';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { timer } from 'rxjs';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { RedactionFilterSorter } from '@utils/sorters/redaction-filter-sorter';
|
||||
import { StatusSorter } from '@utils/sorters/status-sorter';
|
||||
import { convertFiles, handleFileDrop } from '@utils/file-drop-utils';
|
||||
import { convertFiles, Files, handleFileDrop } from '@utils/file-drop-utils';
|
||||
import { DossiersDialogService } from '../../services/dossiers-dialog.service';
|
||||
import { OnAttach, OnDetach } from '@utils/custom-route-reuse.strategy';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
@ -63,7 +63,7 @@ import StatusEnum = FileStatus.StatusEnum;
|
||||
styleUrls: ['./dossier-overview-screen.component.scss'],
|
||||
providers: [...DefaultListingServices, { provide: ListingComponent, useExisting: forwardRef(() => DossierOverviewScreenComponent) }]
|
||||
})
|
||||
export class DossierOverviewScreenComponent extends ListingComponent<FileStatusWrapper> implements OnInit, OnDestroy, OnDetach, OnAttach {
|
||||
export class DossierOverviewScreenComponent extends ListingComponent<File> implements OnInit, OnDestroy, OnDetach, OnAttach {
|
||||
readonly listingModes = ListingModes;
|
||||
readonly circleButtonTypes = CircleButtonTypes;
|
||||
readonly currentUser = this._userService.currentUser;
|
||||
@ -77,7 +77,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<FileStatusW
|
||||
hide: !this.currentUser.isManager
|
||||
}
|
||||
];
|
||||
tableColumnConfigs: readonly TableColumnConfig<FileStatusWrapper>[] = [];
|
||||
tableColumnConfigs: readonly TableColumnConfig<File>[] = [];
|
||||
collapsedDetails = false;
|
||||
dossierAttributes: DossierAttributeWithValue[] = [];
|
||||
fileAttributeConfigs: IFileAttributeConfig[];
|
||||
@ -303,7 +303,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<FileStatusW
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
async uploadFiles(files: File[] | FileList): Promise<void> {
|
||||
async uploadFiles(files: Files): Promise<void> {
|
||||
await this._uploadFiles(convertFiles(files, this.currentDossier));
|
||||
this._fileInput.nativeElement.value = null;
|
||||
}
|
||||
@ -335,11 +335,11 @@ export class DossierOverviewScreenComponent extends ListingComponent<FileStatusW
|
||||
this.collapsedDetails = !this.collapsedDetails;
|
||||
}
|
||||
|
||||
recentlyModifiedChecker = (file: FileStatusWrapper) =>
|
||||
recentlyModifiedChecker = (file: File) =>
|
||||
moment(file.lastUpdated).add(this._configService.values.RECENT_PERIOD_IN_HOURS, 'hours').isAfter(moment());
|
||||
|
||||
private _configureTableColumns() {
|
||||
const dynamicColumns: TableColumnConfig<FileStatusWrapper>[] = [];
|
||||
const dynamicColumns: TableColumnConfig<File>[] = [];
|
||||
for (const config of this.displayedInFileListAttributes) {
|
||||
if (config.displayedInFileList) {
|
||||
dynamicColumns.push({ label: config.label, notTranslatable: true, template: this.attributeTemplate, extra: config });
|
||||
@ -372,7 +372,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<FileStatusW
|
||||
},
|
||||
{
|
||||
label: _('dossier-overview.table-col-names.pages'),
|
||||
sortByKey: 'pages',
|
||||
sortByKey: 'numberOfPages',
|
||||
template: this.pagesTemplate
|
||||
},
|
||||
{
|
||||
@ -534,14 +534,14 @@ export class DossierOverviewScreenComponent extends ListingComponent<FileStatusW
|
||||
label: value === '-' ? this._translateService.instant('filters.empty') : value
|
||||
})
|
||||
),
|
||||
checker: (input: FileStatusWrapper, filter: INestedFilter) => filter.id === input.fileAttributes.attributeIdToValue[id]
|
||||
checker: (input: File, filter: INestedFilter) => filter.id === input.fileAttributes.attributeIdToValue[id]
|
||||
});
|
||||
});
|
||||
|
||||
this.filterService.addFilterGroup({
|
||||
slug: 'quickFilters',
|
||||
filters: this._createQuickFilters(),
|
||||
checker: (file: FileStatusWrapper) =>
|
||||
checker: (file: File) =>
|
||||
this.checkedRequiredFilters.reduce((acc, f) => acc && f.checker(file), true) &&
|
||||
(this.checkedNotRequiredFilters.length === 0 ||
|
||||
this.checkedNotRequiredFilters.reduce((acc, f) => acc || f.checker(file), false))
|
||||
@ -586,17 +586,17 @@ export class DossierOverviewScreenComponent extends ListingComponent<FileStatusW
|
||||
{
|
||||
id: 'assigned-to-me',
|
||||
label: this._translateService.instant('dossier-overview.quick-filters.assigned-to-me'),
|
||||
checker: (file: FileStatusWrapper) => file.currentReviewer === this.currentUser.id
|
||||
checker: (file: File) => file.currentReviewer === this.currentUser.id
|
||||
},
|
||||
{
|
||||
id: 'unassigned',
|
||||
label: this._translateService.instant('dossier-overview.quick-filters.unassigned'),
|
||||
checker: (file: FileStatusWrapper) => !file.currentReviewer
|
||||
checker: (file: File) => !file.currentReviewer
|
||||
},
|
||||
{
|
||||
id: 'assigned-to-others',
|
||||
label: this._translateService.instant('dossier-overview.quick-filters.assigned-to-others'),
|
||||
checker: (file: FileStatusWrapper) => !!file.currentReviewer && file.currentReviewer !== this.currentUser.id
|
||||
checker: (file: File) => !!file.currentReviewer && file.currentReviewer !== this.currentUser.id
|
||||
}
|
||||
].map(filter => new NestedFilter(filter));
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@
|
||||
[annotations]="annotations"
|
||||
[canPerformActions]="canPerformAnnotationActions"
|
||||
[fileData]="displayData"
|
||||
[fileStatus]="appStateService.activeFile"
|
||||
[file]="appStateService.activeFile"
|
||||
[multiSelectActive]="multiSelectActive"
|
||||
[shouldDeselectAnnotationsOnPageChange]="shouldDeselectAnnotationsOnPageChange"
|
||||
></redaction-pdf-viewer>
|
||||
@ -159,7 +159,7 @@
|
||||
<redaction-document-info
|
||||
(closeDocumentInfoView)="viewDocumentInfo = false"
|
||||
*ngIf="viewDocumentInfo"
|
||||
[file]="fileData.fileStatus"
|
||||
[file]="fileData.file"
|
||||
></redaction-document-info>
|
||||
|
||||
<redaction-file-workload
|
||||
|
||||
@ -21,7 +21,7 @@ import { AnnotationData, FileDataModel } from '@models/file/file-data.model';
|
||||
import { FileActionService } from '../../services/file-action.service';
|
||||
import { AnnotationDrawService } from '../../services/annotation-draw.service';
|
||||
import { AnnotationProcessingService } from '../../services/annotation-processing.service';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { timer } from 'rxjs';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
@ -73,6 +73,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
viewDocumentInfo = false;
|
||||
excludePages = false;
|
||||
@ViewChild(PdfViewerComponent) readonly viewerComponent: PdfViewerComponent;
|
||||
@ViewChild('fileActions') fileActions: FileActionsComponent;
|
||||
private _instance: WebViewerInstance;
|
||||
private _lastPage: string;
|
||||
private _reloadFileOnReanalysis = false;
|
||||
@ -82,7 +83,6 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
static: true
|
||||
})
|
||||
private readonly _filterTemplate: TemplateRef<INestedFilter>;
|
||||
@ViewChild('fileActions') fileActions: FileActionsComponent;
|
||||
|
||||
constructor(
|
||||
readonly appStateService: AppStateService,
|
||||
@ -148,11 +148,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
get canSwitchToRedactedView(): boolean {
|
||||
return this.fileData && !this.fileData.fileStatus.analysisRequired && !this.fileData.fileStatus.excluded;
|
||||
return this.fileData && !this.fileData.file.analysisRequired && !this.fileData.file.excluded;
|
||||
}
|
||||
|
||||
get canSwitchToDeltaView(): boolean {
|
||||
return this.fileData?.redactionChangeLog?.redactionLogEntry?.length > 0 && !this.fileData.fileStatus.excluded;
|
||||
return this.fileData?.redactionChangeLog?.redactionLogEntry?.length > 0 && !this.fileData.file.excluded;
|
||||
}
|
||||
|
||||
get canAssign(): boolean {
|
||||
@ -176,7 +176,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
get lastReviewer(): string | undefined {
|
||||
return this.appStateService.activeFile.fileStatus.lastReviewer;
|
||||
return this.appStateService.activeFile.lastReviewer;
|
||||
}
|
||||
|
||||
get assignOrChangeReviewerTooltip(): string {
|
||||
@ -189,11 +189,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
return this.appStateService.activeFile.currentReviewer;
|
||||
}
|
||||
|
||||
get status(): FileStatus.StatusEnum {
|
||||
get status(): FileStatus {
|
||||
return this.appStateService.activeFile.status;
|
||||
}
|
||||
|
||||
get statusBarConfig(): [{ length: number; color: FileStatus.StatusEnum }] {
|
||||
get statusBarConfig(): [{ length: number; color: FileStatus }] {
|
||||
return [{ length: 1, color: this.status }];
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
this._updateCanPerformActions();
|
||||
this._subscribeToFileUpdates();
|
||||
|
||||
if (this.fileData?.fileStatus?.analysisRequired) {
|
||||
if (this.fileData?.file?.analysisRequired) {
|
||||
this.fileActions.reanalyseFile();
|
||||
}
|
||||
}
|
||||
@ -355,7 +355,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
response.manualRedactionEntryWrapper.rectId
|
||||
);
|
||||
this._instance.Core.annotationManager.deleteAnnotation(annotation);
|
||||
this.fileData.fileStatus = await this.appStateService.reloadActiveFile();
|
||||
this.fileData.file = await this.appStateService.reloadActiveFile();
|
||||
const distinctPages = entryWrapper.manualRedactionEntry.positions
|
||||
.map(p => p.page)
|
||||
.filter((item, pos, self) => self.indexOf(item) === pos);
|
||||
@ -490,7 +490,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
async assignToMe() {
|
||||
await this._fileActionService.assignToMe(this.fileData.fileStatus, async () => {
|
||||
await this._fileActionService.assignToMe([this.fileData.file], async () => {
|
||||
await this.appStateService.reloadActiveFile();
|
||||
this._updateCanPerformActions();
|
||||
});
|
||||
@ -500,7 +500,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
const reviewerId = typeof user === 'string' ? user : user.id;
|
||||
const reviewerName = this.userService.getNameForId(reviewerId);
|
||||
|
||||
const { dossierId, fileId, filename } = this.fileData.fileStatus;
|
||||
const { dossierId, fileId, filename } = this.fileData.file;
|
||||
await this._statusControllerService.setFileReviewer(dossierId, fileId, reviewerId).toPromise();
|
||||
|
||||
this._toaster.info(_('assignment.reviewer'), { params: { reviewerName, filename } });
|
||||
@ -523,9 +523,9 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
downloadOriginalFile() {
|
||||
this.addSubscription = this._fileManagementControllerService
|
||||
.downloadOriginalFile(this.dossierId, this.fileId, true, this.fileData.fileStatus.cacheIdentifier, 'response')
|
||||
.downloadOriginalFile(this.dossierId, this.fileId, true, this.fileData.file.cacheIdentifier, 'response')
|
||||
.subscribe(data => {
|
||||
download(data, this.fileData.fileStatus.filename);
|
||||
download(data, this.fileData.file.filename);
|
||||
});
|
||||
}
|
||||
|
||||
@ -561,7 +561,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
if (excludedPages && excludedPages.length > 0) {
|
||||
const pdfNet = this._instance.Core.PDFNet;
|
||||
const document = await this._instance.Core.documentViewer.getDocument().getPDFDoc();
|
||||
await clearStamps(document, pdfNet, [...Array(this.fileData.fileStatus.numberOfPages).keys()]);
|
||||
await clearStamps(document, pdfNet, [...Array(this.fileData.file.numberOfPages).keys()]);
|
||||
await stampPDFPage(
|
||||
document,
|
||||
pdfNet,
|
||||
@ -577,7 +577,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
}
|
||||
|
||||
private async _stampExcludedPages() {
|
||||
await this._doStampExcludedPages(this.fileData.fileStatus.excludedPages);
|
||||
await this._doStampExcludedPages(this.fileData.file.excludedPages);
|
||||
this._instance.Core.documentViewer.refreshAll();
|
||||
this._instance.Core.documentViewer.updateView([this.activeViewerPage], this.activeViewerPage);
|
||||
this._changeDetectorRef.detectChanges();
|
||||
@ -585,8 +585,8 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
private _subscribeToFileUpdates(): void {
|
||||
this.addSubscription = timer(0, 5000).subscribe(async () => await this.appStateService.reloadActiveFile());
|
||||
this.addSubscription = this.appStateService.fileReanalysed$.subscribe(async (fileStatus: FileStatusWrapper) => {
|
||||
if (fileStatus.fileId === this.fileId) {
|
||||
this.addSubscription = this.appStateService.fileReanalysed$.subscribe(async (file: File) => {
|
||||
if (file.fileId === this.fileId) {
|
||||
await this._loadFileData(!this._reloadFileOnReanalysis);
|
||||
this._reloadFileOnReanalysis = false;
|
||||
this._loadingService.stop();
|
||||
@ -606,11 +606,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
private async _loadFileData(performUpdate = false): Promise<void> {
|
||||
const fileData = await this._fileDownloadService.loadActiveFileData().toPromise();
|
||||
|
||||
if (!fileData.fileStatus?.isPending && !fileData.fileStatus?.isError) {
|
||||
if (!fileData.file?.isPending && !fileData.file?.isError) {
|
||||
if (performUpdate) {
|
||||
this.fileData.redactionLog = fileData.redactionLog;
|
||||
this.fileData.redactionChangeLog = fileData.redactionChangeLog;
|
||||
this.fileData.fileStatus = fileData.fileStatus;
|
||||
this.fileData.file = fileData.file;
|
||||
this.rebuildFilters(true);
|
||||
} else {
|
||||
this.fileData = fileData;
|
||||
@ -620,7 +620,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
return;
|
||||
}
|
||||
|
||||
if (fileData.fileStatus.isError) {
|
||||
if (fileData.file.isError) {
|
||||
await this._router.navigate(['/main/dossiers/' + this.dossierId]);
|
||||
}
|
||||
}
|
||||
@ -648,7 +648,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
private async _cleanupAndRedrawManualAnnotationsForEntirePage(page: number) {
|
||||
const currentPageAnnotations = this.annotations.filter(a => a.pageNumber === page);
|
||||
const currentPageAnnotationIds = currentPageAnnotations.map(a => a.id);
|
||||
this.fileData.fileStatus = await this.appStateService.reloadActiveFile();
|
||||
this.fileData.file = await this.appStateService.reloadActiveFile();
|
||||
|
||||
this._fileDownloadService.loadActiveFileRedactionLog().subscribe(redactionLogPreview => {
|
||||
this.fileData.redactionLog = redactionLogPreview;
|
||||
|
||||
@ -2,9 +2,8 @@ import { Injectable } from '@angular/core';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { ReanalysisControllerService, StatusControllerService } from '@redaction/red-ui-http';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { isArray } from 'rxjs/internal-compatibility';
|
||||
import { DossiersDialogService } from './dossiers-dialog.service';
|
||||
import { ConfirmationDialogInput } from '@shared/dialogs/confirmation-dialog/confirmation-dialog.component';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
@ -21,108 +20,87 @@ export class FileActionService {
|
||||
private readonly _appStateService: AppStateService
|
||||
) {}
|
||||
|
||||
reanalyseFile(fileStatusWrapper?: FileStatusWrapper) {
|
||||
if (!fileStatusWrapper) {
|
||||
fileStatusWrapper = this._appStateService.activeFile;
|
||||
}
|
||||
return this._reanalysisControllerService.reanalyzeFile(this._appStateService.activeDossier.id, fileStatusWrapper.fileId, true);
|
||||
reanalyseFile(file = this._appStateService.activeFile) {
|
||||
return this._reanalysisControllerService.reanalyzeFile(this._appStateService.activeDossier.id, file.fileId, true);
|
||||
}
|
||||
|
||||
toggleAnalysis(fileStatusWrapper?: FileStatusWrapper) {
|
||||
if (!fileStatusWrapper) {
|
||||
fileStatusWrapper = this._appStateService.activeFile;
|
||||
}
|
||||
return this._reanalysisControllerService.toggleAnalysis(
|
||||
fileStatusWrapper.dossierId,
|
||||
fileStatusWrapper.fileId,
|
||||
!fileStatusWrapper.excluded
|
||||
);
|
||||
toggleAnalysis(file = this._appStateService.activeFile) {
|
||||
return this._reanalysisControllerService.toggleAnalysis(file.dossierId, file.fileId, !file.excluded);
|
||||
}
|
||||
|
||||
async assignToMe(fileStatus?: FileStatusWrapper | FileStatusWrapper[], callback?: Function) {
|
||||
async assignToMe(files?: File[], callback?: Function) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
if (!isArray(fileStatus)) {
|
||||
fileStatus = [fileStatus];
|
||||
}
|
||||
|
||||
const atLeastOneFileHasReviewer = fileStatus.reduce((acc, fs) => acc || !!fs.currentReviewer, false);
|
||||
const atLeastOneFileHasReviewer = files.reduce((acc, fs) => acc || !!fs.currentReviewer, false);
|
||||
if (atLeastOneFileHasReviewer) {
|
||||
const data = new ConfirmationDialogInput({
|
||||
title: _('confirmation-dialog.assign-file-to-me.title'),
|
||||
question: _('confirmation-dialog.assign-file-to-me.question')
|
||||
});
|
||||
this._dialogService.openDialog('confirm', null, data, () => {
|
||||
this._assignReviewerToCurrentUser(fileStatus, callback)
|
||||
this._assignReviewerToCurrentUser(files, callback)
|
||||
.then(() => resolve())
|
||||
.catch(() => reject());
|
||||
});
|
||||
} else {
|
||||
this._assignReviewerToCurrentUser(fileStatus, callback)
|
||||
this._assignReviewerToCurrentUser(files, callback)
|
||||
.then(() => resolve())
|
||||
.catch(() => reject());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setFileUnderApproval(fileStatus: FileStatusWrapper | FileStatusWrapper[], approverId?: string) {
|
||||
if (!isArray(fileStatus)) {
|
||||
fileStatus = [fileStatus];
|
||||
}
|
||||
|
||||
setFilesUnderApproval(files: File[], approverId?: string) {
|
||||
if (!approverId) {
|
||||
approverId = this._appStateService.activeDossier.approverIds[0];
|
||||
}
|
||||
|
||||
return this._statusControllerService.setStatusUnderApprovalForList(
|
||||
fileStatus.map(f => f.fileId),
|
||||
files.map(f => f.fileId),
|
||||
approverId,
|
||||
this._appStateService.activeDossierId
|
||||
);
|
||||
}
|
||||
|
||||
setFileApproved(fileStatus: FileStatusWrapper | FileStatusWrapper[]): Observable<any> {
|
||||
if (!isArray(fileStatus)) {
|
||||
fileStatus = [fileStatus];
|
||||
}
|
||||
setFilesApproved(files: File[]) {
|
||||
return this._statusControllerService.setStatusApprovedForList(
|
||||
fileStatus.map(f => f.fileId),
|
||||
files.map(f => f.fileId),
|
||||
this._appStateService.activeDossierId
|
||||
);
|
||||
}
|
||||
|
||||
setFileUnderReview(fileStatus: FileStatusWrapper | FileStatusWrapper[]) {
|
||||
if (!isArray(fileStatus)) {
|
||||
fileStatus = [fileStatus];
|
||||
}
|
||||
setFilesUnderReview(files: File[]) {
|
||||
return this._statusControllerService.setStatusUnderReviewForList(
|
||||
fileStatus.map(f => f.fileId),
|
||||
files.map(f => f.fileId),
|
||||
this._appStateService.activeDossierId
|
||||
);
|
||||
}
|
||||
|
||||
ocrFile(fileStatus: FileStatusWrapper | FileStatusWrapper[]) {
|
||||
if (!isArray(fileStatus)) {
|
||||
fileStatus = [fileStatus];
|
||||
}
|
||||
ocrFiles(files: File[]) {
|
||||
return this._reanalysisControllerService.ocrFiles(
|
||||
fileStatus.map(f => f.fileId),
|
||||
files.map(f => f.fileId),
|
||||
this._appStateService.activeDossierId
|
||||
);
|
||||
}
|
||||
|
||||
assignFile(mode: 'reviewer' | 'approver', $event: MouseEvent, file?: FileStatusWrapper, callback?: Function, ignoreChanged = false) {
|
||||
const files = file ? [file] : [this._appStateService.activeFile];
|
||||
const data = { mode, files, ignoreChanged };
|
||||
this._dialogService.openDialog('assignFile', $event, data, callback);
|
||||
assignFile(
|
||||
mode: 'reviewer' | 'approver',
|
||||
$event: MouseEvent,
|
||||
file = this._appStateService.activeFile,
|
||||
callback?: Function,
|
||||
ignoreChanged = false
|
||||
) {
|
||||
const data = { mode, files: [file], ignoreChanged };
|
||||
this._dialogService.openDialog('assignFile', $event, data, async () => {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async _assignReviewerToCurrentUser(fileStatus: FileStatusWrapper | FileStatusWrapper[], callback?: Function) {
|
||||
if (!isArray(fileStatus)) {
|
||||
fileStatus = [fileStatus];
|
||||
}
|
||||
private async _assignReviewerToCurrentUser(files: File[], callback?: Function) {
|
||||
await this._statusControllerService
|
||||
.setFileReviewerForList(
|
||||
fileStatus.map(f => f.fileId),
|
||||
files.map(f => f.fileId),
|
||||
this._appStateService.activeDossierId,
|
||||
this._userService.currentUser.id
|
||||
)
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
import { FileDataModel } from '@models/file/file-data.model';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
|
||||
@Injectable()
|
||||
export class PdfViewerDataService {
|
||||
@ -59,13 +59,7 @@ export class PdfViewerDataService {
|
||||
return of({ pages: [] });
|
||||
}
|
||||
|
||||
downloadOriginalFile(fileStatus: FileStatusWrapper): Observable<any> {
|
||||
return this._fileManagementControllerService.downloadOriginalFile(
|
||||
fileStatus.dossierId,
|
||||
fileStatus.fileId,
|
||||
true,
|
||||
fileStatus.cacheIdentifier,
|
||||
'body'
|
||||
);
|
||||
downloadOriginalFile(file: File): Observable<any> {
|
||||
return this._fileManagementControllerService.downloadOriginalFile(file.dossierId, file.fileId, true, file.cacheIdentifier, 'body');
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { FileStatus } from '@redaction/red-ui-http';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
export const fileStatusTranslations: { [key in FileStatus.StatusEnum]: string } = {
|
||||
export const fileStatusTranslations: { [key in FileStatus]: string } = {
|
||||
APPROVED: _('file-status.approved'),
|
||||
DELETED: _('file-status.deleted'),
|
||||
ERROR: _('file-status.error'),
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, Input, OnDestroy } from '@angular/core';
|
||||
import { PermissionsService } from '@services/permissions.service';
|
||||
import { Dossier } from '../../../../../state/model/dossier';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { FileDownloadService } from '@upload-download/services/file-download.service';
|
||||
import { Toaster } from '@iqser/common-ui';
|
||||
import { AutoUnsubscribe, CircleButtonType, CircleButtonTypes } from '@iqser/common-ui';
|
||||
@ -18,7 +18,7 @@ export type MenuState = 'OPEN' | 'CLOSED';
|
||||
})
|
||||
export class FileDownloadBtnComponent extends AutoUnsubscribe implements OnDestroy {
|
||||
@Input() dossier: Dossier;
|
||||
@Input() file: FileStatusWrapper | FileStatusWrapper[];
|
||||
@Input() file: File | File[];
|
||||
@Input() tooltipPosition: 'above' | 'below' | 'before' | 'after' = 'above';
|
||||
@Input() type: CircleButtonType = CircleButtonTypes.default;
|
||||
@Input() tooltipClass: string;
|
||||
|
||||
@ -4,7 +4,7 @@ import { interval, Observable } from 'rxjs';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Dossier } from '@state/model/dossier';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { mergeMap, tap } from 'rxjs/operators';
|
||||
import { DownloadStatusWrapper } from '../model/download-status.wrapper';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
@ -34,10 +34,10 @@ export class FileDownloadService {
|
||||
});
|
||||
}
|
||||
|
||||
downloadFiles(fileStatusWrappers: FileStatusWrapper[], dossier: Dossier): Observable<any> {
|
||||
downloadFiles(files: File[], dossier: Dossier): Observable<any> {
|
||||
return this._downloadControllerService
|
||||
.prepareDownload({
|
||||
fileIds: fileStatusWrappers.map(f => f.fileId),
|
||||
fileIds: files.map(f => f.fileId),
|
||||
dossierId: dossier.id
|
||||
})
|
||||
.pipe(mergeMap(() => this.getDownloadStatus()));
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { UserService } from './user.service';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { Comment } from '@redaction/red-ui-http';
|
||||
import { Dossier } from '../state/model/dossier';
|
||||
import { Dossier } from '@state/model/dossier';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@ -11,7 +11,7 @@ import { Dossier } from '../state/model/dossier';
|
||||
export class PermissionsService {
|
||||
constructor(private readonly _appStateService: AppStateService, private readonly _userService: UserService) {}
|
||||
|
||||
private get _activeFile(): FileStatusWrapper | undefined {
|
||||
private get _activeFile(): File | undefined {
|
||||
return this._appStateService.activeFile;
|
||||
}
|
||||
|
||||
@ -19,42 +19,39 @@ export class PermissionsService {
|
||||
return this._appStateService.activeDossier;
|
||||
}
|
||||
|
||||
isReviewerOrApprover(fileStatus?: FileStatusWrapper): boolean {
|
||||
return this.isFileReviewer(fileStatus) || this.isApprover();
|
||||
isReviewerOrApprover(file?: File): boolean {
|
||||
return this.isFileReviewer(file) || this.isApprover();
|
||||
}
|
||||
|
||||
displayReanalyseBtn(dossier = this._activeDossier): boolean {
|
||||
return this.isApprover(dossier) && dossier.files.filter(file => file.analysisRequired).length > 0;
|
||||
}
|
||||
|
||||
canToggleAnalysis(fileStatus: FileStatusWrapper): boolean {
|
||||
return this.isReviewerOrApprover(fileStatus) && ['UNASSIGNED', 'UNDER_REVIEW', 'UNDER_APPROVAL'].includes(fileStatus.status);
|
||||
canToggleAnalysis(file: File): boolean {
|
||||
return this.isReviewerOrApprover(file) && ['UNASSIGNED', 'UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file.status);
|
||||
}
|
||||
|
||||
canReanalyseFile(fileStatus = this._activeFile): boolean {
|
||||
return (
|
||||
(fileStatus.analysisRequired && (this.isReviewerOrApprover(fileStatus) || fileStatus.isUnassigned)) ||
|
||||
(fileStatus.isError && fileStatus.isUnassigned)
|
||||
);
|
||||
canReanalyseFile(file = this._activeFile): boolean {
|
||||
return (file.analysisRequired && (this.isReviewerOrApprover(file) || file.isUnassigned)) || (file.isError && file.isUnassigned);
|
||||
}
|
||||
|
||||
isFileReviewer(fileStatus = this._activeFile): boolean {
|
||||
return fileStatus.currentReviewer === this._userService.currentUser.id;
|
||||
isFileReviewer(file = this._activeFile): boolean {
|
||||
return file.currentReviewer === this._userService.currentUser.id;
|
||||
}
|
||||
|
||||
canDeleteFile(fileStatus = this._activeFile, dossier?: Dossier): boolean {
|
||||
return (this.isOwner(dossier) && !fileStatus.isApproved) || fileStatus.isUnassigned;
|
||||
canDeleteFile(file = this._activeFile, dossier?: Dossier): boolean {
|
||||
return (this.isOwner(dossier) && !file.isApproved) || file.isUnassigned;
|
||||
}
|
||||
|
||||
canAssignToSelf(fileStatus = this._activeFile): boolean {
|
||||
const precondition = this.isDossierMember() && !fileStatus.isProcessing && !fileStatus.isError && !fileStatus.isApproved;
|
||||
canAssignToSelf(file = this._activeFile): boolean {
|
||||
const precondition = this.isDossierMember() && !file.isProcessing && !file.isError && !file.isApproved;
|
||||
|
||||
const isTheOnlyReviewer = !this._appStateService.activeDossier?.hasReviewers;
|
||||
|
||||
if (precondition) {
|
||||
if (
|
||||
(fileStatus.isUnassigned || (fileStatus.isUnderReview && !this.isFileReviewer(fileStatus))) &&
|
||||
(this.isApprover() || isTheOnlyReviewer || (this.isDossierReviewer() && fileStatus.isUnassigned))
|
||||
(file.isUnassigned || (file.isUnderReview && !this.isFileReviewer(file))) &&
|
||||
(this.isApprover() || isTheOnlyReviewer || (this.isDossierReviewer() && file.isUnassigned))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
@ -62,30 +59,30 @@ export class PermissionsService {
|
||||
return false;
|
||||
}
|
||||
|
||||
canAssignUser(fileStatus = this._activeFile): boolean {
|
||||
const precondition = !fileStatus.isProcessing && !fileStatus.isError && !fileStatus.isApproved && this.isApprover();
|
||||
canAssignUser(file = this._activeFile): boolean {
|
||||
const precondition = !file.isProcessing && !file.isError && !file.isApproved && this.isApprover();
|
||||
|
||||
if (precondition) {
|
||||
if ((fileStatus.isUnassigned || fileStatus.isUnderReview) && this._activeDossier.hasReviewers) {
|
||||
if ((file.isUnassigned || file.isUnderReview) && this._activeDossier.hasReviewers) {
|
||||
return true;
|
||||
}
|
||||
if (fileStatus.isUnderApproval && this._activeDossier.approverIds.length > 1) {
|
||||
if (file.isUnderApproval && this._activeDossier.approverIds.length > 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
canSetUnderReview(fileStatus = this._activeFile): boolean {
|
||||
return fileStatus?.isUnderApproval && this.isApprover();
|
||||
canSetUnderReview(file = this._activeFile): boolean {
|
||||
return file?.isUnderApproval && this.isApprover();
|
||||
}
|
||||
|
||||
isReadyForApproval(fileStatus = this._activeFile): boolean {
|
||||
return this.canSetUnderReview(fileStatus);
|
||||
isReadyForApproval(file = this._activeFile): boolean {
|
||||
return this.canSetUnderReview(file);
|
||||
}
|
||||
|
||||
canSetUnderApproval(fileStatus = this._activeFile): boolean {
|
||||
return fileStatus?.isUnderReview && this.isReviewerOrApprover(fileStatus);
|
||||
canSetUnderApproval(file = this._activeFile): boolean {
|
||||
return file?.isUnderReview && this.isReviewerOrApprover(file);
|
||||
}
|
||||
|
||||
isOwner(dossier = this._activeDossier, user = this._userService.currentUser): boolean {
|
||||
@ -104,25 +101,25 @@ export class PermissionsService {
|
||||
return dossier?.memberIds.includes(user.id);
|
||||
}
|
||||
|
||||
canPerformAnnotationActions(fileStatus = this._activeFile): boolean {
|
||||
return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(fileStatus?.status) && this.isFileReviewer(fileStatus);
|
||||
canPerformAnnotationActions(file = this._activeFile): boolean {
|
||||
return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file?.status) && this.isFileReviewer(file);
|
||||
}
|
||||
|
||||
canUndoApproval(fileStatus = this._activeFile): boolean {
|
||||
return fileStatus?.isApproved && this.isApprover();
|
||||
canUndoApproval(file = this._activeFile): boolean {
|
||||
return file?.isApproved && this.isApprover();
|
||||
}
|
||||
|
||||
canMarkPagesAsViewed(fileStatus = this._activeFile): boolean {
|
||||
return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(fileStatus?.status) && this.isFileReviewer(fileStatus);
|
||||
canMarkPagesAsViewed(file = this._activeFile): boolean {
|
||||
return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file?.status) && this.isFileReviewer(file);
|
||||
}
|
||||
|
||||
canDownloadFiles(fileStatus = this._activeFile): boolean {
|
||||
const dossier = this._appStateService.getDossierById(fileStatus?.dossierId);
|
||||
canDownloadFiles(file = this._activeFile): boolean {
|
||||
const dossier = this._appStateService.getDossierById(file?.dossierId);
|
||||
if (!dossier) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return fileStatus.isApproved && this.isApprover(dossier);
|
||||
return file.isApproved && this.isApprover(dossier);
|
||||
}
|
||||
|
||||
canDeleteDossier(dossier = this._activeDossier): boolean {
|
||||
@ -133,15 +130,15 @@ export class PermissionsService {
|
||||
return user.isAdmin;
|
||||
}
|
||||
|
||||
canAddComment(fileStatus = this._activeFile): boolean {
|
||||
return (this.isFileReviewer(fileStatus) || this.isApprover()) && !fileStatus.isApproved;
|
||||
canAddComment(file = this._activeFile): boolean {
|
||||
return (this.isFileReviewer(file) || this.isApprover()) && !file.isApproved;
|
||||
}
|
||||
|
||||
canExcludePages(fileStatus = this._activeFile): boolean {
|
||||
return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(fileStatus.status) && (this.isFileReviewer(fileStatus) || this.isApprover());
|
||||
canExcludePages(file = this._activeFile): boolean {
|
||||
return ['UNDER_REVIEW', 'UNDER_APPROVAL'].includes(file.status) && (this.isFileReviewer(file) || this.isApprover());
|
||||
}
|
||||
|
||||
canDeleteComment(comment: Comment, fileStatus = this._activeFile) {
|
||||
return (comment.user === this._userService.currentUser.id || this.isApprover()) && !fileStatus.isApproved;
|
||||
canDeleteComment(comment: Comment, file = this._activeFile) {
|
||||
return (comment.user === this._userService.currentUser.id || this.isApprover()) && !file.isApproved;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,8 +4,8 @@ import {
|
||||
DossierTemplateControllerService,
|
||||
FileAttributesConfig,
|
||||
FileAttributesControllerService,
|
||||
FileStatus,
|
||||
IDossier,
|
||||
IFile,
|
||||
ReanalysisControllerService,
|
||||
StatusControllerService
|
||||
} from '@redaction/red-ui-http';
|
||||
@ -16,7 +16,7 @@ import { UserService } from '@services/user.service';
|
||||
import { forkJoin, Observable, of, Subject } from 'rxjs';
|
||||
import { catchError, map, tap } from 'rxjs/operators';
|
||||
import { FALLBACK_COLOR, hexToRgb } from '@utils/functions';
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { Dossier } from './model/dossier';
|
||||
import { TypeValue } from '@models/file/type-value';
|
||||
import { DossierTemplate } from '@models/file/dossier-template';
|
||||
@ -40,8 +40,8 @@ export interface AppState {
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AppStateService {
|
||||
readonly fileChanged$ = new Subject<FileStatusWrapper>();
|
||||
readonly fileReanalysed$ = new Subject<FileStatusWrapper>();
|
||||
readonly fileChanged$ = new Subject<File>();
|
||||
readonly fileReanalysed$ = new Subject<File>();
|
||||
readonly dossierChanged$ = new Subject<Dossier>();
|
||||
readonly dossierTemplateChanged$ = new Subject<DossierTemplate>();
|
||||
|
||||
@ -91,7 +91,7 @@ export class AppStateService {
|
||||
return this._dictionaryData;
|
||||
}
|
||||
|
||||
get aggregatedFiles(): FileStatusWrapper[] {
|
||||
get aggregatedFiles(): File[] {
|
||||
return this.allDossiers.reduce((acc, { files }) => [...acc, ...files], []);
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ export class AppStateService {
|
||||
return this.allDossiers?.length > 0;
|
||||
}
|
||||
|
||||
get activeFile(): FileStatusWrapper | undefined {
|
||||
get activeFile(): File | undefined {
|
||||
return this.activeDossier?.files.find(f => f.fileId === this.activeFileId);
|
||||
}
|
||||
|
||||
@ -242,7 +242,7 @@ export class AppStateService {
|
||||
const activeFile = await this._statusControllerService.getFileStatus(this.activeDossierId, this.activeFileId).toPromise();
|
||||
activeFile.dossierTemplateId = dossierTemplateId;
|
||||
|
||||
const activeFileWrapper = new FileStatusWrapper(
|
||||
const activeFileWrapper = new File(
|
||||
activeFile,
|
||||
this._userService.getNameForId(activeFile.currentReviewer),
|
||||
this.getFileAttributeConfig(activeFile.dossierTemplateId)
|
||||
@ -659,12 +659,12 @@ export class AppStateService {
|
||||
await this._userPreferenceService.saveLastOpenedFileForDossier(dossierId, fileId);
|
||||
}
|
||||
|
||||
private _getExistingFiles(dossierId: string): FileStatusWrapper[] {
|
||||
private _getExistingFiles(dossierId: string): File[] {
|
||||
const dossier = this.allDossiers.find(p => p.id === dossierId);
|
||||
return dossier?.files ?? [];
|
||||
}
|
||||
|
||||
private _processFiles(dossier: Dossier, files: FileStatus[], emitEvents: boolean = true) {
|
||||
private _processFiles(dossier: Dossier, files: IFile[], emitEvents: boolean = true) {
|
||||
const oldFiles = [...dossier.files];
|
||||
|
||||
const fileStatusChangedEvent = [];
|
||||
@ -677,7 +677,7 @@ export class AppStateService {
|
||||
for (const oldFile of oldFiles) {
|
||||
if (oldFile.fileId === file.fileId) {
|
||||
// emit when analysis count changed
|
||||
const fileStatusWrapper = new FileStatusWrapper(
|
||||
const fileStatusWrapper = new File(
|
||||
file,
|
||||
this._userService.getNameForId(file.currentReviewer),
|
||||
this.getFileAttributeConfig(file.dossierTemplateId)
|
||||
@ -696,7 +696,7 @@ export class AppStateService {
|
||||
}
|
||||
// emit for new file
|
||||
if (!found) {
|
||||
const fsw = new FileStatusWrapper(
|
||||
const fsw = new File(
|
||||
file,
|
||||
this._userService.getNameForId(file.currentReviewer),
|
||||
this.getFileAttributeConfig(file.dossierTemplateId)
|
||||
@ -707,11 +707,7 @@ export class AppStateService {
|
||||
|
||||
dossier.files = files.map(
|
||||
file =>
|
||||
new FileStatusWrapper(
|
||||
file,
|
||||
this._userService.getNameForId(file.currentReviewer),
|
||||
this.getFileAttributeConfig(file.dossierTemplateId)
|
||||
)
|
||||
new File(file, this._userService.getNameForId(file.currentReviewer), this.getFileAttributeConfig(file.dossierTemplateId))
|
||||
);
|
||||
this._computeStats();
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { Dictionary, DossierStatus, DownloadFileType, IDossier, List } from '@redaction/red-ui-http';
|
||||
import { IListable } from '@iqser/common-ui';
|
||||
|
||||
@ -36,7 +36,7 @@ export class Dossier implements IDossier, IListable {
|
||||
allFilesApproved?: boolean;
|
||||
type?: Dictionary;
|
||||
|
||||
constructor(dossier: IDossier, private _files: FileStatusWrapper[] = []) {
|
||||
constructor(dossier: IDossier, private _files: File[] = []) {
|
||||
this.id = dossier.dossierId;
|
||||
this.dossierId = dossier.dossierId;
|
||||
this.approverIds = dossier.approverIds;
|
||||
@ -63,11 +63,11 @@ export class Dossier implements IDossier, IListable {
|
||||
return this.dossierName;
|
||||
}
|
||||
|
||||
get files() {
|
||||
get files(): File[] {
|
||||
return this._files;
|
||||
}
|
||||
|
||||
set files(files: FileStatusWrapper[]) {
|
||||
set files(files: File[]) {
|
||||
this._files = files ? files : [];
|
||||
this._recomputeFileStatus();
|
||||
}
|
||||
@ -76,7 +76,7 @@ export class Dossier implements IDossier, IListable {
|
||||
return !!this._files.find(f => f.status === status);
|
||||
}
|
||||
|
||||
hasMember(memberId: string) {
|
||||
hasMember(memberId: string): boolean {
|
||||
return this.memberIds.indexOf(memberId) >= 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { FileUploadModel } from '@upload-download/model/file-upload.model';
|
||||
import { Dossier } from '../state/model/dossier';
|
||||
import { Dossier } from '@state/model/dossier';
|
||||
|
||||
export function handleFileDrop(event: DragEvent, dossier: Dossier, uploadFiles: (files: FileUploadModel[]) => void) {
|
||||
event.preventDefault();
|
||||
@ -30,6 +30,8 @@ export function isCsv(file: FileUploadModel): boolean {
|
||||
return file.file.type?.toLowerCase() === 'text/csv' || file.file.name.toLowerCase().endsWith('.csv');
|
||||
}
|
||||
|
||||
export type Files = FileList | File[];
|
||||
|
||||
export function convertFiles(files: FileList | File[], dossier: Dossier): FileUploadModel[] {
|
||||
let uploadFiles: FileUploadModel[] = [];
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { FileStatusWrapper } from '@models/file/file-status.wrapper';
|
||||
import { File } from '@models/file/file';
|
||||
import { Dossier } from '../state/model/dossier';
|
||||
import { handleCheckedValue, INestedFilter } from '@iqser/common-ui';
|
||||
|
||||
@ -45,7 +45,7 @@ export function handleFilterDelta(oldFilters: INestedFilter[], newFilters: INest
|
||||
});
|
||||
}
|
||||
|
||||
export const annotationFilterChecker = (input: FileStatusWrapper | Dossier, filter: INestedFilter) => {
|
||||
export const annotationFilterChecker = (input: File | Dossier, filter: INestedFilter) => {
|
||||
switch (filter.id) {
|
||||
case 'analysis': {
|
||||
if (input instanceof Dossier) {
|
||||
@ -67,13 +67,13 @@ export const annotationFilterChecker = (input: FileStatusWrapper | Dossier, filt
|
||||
return input.hasNone;
|
||||
}
|
||||
case 'updated': {
|
||||
return input instanceof FileStatusWrapper && input.hasUpdates;
|
||||
return input instanceof File && input.hasUpdates;
|
||||
}
|
||||
case 'image': {
|
||||
return input instanceof FileStatusWrapper && input.hasImages;
|
||||
return input instanceof File && input.hasImages;
|
||||
}
|
||||
case 'comment': {
|
||||
return input instanceof FileStatusWrapper && input.hasAnnotationComments;
|
||||
return input instanceof File && input.hasAnnotationComments;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
2
apps/red-ui/src/app/utils/types.d.ts
vendored
2
apps/red-ui/src/app/utils/types.d.ts
vendored
@ -1,3 +1,3 @@
|
||||
import { FileStatus } from '@redaction/red-ui-http';
|
||||
|
||||
export type Color = FileStatus.StatusEnum | DossierStatus.StatusEnum;
|
||||
export type Color = FileStatus | DossierStatus.StatusEnum;
|
||||
|
||||
@ -10,16 +10,16 @@
|
||||
* Do not edit the class manually.
|
||||
*/ /* tslint:disable:no-unused-variable member-ordering */
|
||||
|
||||
import { Inject, Injectable, Optional } from '@angular/core';
|
||||
import { HttpClient, HttpEvent, HttpHeaders, HttpParams, HttpResponse } from '@angular/common/http';
|
||||
import { CustomHttpUrlEncodingCodec } from '../encoder';
|
||||
import { Inject, Injectable, Optional } from "@angular/core";
|
||||
import { HttpClient, HttpEvent, HttpHeaders, HttpParams, HttpResponse } from "@angular/common/http";
|
||||
import { CustomHttpUrlEncodingCodec } from "../encoder";
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import { FileStatus } from '../model/fileStatus';
|
||||
import { IFile } from "../model/file";
|
||||
|
||||
import { BASE_PATH } from '../variables';
|
||||
import { Configuration } from '../configuration';
|
||||
import { BASE_PATH } from "../variables";
|
||||
import { Configuration } from "../configuration";
|
||||
|
||||
@Injectable()
|
||||
export class StatusControllerService {
|
||||
@ -48,13 +48,9 @@ export class StatusControllerService {
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public getDeletedFileStatus(dossierId: string, observe?: 'body', reportProgress?: boolean): Observable<Array<FileStatus>>;
|
||||
public getDeletedFileStatus(
|
||||
dossierId: string,
|
||||
observe?: 'response',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpResponse<Array<FileStatus>>>;
|
||||
public getDeletedFileStatus(dossierId: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<Array<FileStatus>>>;
|
||||
public getDeletedFileStatus(dossierId: string, observe?: 'body', reportProgress?: boolean): Observable<Array<IFile>>;
|
||||
public getDeletedFileStatus(dossierId: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<Array<IFile>>>;
|
||||
public getDeletedFileStatus(dossierId: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<Array<IFile>>>;
|
||||
public getDeletedFileStatus(dossierId: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
|
||||
if (dossierId === null || dossierId === undefined) {
|
||||
throw new Error('Required parameter dossierId was null or undefined when calling getDeletedFileStatus.');
|
||||
@ -76,7 +72,7 @@ export class StatusControllerService {
|
||||
headers = headers.set('Accept', httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<Array<FileStatus>>(
|
||||
return this.httpClient.request<Array<IFile>>(
|
||||
'get',
|
||||
`${this.basePath}/status/softdeleted/${encodeURIComponent(String(dossierId))}`,
|
||||
{
|
||||
@ -95,11 +91,11 @@ export class StatusControllerService {
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public getDossierStatus(dossierId: string, observe?: 'body', reportProgress?: boolean): Observable<Array<FileStatus>>;
|
||||
public getDossierStatus(dossierId: string, observe?: 'body', reportProgress?: boolean): Observable<Array<IFile>>;
|
||||
|
||||
public getDossierStatus(dossierId: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<Array<FileStatus>>>;
|
||||
public getDossierStatus(dossierId: string, observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<Array<IFile>>>;
|
||||
|
||||
public getDossierStatus(dossierId: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<Array<FileStatus>>>;
|
||||
public getDossierStatus(dossierId: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<Array<IFile>>>;
|
||||
|
||||
public getDossierStatus(dossierId: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
|
||||
if (dossierId === null || dossierId === undefined) {
|
||||
@ -122,7 +118,7 @@ export class StatusControllerService {
|
||||
headers = headers.set('Accept', httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<Array<FileStatus>>('get', `${this.basePath}/status/${encodeURIComponent(String(dossierId))}`, {
|
||||
return this.httpClient.request<Array<IFile>>('get', `${this.basePath}/status/${encodeURIComponent(String(dossierId))}`, {
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
observe: observe,
|
||||
@ -138,21 +134,16 @@ export class StatusControllerService {
|
||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
||||
* @param reportProgress flag to report request and response progress.
|
||||
*/
|
||||
public getFileStatus(dossierId: string, fileId: string, observe?: 'body', reportProgress?: boolean): Observable<FileStatus>;
|
||||
public getFileStatus(dossierId: string, fileId: string, observe?: 'body', reportProgress?: boolean): Observable<IFile>;
|
||||
|
||||
public getFileStatus(
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
observe?: 'response',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpResponse<FileStatus>>;
|
||||
): Observable<HttpResponse<IFile>>;
|
||||
|
||||
public getFileStatus(
|
||||
dossierId: string,
|
||||
fileId: string,
|
||||
observe?: 'events',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpEvent<FileStatus>>;
|
||||
public getFileStatus(dossierId: string, fileId: string, observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<IFile>>;
|
||||
|
||||
public getFileStatus(dossierId: string, fileId: string, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
|
||||
if (dossierId === null || dossierId === undefined) {
|
||||
@ -179,7 +170,7 @@ export class StatusControllerService {
|
||||
headers = headers.set('Accept', httpHeaderAcceptSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<FileStatus>(
|
||||
return this.httpClient.request<IFile>(
|
||||
'get',
|
||||
`${this.basePath}/status/${encodeURIComponent(String(dossierId))}/${encodeURIComponent(String(fileId))}`,
|
||||
{
|
||||
@ -202,19 +193,19 @@ export class StatusControllerService {
|
||||
body: Array<string>,
|
||||
observe?: 'body',
|
||||
reportProgress?: boolean
|
||||
): Observable<{ [key: string]: Array<FileStatus> }>;
|
||||
): Observable<{ [key: string]: Array<IFile> }>;
|
||||
|
||||
public getFileStatusForDossiers(
|
||||
body: Array<string>,
|
||||
observe?: 'response',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpResponse<{ [key: string]: Array<FileStatus> }>>;
|
||||
): Observable<HttpResponse<{ [key: string]: Array<IFile> }>>;
|
||||
|
||||
public getFileStatusForDossiers(
|
||||
body: Array<string>,
|
||||
observe?: 'events',
|
||||
reportProgress?: boolean
|
||||
): Observable<HttpEvent<{ [key: string]: Array<FileStatus> }>>;
|
||||
): Observable<HttpEvent<{ [key: string]: Array<IFile> }>>;
|
||||
|
||||
public getFileStatusForDossiers(body: Array<string>, observe: any = 'body', reportProgress: boolean = false): Observable<any> {
|
||||
if (body === null || body === undefined) {
|
||||
@ -244,7 +235,7 @@ export class StatusControllerService {
|
||||
headers = headers.set('Content-Type', httpContentTypeSelected);
|
||||
}
|
||||
|
||||
return this.httpClient.request<{ [key: string]: Array<FileStatus> }>('post', `${this.basePath}/status`, {
|
||||
return this.httpClient.request<{ [key: string]: Array<IFile> }>('post', `${this.basePath}/status`, {
|
||||
body: body,
|
||||
withCredentials: this.configuration.withCredentials,
|
||||
headers: headers,
|
||||
|
||||
@ -14,43 +14,43 @@ import { FileAttributes } from './fileAttributes';
|
||||
/**
|
||||
* Object containing information on a specific file.
|
||||
*/
|
||||
export interface FileStatus {
|
||||
export interface IFile {
|
||||
/**
|
||||
* Date and time when the file was added to the system.
|
||||
*/
|
||||
added?: string;
|
||||
readonly added?: string;
|
||||
/**
|
||||
* Shows if all manual changes have been applied by a reanalysis.
|
||||
*/
|
||||
allManualRedactionsApplied?: boolean;
|
||||
readonly allManualRedactionsApplied?: boolean;
|
||||
/**
|
||||
* Shows how long the last analysis took
|
||||
*/
|
||||
analysisDuration?: number;
|
||||
readonly analysisDuration?: number;
|
||||
/**
|
||||
* Shows if the file requires reanalysis.
|
||||
*/
|
||||
analysisRequired?: boolean;
|
||||
readonly analysisRequired?: boolean;
|
||||
/**
|
||||
* Shows the date of approval, if approved.
|
||||
*/
|
||||
approvalDate?: string;
|
||||
readonly approvalDate?: string;
|
||||
/**
|
||||
* The current reviewer's (if any) user id.
|
||||
*/
|
||||
currentReviewer?: string;
|
||||
readonly currentReviewer?: string;
|
||||
/**
|
||||
* Shows which dictionary versions was used during the analysis.
|
||||
*/
|
||||
dictionaryVersion?: number;
|
||||
readonly dictionaryVersion?: number;
|
||||
/**
|
||||
* Shows which dossier dictionary versions was used during the analysis.
|
||||
*/
|
||||
dossierDictionaryVersion?: number;
|
||||
readonly dossierDictionaryVersion?: number;
|
||||
/**
|
||||
* The ID of the dossier the file belongs to.
|
||||
*/
|
||||
dossierId?: string;
|
||||
readonly dossierId?: string;
|
||||
/**
|
||||
* The dossierTemplateId for this file.
|
||||
*/
|
||||
@ -58,130 +58,116 @@ export interface FileStatus {
|
||||
/**
|
||||
* Shows if the file was excluded from analysis.
|
||||
*/
|
||||
excluded?: boolean;
|
||||
readonly excluded?: boolean;
|
||||
/**
|
||||
* Set of excluded pages for this file.
|
||||
*/
|
||||
excludedPages?: Array<number>;
|
||||
readonly excludedPages?: Array<number>;
|
||||
fileAttributes?: FileAttributes;
|
||||
/**
|
||||
* The ID of the file.
|
||||
*/
|
||||
fileId?: string;
|
||||
readonly fileId?: string;
|
||||
/**
|
||||
* The file's name.
|
||||
*/
|
||||
filename?: string;
|
||||
readonly filename?: string;
|
||||
/**
|
||||
* Shows if this file has comments on annotations.
|
||||
*/
|
||||
hasAnnotationComments?: boolean;
|
||||
readonly hasAnnotationComments?: boolean;
|
||||
/**
|
||||
* Shows if any hints were found during the analysis.
|
||||
*/
|
||||
hasHints?: boolean;
|
||||
readonly hasHints?: boolean;
|
||||
/**
|
||||
* Shows if any images were found during the analysis.
|
||||
*/
|
||||
hasImages?: boolean;
|
||||
readonly hasImages?: boolean;
|
||||
/**
|
||||
* Shows if any redactions were found during the analysis.
|
||||
*/
|
||||
hasRedactions?: boolean;
|
||||
readonly hasRedactions?: boolean;
|
||||
/**
|
||||
* Shows if any requests were found during the analysis.
|
||||
*/
|
||||
hasRequests?: boolean;
|
||||
readonly hasRequests?: boolean;
|
||||
/**
|
||||
* Shows if there are any Suggestions in this file.
|
||||
*/
|
||||
hasSuggestions?: boolean;
|
||||
readonly hasSuggestions?: boolean;
|
||||
/**
|
||||
* Shows if there is any change between the previous and current analysis.
|
||||
*/
|
||||
hasUpdates?: boolean;
|
||||
readonly hasUpdates?: boolean;
|
||||
/**
|
||||
* Date and time when the files attributes was last updated.
|
||||
*/
|
||||
lastFileAttributeChange?: string;
|
||||
readonly lastFileAttributeChange?: string;
|
||||
/**
|
||||
* Shows if this file has been OCRed by us. Last Time of OCR.
|
||||
*/
|
||||
lastOCRTime?: string;
|
||||
readonly lastOCRTime?: string;
|
||||
/**
|
||||
* Shows the last date of a successful analysis.
|
||||
*/
|
||||
lastProcessed?: string;
|
||||
readonly lastProcessed?: string;
|
||||
/**
|
||||
* The last reviewer's (if any) user id.
|
||||
*/
|
||||
lastReviewer?: string;
|
||||
readonly lastReviewer?: string;
|
||||
/**
|
||||
* Date and time when the file was last updated.
|
||||
*/
|
||||
lastUpdated?: string;
|
||||
readonly lastUpdated?: string;
|
||||
/**
|
||||
* Shows last date the document was uploaded.
|
||||
*/
|
||||
lastUploaded?: string;
|
||||
readonly lastUploaded?: string;
|
||||
/**
|
||||
* Shows which legal basis versions was used during the analysis.
|
||||
*/
|
||||
legalBasisVersion?: number;
|
||||
readonly legalBasisVersion?: number;
|
||||
/**
|
||||
* The number of times the file has been analyzed.
|
||||
*/
|
||||
numberOfAnalyses?: number;
|
||||
readonly numberOfAnalyses?: number;
|
||||
/**
|
||||
* The number of pages of the file.
|
||||
*/
|
||||
numberOfPages?: number;
|
||||
readonly numberOfPages?: number;
|
||||
/**
|
||||
* Shows which rules versions was used during the analysis.
|
||||
*/
|
||||
rulesVersion?: number;
|
||||
readonly rulesVersion?: number;
|
||||
/**
|
||||
* Shows if the file is soft deleted.
|
||||
*/
|
||||
softDeleted?: string;
|
||||
readonly softDeleted?: string;
|
||||
/**
|
||||
* The status of the file with regard to its analysis an review processes.
|
||||
*/
|
||||
status?: FileStatus.StatusEnum;
|
||||
readonly status?: FileStatus;
|
||||
/**
|
||||
* The ID of the user who uploaded the file.
|
||||
*/
|
||||
uploader?: string;
|
||||
readonly uploader?: string;
|
||||
}
|
||||
|
||||
export namespace FileStatus {
|
||||
export type StatusEnum =
|
||||
| 'APPROVED'
|
||||
| 'DELETED'
|
||||
| 'ERROR'
|
||||
| 'EXCLUDED'
|
||||
| 'FULLREPROCESS'
|
||||
| 'INDEXING'
|
||||
| 'OCR_PROCESSING'
|
||||
| 'PROCESSING'
|
||||
| 'REPROCESS'
|
||||
| 'UNASSIGNED'
|
||||
| 'UNDER_APPROVAL'
|
||||
| 'UNDER_REVIEW'
|
||||
| 'UNPROCESSED';
|
||||
export const StatusEnum = {
|
||||
APPROVED: 'APPROVED' as StatusEnum,
|
||||
DELETED: 'DELETED' as StatusEnum,
|
||||
ERROR: 'ERROR' as StatusEnum,
|
||||
EXCLUDED: 'EXCLUDED' as StatusEnum,
|
||||
FULLREPROCESS: 'FULLREPROCESS' as StatusEnum,
|
||||
INDEXING: 'INDEXING' as StatusEnum,
|
||||
OCRPROCESSING: 'OCR_PROCESSING' as StatusEnum,
|
||||
PROCESSING: 'PROCESSING' as StatusEnum,
|
||||
REPROCESS: 'REPROCESS' as StatusEnum,
|
||||
UNASSIGNED: 'UNASSIGNED' as StatusEnum,
|
||||
UNDERAPPROVAL: 'UNDER_APPROVAL' as StatusEnum,
|
||||
UNDERREVIEW: 'UNDER_REVIEW' as StatusEnum,
|
||||
UNPROCESSED: 'UNPROCESSED' as StatusEnum
|
||||
} as const;
|
||||
}
|
||||
export const FileStatuses = {
|
||||
APPROVED: 'APPROVED',
|
||||
DELETED: 'DELETED',
|
||||
ERROR: 'ERROR',
|
||||
EXCLUDED: 'EXCLUDED',
|
||||
FULLREPROCESS: 'FULLREPROCESS',
|
||||
INDEXING: 'INDEXING',
|
||||
OCR_PROCESSING: 'OCR_PROCESSING',
|
||||
PROCESSING: 'PROCESSING',
|
||||
REPROCESS: 'REPROCESS',
|
||||
UNASSIGNED: 'UNASSIGNED',
|
||||
UNDER_APPROVAL: 'UNDER_APPROVAL',
|
||||
UNDER_REVIEW: 'UNDER_REVIEW',
|
||||
UNPROCESSED: 'UNPROCESSED'
|
||||
} as const;
|
||||
|
||||
export type FileStatus = keyof typeof FileStatuses;
|
||||
@ -31,7 +31,7 @@ export * from './downloadStatusResponse';
|
||||
export * from './fileAttributeConfig';
|
||||
export * from './fileAttributes';
|
||||
export * from './fileAttributesConfig';
|
||||
export * from './fileStatus';
|
||||
export * from './file';
|
||||
export * from './fileUploadResult';
|
||||
export * from './forceRedactionRequest';
|
||||
export * from './generalConfigurationModel';
|
||||
|
||||
@ -41,12 +41,12 @@ export namespace ReportData {
|
||||
ERROR: 'ERROR' as StatusEnum,
|
||||
EXCLUDED: 'EXCLUDED' as StatusEnum,
|
||||
FULLREPROCESS: 'FULLREPROCESS' as StatusEnum,
|
||||
OCRPROCESSING: 'OCR_PROCESSING' as StatusEnum,
|
||||
OCR_PROCESSING: 'OCR_PROCESSING' as StatusEnum,
|
||||
PROCESSING: 'PROCESSING' as StatusEnum,
|
||||
REPROCESS: 'REPROCESS' as StatusEnum,
|
||||
UNASSIGNED: 'UNASSIGNED' as StatusEnum,
|
||||
UNDERAPPROVAL: 'UNDER_APPROVAL' as StatusEnum,
|
||||
UNDERREVIEW: 'UNDER_REVIEW' as StatusEnum,
|
||||
UNDER_APPROVAL: 'UNDER_APPROVAL' as StatusEnum,
|
||||
UNDER_REVIEW: 'UNDER_REVIEW' as StatusEnum,
|
||||
UNPROCESSED: 'UNPROCESSED' as StatusEnum
|
||||
};
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
"lint": "nx workspace-lint && nx lint",
|
||||
"lint-fix": "nx workspace-lint --fix && nx lint --fix",
|
||||
"nx": "nx",
|
||||
"start": "nx serve",
|
||||
"start": "nx serve --hmr",
|
||||
"test": "nx test",
|
||||
"update": "nx migrate latest",
|
||||
"migrate": "nx migrate --run-migrations",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user