remove files related methods from app state
This commit is contained in:
parent
fd00fddc42
commit
59b9e69458
@ -5,6 +5,7 @@ import { BreadcrumbsService } from '../services/breadcrumbs.service';
|
||||
import { pluck } from 'rxjs/operators';
|
||||
import { AppStateService } from '../state/app-state.service';
|
||||
import { FilesMapService } from '../services/entity-services/files-map.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class DossierFilesGuard implements CanActivate, CanDeactivate<unknown> {
|
||||
@ -13,20 +14,20 @@ export class DossierFilesGuard implements CanActivate, CanDeactivate<unknown> {
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _breadcrumbsService: BreadcrumbsService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _router: Router,
|
||||
) {}
|
||||
|
||||
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
|
||||
const dossierId = route.paramMap.get('dossierId');
|
||||
const dossier = this._dossiersService.find(dossierId);
|
||||
|
||||
if (!dossier) {
|
||||
if (!this._dossiersService.has(dossierId)) {
|
||||
await this._router.navigate(['/main', 'dossiers']);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this._filesMapService.has(dossierId)) {
|
||||
await this._appStateService.getFiles(dossier);
|
||||
await this._filesService.loadAll(dossierId).toPromise();
|
||||
}
|
||||
|
||||
this._breadcrumbsService.append({
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
(remove)="toggleSelected($event)"
|
||||
[canAdd]="false"
|
||||
[canRemove]="true"
|
||||
[dossierId]="dossier.dossierId"
|
||||
[largeSpacing]="true"
|
||||
[memberIds]="selectedApproversList"
|
||||
[perLine]="13"
|
||||
@ -27,6 +28,7 @@
|
||||
(remove)="toggleSelected($event)"
|
||||
[canAdd]="false"
|
||||
[canRemove]="true"
|
||||
[dossierId]="dossier.dossierId"
|
||||
[largeSpacing]="true"
|
||||
[memberIds]="selectedReviewers$ | async"
|
||||
[perLine]="13"
|
||||
|
||||
@ -19,7 +19,6 @@ import { getLeftDateTime } from '@utils/functions';
|
||||
import { Observable } from 'rxjs';
|
||||
import { distinctUntilChanged, map } from 'rxjs/operators';
|
||||
import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
import { FileManagementService } from '../../../shared/services/file-management.service';
|
||||
|
||||
@ -56,7 +55,6 @@ export class EditDossierDeletedDocumentsComponent extends ListingComponent<FileL
|
||||
constructor(
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _fileManagementService: FileManagementService,
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _configService: ConfigService,
|
||||
@ -115,7 +113,7 @@ export class EditDossierDeletedDocumentsComponent extends ListingComponent<FileL
|
||||
const fileIds = files.map(f => f.fileId);
|
||||
await this._fileManagementService.restore(fileIds, this.dossier.id).toPromise();
|
||||
this._removeFromList(fileIds);
|
||||
await this._appStateService.reloadDossierFiles(files[0].dossierId);
|
||||
await this._filesService.loadAll(files[0].dossierId).toPromise();
|
||||
this.updateDossier.emit();
|
||||
}
|
||||
|
||||
|
||||
@ -34,15 +34,15 @@
|
||||
|
||||
<div>
|
||||
<mat-icon svgIcon="red:template"></mat-icon>
|
||||
<span>{{ dossierTemplate(dossier).name }} </span>
|
||||
<span>{{ dossierTemplateName }} </span>
|
||||
</div>
|
||||
|
||||
<div (click)="openDossierDictionaryDialog.emit()" class="link-property">
|
||||
<div (click)="openEditDossierDialog('dossierDictionary')" class="link-property">
|
||||
<mat-icon svgIcon="red:dictionary"></mat-icon>
|
||||
<span>{{ 'dossier-overview.dossier-details.dictionary' | translate }} </span>
|
||||
</div>
|
||||
|
||||
<div (click)="openEditDossierAttributesDialog(dossier.dossierId, 'deletedDocuments')" class="link-property">
|
||||
<div (click)="openEditDossierDialog('deletedDocuments')" class="link-property">
|
||||
<mat-icon svgIcon="iqser:trash"></mat-icon>
|
||||
<span>{{ 'dossier-overview.dossier-details.stats.deleted' | translate: { count: deletedFilesCount$ | async } }}</span>
|
||||
</div>
|
||||
@ -53,11 +53,7 @@
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="attributesExpanded">
|
||||
<div
|
||||
(click)="openEditDossierAttributesDialog(dossier.dossierId, 'dossierAttributes')"
|
||||
*ngFor="let attr of dossierAttributes"
|
||||
class="link-property"
|
||||
>
|
||||
<div (click)="openEditDossierDialog('dossierAttributes')" *ngFor="let attr of dossierAttributes" class="link-property">
|
||||
<mat-icon svgIcon="red:attribute"></mat-icon>
|
||||
<span *ngIf="!attr.value"> {{ attr.label + ': -' }}</span>
|
||||
<span *ngIf="attr.value && attr.type === 'DATE'"> {{ attr.label + ': ' + (attr.value | date: 'd MMM. yyyy') }}</span>
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { Dossier, DossierAttributeWithValue, DossierStats, DossierTemplate } from '@red/domain';
|
||||
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
|
||||
import { Dossier, DossierAttributeWithValue, DossierStats } from '@red/domain';
|
||||
import { DossiersDialogService } from '../../../../services/dossiers-dialog.service';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
import { Observable } from 'rxjs';
|
||||
@ -13,17 +12,16 @@ import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
selector: 'redaction-dossier-details-stats',
|
||||
templateUrl: './dossier-details-stats.component.html',
|
||||
styleUrls: ['./dossier-details-stats.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DossierDetailsStatsComponent implements OnInit {
|
||||
@Input() dossierAttributes: DossierAttributeWithValue[];
|
||||
@Input() dossier: Dossier;
|
||||
|
||||
attributesExpanded = false;
|
||||
dossierTemplateName: string;
|
||||
deletedFilesCount$: Observable<number>;
|
||||
dossierStats$: Observable<DossierStats>;
|
||||
@Input()
|
||||
dossierAttributes: DossierAttributeWithValue[];
|
||||
@Input()
|
||||
dossier: Dossier;
|
||||
@Output()
|
||||
readonly openDossierDictionaryDialog = new EventEmitter();
|
||||
|
||||
constructor(
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
@ -31,7 +29,6 @@ export class DossierDetailsStatsComponent implements OnInit {
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _dossierStatsService: DossierStatsService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
readonly dossiersService: DossiersService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@ -40,16 +37,13 @@ export class DossierDetailsStatsComponent implements OnInit {
|
||||
switchMapTo(this._filesService.getDeletedFilesFor(this.dossier.id)),
|
||||
map(files => files.length),
|
||||
);
|
||||
this.dossierTemplateName = this._dossierTemplatesService.find(this.dossier.dossierTemplateId).name;
|
||||
}
|
||||
|
||||
dossierTemplate(dossier: Dossier): DossierTemplate {
|
||||
return this._dossierTemplatesService.find(dossier.dossierTemplateId);
|
||||
}
|
||||
|
||||
openEditDossierAttributesDialog(dossierId: string, section: string) {
|
||||
this._dialogService.openDialog('editDossier', null, {
|
||||
dossierId,
|
||||
section: section,
|
||||
openEditDossierDialog(section: string): void {
|
||||
const data = { dossierId: this.dossier.dossierId, section };
|
||||
this._dialogService.openDialog('editDossier', null, data, async () => {
|
||||
await this._filesService.loadAll(this.dossier.dossierId).toPromise();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,11 +32,7 @@
|
||||
|
||||
<div class="mt-16">
|
||||
<div class="all-caps-label" translate="dossier-details.members"></div>
|
||||
<redaction-team-members
|
||||
(openAssignDossierMembersDialog)="openEditDossierDialog(dossier, 'members')"
|
||||
[memberIds]="dossier.memberIds"
|
||||
[perLine]="9"
|
||||
></redaction-team-members>
|
||||
<redaction-team-members [dossierId]="dossierId" [memberIds]="dossier.memberIds" [perLine]="9"></redaction-team-members>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="dossierStats$ | async as stats">
|
||||
@ -65,11 +61,7 @@
|
||||
</div>
|
||||
|
||||
<div [class.mt-24]="!stats.hasFiles" class="pb-32">
|
||||
<redaction-dossier-details-stats
|
||||
(openDossierDictionaryDialog)="openEditDossierDialog(dossier, 'dossierDictionary')"
|
||||
[dossierAttributes]="dossierAttributes"
|
||||
[dossier]="dossier"
|
||||
></redaction-dossier-details-stats>
|
||||
<redaction-dossier-details-stats [dossierAttributes]="dossierAttributes" [dossier]="dossier"></redaction-dossier-details-stats>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ import { Observable } from 'rxjs';
|
||||
import { DossierStatsService } from '@services/entity-services/dossier-stats.service';
|
||||
import { pluck, switchMap } from 'rxjs/operators';
|
||||
import { DossiersDialogService } from '../../../../services/dossiers-dialog.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossier-details',
|
||||
@ -40,6 +41,7 @@ export class DossierDetailsComponent {
|
||||
readonly filterService: FilterService,
|
||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _dossierStatsService: DossierStatsService,
|
||||
private readonly _toaster: Toaster,
|
||||
private readonly _dialogService: DossiersDialogService,
|
||||
@ -77,11 +79,4 @@ export class DossierDetailsComponent {
|
||||
const dossierName = dossier.dossierName;
|
||||
this._toaster.info(_('assignment.owner'), { params: { ownerName, dossierName } });
|
||||
}
|
||||
|
||||
openEditDossierDialog(dossier: Dossier, section: string): void {
|
||||
const data = { dossierId: this.dossierId, section };
|
||||
this._dialogService.openDialog('editDossier', null, data, async () => {
|
||||
await this.appStateService.getFiles(dossier);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="file.primaryAttribute" class="small-label">
|
||||
<div *ngIf="primaryAttribute" class="small-label">
|
||||
<div class="primary-attribute">
|
||||
<span [matTooltip]="file.primaryAttribute" matTooltipPosition="above">
|
||||
{{ file.primaryAttribute }}
|
||||
<span [matTooltip]="primaryAttribute" matTooltipPosition="above">
|
||||
{{ primaryAttribute }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
|
||||
import { File } from '@red/domain';
|
||||
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-name-column',
|
||||
@ -7,6 +8,24 @@ import { File } from '@red/domain';
|
||||
styleUrls: ['./file-name-column.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class FileNameColumnComponent {
|
||||
export class FileNameColumnComponent implements OnChanges {
|
||||
@Input() file: File;
|
||||
@Input() dossierTemplateId: string;
|
||||
primaryAttribute: string;
|
||||
|
||||
constructor(private readonly _fileAttributesService: FileAttributesService) {}
|
||||
|
||||
ngOnChanges() {
|
||||
const fileAttributesConfig = this._fileAttributesService.getFileAttributeConfig(this.dossierTemplateId);
|
||||
if (fileAttributesConfig) {
|
||||
const primary = fileAttributesConfig.fileAttributeConfigs?.find(c => c.primaryAttribute);
|
||||
if (primary && this.file.fileAttributes?.attributeIdToValue) {
|
||||
this.primaryAttribute = this.file.fileAttributes?.attributeIdToValue[primary.id];
|
||||
}
|
||||
|
||||
if (!this.primaryAttribute) {
|
||||
this.primaryAttribute = '-';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<div class="cell">
|
||||
<redaction-file-name-column [file]="file"></redaction-file-name-column>
|
||||
<redaction-file-name-column [dossierTemplateId]="dossierTemplateId" [file]="file"></redaction-file-name-column>
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
|
||||
@ -11,5 +11,6 @@ import { Required } from '@iqser/common-ui';
|
||||
export class TableItemComponent {
|
||||
@Input() @Required() file!: File;
|
||||
@Input() @Required() displayedAttributes!: IFileAttributeConfig[];
|
||||
@Input() dossierTemplateId: string;
|
||||
@Output() readonly calculateData = new EventEmitter<string>();
|
||||
}
|
||||
|
||||
@ -56,6 +56,15 @@
|
||||
<ng-template #bulkActions>
|
||||
<redaction-dossier-overview-bulk-actions (reload)="reloadFiles()" [dossier]="dossier"></redaction-dossier-overview-bulk-actions>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #tableItemTemplate let-file="entity">
|
||||
<redaction-table-item
|
||||
(calculateData)="actionPerformed($event)"
|
||||
[displayedAttributes]="displayedAttributes"
|
||||
[dossierTemplateId]="dossier.dossierTemplateId"
|
||||
[file]="file"
|
||||
></redaction-table-item>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
|
||||
<ng-template #needsWorkFilterTemplate let-filter="filter">
|
||||
@ -64,14 +73,6 @@
|
||||
|
||||
<input #fileInput (change)="uploadFiles($event.target['files'])" class="file-upload-input" multiple="true" type="file" />
|
||||
|
||||
<ng-template #tableItemTemplate let-file="entity">
|
||||
<redaction-table-item
|
||||
(calculateData)="actionPerformed($event)"
|
||||
[displayedAttributes]="displayedAttributes"
|
||||
[file]="file"
|
||||
></redaction-table-item>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #workflowItemTemplate let-entity="entity">
|
||||
<redaction-workflow-item (actionPerformed)="actionPerformed($event, entity)" [file]="entity"></redaction-workflow-item>
|
||||
</ng-template>
|
||||
|
||||
@ -46,7 +46,6 @@ import { DossierTemplatesService } from '@services/entity-services/dossier-templ
|
||||
import { LongPressEvent } from '@shared/directives/long-press.directive';
|
||||
import { UserPreferenceService } from '@services/user-preference.service';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
import { DossierStatsService } from '@services/entity-services/dossier-stats.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
|
||||
@Component({
|
||||
@ -94,7 +93,6 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
readonly configService: ConfigService,
|
||||
private readonly _userPreferenceService: UserPreferenceService,
|
||||
private readonly _fileMapService: FilesMapService,
|
||||
private readonly _dossierStatsService: DossierStatsService,
|
||||
activatedRoute: ActivatedRoute,
|
||||
) {
|
||||
super(_injector);
|
||||
@ -205,8 +203,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
}
|
||||
|
||||
async reloadFiles() {
|
||||
await this._appStateService.getFiles(this.currentDossier);
|
||||
await this._dossierStatsService.getFor([this.dossierId]).toPromise();
|
||||
await this._filesService.loadAll(this.dossierId).toPromise();
|
||||
this._computeAllFilters();
|
||||
}
|
||||
|
||||
|
||||
@ -367,7 +367,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
response.manualRedactionEntryWrapper.rectId,
|
||||
);
|
||||
this._instance.Core.annotationManager.deleteAnnotation(annotation);
|
||||
await this.appStateService.reloadFile(this.dossierId, this.fileId);
|
||||
await this._filesService.reload(this.dossierId, this.fileId);
|
||||
const distinctPages = manualRedactionEntryWrapper.manualRedactionEntry.positions
|
||||
.map(p => p.page)
|
||||
.filter((item, pos, self) => self.indexOf(item) === pos);
|
||||
@ -475,11 +475,11 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
case 'reanalyse':
|
||||
await this._loadFileData(true);
|
||||
this._updateCanPerformActions();
|
||||
await this.appStateService.reloadDossierFiles(this.dossierId);
|
||||
await this._filesService.loadAll(this.dossierId).toPromise();
|
||||
return;
|
||||
|
||||
case 'exclude-pages':
|
||||
await this.appStateService.reloadDossierFiles(this.dossierId);
|
||||
await this._filesService.loadAll(this.dossierId).toPromise();
|
||||
await this._loadFileData(true);
|
||||
this._cleanupAndRedrawManualAnnotations$();
|
||||
await this._stampPDF();
|
||||
@ -508,7 +508,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
async assignToMe(file: File) {
|
||||
await this._fileActionService.assignToMe([file], async () => {
|
||||
await this.appStateService.reloadFile(this.dossierId, this.fileId);
|
||||
await this._filesService.reload(this.dossierId, this.fileId);
|
||||
this._updateCanPerformActions();
|
||||
});
|
||||
}
|
||||
@ -521,7 +521,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
await this._filesService.setReviewerFor([fileId], dossierId, reviewerId).toPromise();
|
||||
|
||||
this._toaster.info(_('assignment.reviewer'), { params: { reviewerName, filename } });
|
||||
await this.appStateService.reloadFile(this.dossierId, this.fileId);
|
||||
await this._filesService.reload(this.dossierId, this.fileId);
|
||||
this._updateCanPerformActions();
|
||||
this.editingReviewer = false;
|
||||
}
|
||||
@ -617,7 +617,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
|
||||
private _subscribeToFileUpdates(): void {
|
||||
this.addSubscription = timer(0, 5000)
|
||||
.pipe(switchMap(() => this.appStateService.reloadFile(this.dossierId, this.fileId)))
|
||||
.pipe(switchMap(() => this._filesService.reload(this.dossierId, this.fileId)))
|
||||
.subscribe();
|
||||
this.addSubscription = this._filesMapService.fileReanalysed$
|
||||
.pipe(filter(file => file.fileId === this.fileId))
|
||||
@ -679,7 +679,7 @@ export class FilePreviewScreenComponent extends AutoUnsubscribe implements OnIni
|
||||
const currentPageAnnotations = this.annotations.filter(a => a.pageNumber === page);
|
||||
const currentPageAnnotationIds = currentPageAnnotations.map(a => a.id);
|
||||
|
||||
await this.appStateService.reloadFile(this.dossierId, this.fileId);
|
||||
await this._filesService.reload(this.dossierId, this.fileId);
|
||||
this.fileData.redactionLog = await this._fileDownloadService.loadRedactionLogFor(this.dossierId, this.fileId).toPromise();
|
||||
|
||||
this.rebuildFilters();
|
||||
|
||||
@ -20,6 +20,7 @@ import { LongPressEvent } from '@shared/directives/long-press.directive';
|
||||
import { FileActionService } from '../../services/file-action.service';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { FileManagementService } from '../../services/file-management.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-actions',
|
||||
@ -70,6 +71,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
private readonly _fileActionService: FileActionService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _fileManagementService: FileManagementService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _toaster: Toaster,
|
||||
private readonly _userPreferenceService: UserPreferenceService,
|
||||
@ -117,7 +119,7 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
.catch(error => {
|
||||
this._toaster.error(_('error.http.generic'), { params: error });
|
||||
});
|
||||
await this.appStateService.reloadDossierFiles(this.file.dossierId);
|
||||
await this._filesService.loadAll(this.file.dossierId).toPromise();
|
||||
this.actionPerformed.emit('delete');
|
||||
this._loadingService.stop();
|
||||
},
|
||||
@ -191,14 +193,17 @@ export class FileActionsComponent extends AutoUnsubscribe implements OnDestroy,
|
||||
}
|
||||
|
||||
reloadFiles(action: string) {
|
||||
this.appStateService.getFiles(this.dossiersService.find(this.file.dossierId)).then(() => {
|
||||
this.actionPerformed.emit(action);
|
||||
});
|
||||
this._filesService
|
||||
.loadAll(this.file.dossierId)
|
||||
.toPromise()
|
||||
.then(() => {
|
||||
this.actionPerformed.emit(action);
|
||||
});
|
||||
}
|
||||
|
||||
async toggleAnalysis() {
|
||||
await this._fileActionService.toggleAnalysis(this.file).toPromise();
|
||||
await this.appStateService.getFiles(this.dossiersService.find(this.file.dossierId));
|
||||
await this._filesService.loadAll(this.file.dossierId).toPromise();
|
||||
this.actionPerformed.emit(this.file?.excluded ? 'enable-analysis' : 'disable-analysis');
|
||||
}
|
||||
|
||||
|
||||
@ -3,15 +3,15 @@ import { GenericService } from '@iqser/common-ui';
|
||||
import { IMatchedDocument, ISearchInput, ISearchRequest, ISearchResponse } from '@red/domain';
|
||||
import { Observable, of, zip } from 'rxjs';
|
||||
import { mapTo, switchMap } from 'rxjs/operators';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
|
||||
@Injectable()
|
||||
export class PlatformSearchService extends GenericService<ISearchResponse> {
|
||||
constructor(
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
) {
|
||||
@ -47,7 +47,6 @@ export class PlatformSearchService extends GenericService<ISearchResponse> {
|
||||
}
|
||||
|
||||
private _loadFilesFor$(dossierIds: string[]) {
|
||||
const dossiers = dossierIds.map(dossierId => this._dossiersService.find(dossierId));
|
||||
return zip(...dossiers.map(dossier => this._appStateService.getFiles(dossier)));
|
||||
return zip(...dossierIds.map(dossierId => this._filesService.loadAll(dossierId)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,15 +7,18 @@
|
||||
class="member"
|
||||
>
|
||||
<redaction-initials-avatar [user]="userId" color="gray" size="large"></redaction-initials-avatar>
|
||||
|
||||
<div *ngIf="canRemoveMember(userId)" class="remove">
|
||||
<mat-icon svgIcon="iqser:close"></mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="overflowCount && !expandedTeam" [class.large-spacing]="largeSpacing" class="member pointer">
|
||||
<div (click)="toggleExpandedTeam()" class="oval large white-dark">+{{ overflowCount }}</div>
|
||||
</div>
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="openAssignDossierMembersDialog.emit()"
|
||||
(action)="openEditDossierDialog()"
|
||||
*ngIf="currentUser.isManager && canAdd"
|
||||
[class.large-spacing]="largeSpacing"
|
||||
[size]="32"
|
||||
@ -26,4 +29,5 @@
|
||||
iqserHelpMode="edit-dossier-member"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
|
||||
<div (click)="toggleExpandedTeam()" *ngIf="expandedTeam" class="all-caps-label see-less pointer" translate="dossier-details.see-less"></div>
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
||||
import { CircleButtonTypes, List } from '@iqser/common-ui';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { DossiersDialogService } from '../../../dossier/services/dossiers-dialog.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-team-members',
|
||||
@ -13,18 +14,18 @@ export class TeamMembersComponent {
|
||||
|
||||
@Input() memberIds: List;
|
||||
@Input() perLine: number;
|
||||
@Input() dossierId: string;
|
||||
@Input() canAdd = true;
|
||||
@Input() largeSpacing = false;
|
||||
@Input() canRemove = false;
|
||||
@Input() unremovableMembers: string[] = [];
|
||||
@Output() openAssignDossierMembersDialog = new EventEmitter();
|
||||
@Output() remove = new EventEmitter<string>();
|
||||
|
||||
@ViewChild('container', { static: true }) container: ElementRef;
|
||||
@ViewChild('container', { static: true }) readonly container: ElementRef;
|
||||
|
||||
expandedTeam = false;
|
||||
|
||||
constructor(private readonly _userService: UserService) {}
|
||||
constructor(private readonly _userService: UserService, private readonly _dialogService: DossiersDialogService) {}
|
||||
|
||||
get maxTeamMembersBeforeExpand(): number {
|
||||
return this.perLine - (this.canAdd ? 1 : 0);
|
||||
@ -45,4 +46,9 @@ export class TeamMembersComponent {
|
||||
canRemoveMember(userId: string) {
|
||||
return this.canRemove && this.unremovableMembers.indexOf(userId) === -1;
|
||||
}
|
||||
|
||||
openEditDossierDialog(): void {
|
||||
const data = { dossierId: this.dossierId, section: 'members' };
|
||||
this._dialogService.openDialog('editDossier', null, data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { ApplicationRef, Injectable, Injector, OnDestroy } from '@angular/core';
|
||||
import { FileUploadModel } from '../model/file-upload.model';
|
||||
import { AppStateService } from '@state/app-state.service';
|
||||
import { HttpErrorResponse, HttpEventType } from '@angular/common/http';
|
||||
import { interval, Subject, Subscription } from 'rxjs';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
@ -11,6 +10,7 @@ import { isCsv } from '@utils/file-drop-utils';
|
||||
import { ErrorMessageService, GenericService, HeadersConfiguration, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
import { switchMap, tap, throttleTime } from 'rxjs/operators';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
|
||||
export interface ActiveUpload {
|
||||
subscription: Subscription;
|
||||
@ -30,7 +30,7 @@ export class FileUploadService extends GenericService<IFileUploadResult> impleme
|
||||
private readonly _subscriptions = new Subscription();
|
||||
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _applicationRef: ApplicationRef,
|
||||
private readonly _translateService: TranslateService,
|
||||
@ -42,7 +42,7 @@ export class FileUploadService extends GenericService<IFileUploadResult> impleme
|
||||
super(_injector, 'upload');
|
||||
const fileFetch$ = this._fetchFiles$.pipe(
|
||||
throttleTime(1500),
|
||||
switchMap(dossierId => this._appStateService.reloadDossierFiles(dossierId)),
|
||||
switchMap(dossierId => this._filesService.loadAll(dossierId)),
|
||||
);
|
||||
this._subscriptions.add(fileFetch$.subscribe());
|
||||
const interval$ = interval(2500).pipe(tap(() => this._handleUploads()));
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
||||
import { File } from '@red/domain';
|
||||
import { filter, startWith } from 'rxjs/operators';
|
||||
@ -10,8 +9,6 @@ export class FilesMapService {
|
||||
private readonly _entityChanged$ = new Subject<File>();
|
||||
private readonly _map = new Map<string, BehaviorSubject<File[]>>();
|
||||
|
||||
constructor(private readonly _filesService: FilesService) {}
|
||||
|
||||
get$(dossierId: string) {
|
||||
if (!this._map.has(dossierId)) {
|
||||
this._map.set(dossierId, new BehaviorSubject<File[]>([]));
|
||||
|
||||
@ -1,26 +1,47 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { EntitiesService, List, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { EntitiesService, List, mapEach, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { File, IFile } from '@red/domain';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { UserService } from '../user.service';
|
||||
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
import { tap } from 'rxjs/operators';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class FilesService extends EntitiesService<File, IFile> {
|
||||
constructor(protected readonly _injector: Injector, private readonly _userService: UserService) {
|
||||
constructor(
|
||||
protected readonly _injector: Injector,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _fileAttributesService: FileAttributesService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
) {
|
||||
super(_injector, File, 'status');
|
||||
}
|
||||
|
||||
fetch() {
|
||||
this.get().pipe(map(files => files.map(file => new File(file, this._userService.getNameForId(file.currentReviewer)))));
|
||||
loadAll(dossierId: string) {
|
||||
const files$ = this.getFor(dossierId).pipe(mapEach(file => new File(file, this._userService.getNameForId(file.currentReviewer))));
|
||||
return files$.pipe(tap(files => this._filesMapService.set(dossierId, files)));
|
||||
}
|
||||
|
||||
getOne(dossierId: string, fileId: string): Observable<IFile> {
|
||||
return super._getOne([dossierId, fileId]);
|
||||
}
|
||||
|
||||
async reload(dossierId: string, fileId: string): Promise<File> {
|
||||
const oldFile = this._filesMapService.get(dossierId, fileId);
|
||||
|
||||
if (!oldFile) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const rawFile = await this.getOne(dossierId, fileId).toPromise();
|
||||
const newFile = new File(rawFile, this._userService.getNameForId(rawFile.currentReviewer));
|
||||
this._filesMapService.replace(newFile);
|
||||
return newFile;
|
||||
}
|
||||
|
||||
@Validate()
|
||||
setUnderApprovalFor(@RequiredParam() body: List, @RequiredParam() dossierId: string, approverId: string) {
|
||||
const url = `${this._defaultModelPath}/under-approval/${dossierId}/bulk`;
|
||||
|
||||
@ -2,9 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
|
||||
import { AppStateService } from './app-state.service';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@ -12,8 +10,6 @@ import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
export class AppStateGuard implements CanActivate {
|
||||
constructor(
|
||||
private readonly _appStateService: AppStateService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _router: Router,
|
||||
|
||||
@ -1,17 +1,13 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Dictionary, Dossier, DossierTemplate, File, IColors } from '@red/domain';
|
||||
import { Dictionary, DossierTemplate, IColors } from '@red/domain';
|
||||
import { ActivationEnd, Router } from '@angular/router';
|
||||
import { UserService } from '@services/user.service';
|
||||
import { forkJoin, Observable, of } from 'rxjs';
|
||||
import { catchError, map, tap } from 'rxjs/operators';
|
||||
import { currentComponentRoute, FALLBACK_COLOR, hexToRgb } from '@utils/functions';
|
||||
import { DossiersService } from '@services/entity-services/dossiers.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
import { DictionaryService } from '@shared/services/dictionary.service';
|
||||
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
|
||||
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
|
||||
import { DossierStatsService } from '@services/entity-services/dossier-stats.service';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
|
||||
export interface AppState {
|
||||
activeFileId?: string;
|
||||
@ -27,14 +23,10 @@ export class AppStateService {
|
||||
|
||||
constructor(
|
||||
private readonly _router: Router,
|
||||
private readonly _userService: UserService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _dictionaryService: DictionaryService,
|
||||
private readonly _dossierTemplatesService: DossierTemplatesService,
|
||||
private readonly _dossierStatsService: DossierStatsService,
|
||||
private readonly _fileAttributesService: FileAttributesService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
) {
|
||||
_router.events.pipe(currentComponentRoute).subscribe((event: ActivationEnd) => {
|
||||
const fileId = event.snapshot.paramMap.get('fileId');
|
||||
@ -96,37 +88,6 @@ export class AppStateService {
|
||||
return data ? data : this._dictionaryData[dossierTemplateId]['default'];
|
||||
}
|
||||
|
||||
async reloadFile(dossierId: string, fileId: string): Promise<File> {
|
||||
const dossier = this._dossiersService.find(dossierId);
|
||||
const oldFile = this._filesMapService.get(dossierId, fileId);
|
||||
|
||||
if (!oldFile || !dossier) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const iFile = await this._filesService.getOne(dossierId, fileId).toPromise();
|
||||
|
||||
const newFile = new File(
|
||||
iFile,
|
||||
this._userService.getNameForId(iFile.currentReviewer),
|
||||
this._fileAttributesService.getFileAttributeConfig(dossier.dossierTemplateId),
|
||||
);
|
||||
|
||||
this._filesMapService.replace(newFile);
|
||||
return newFile;
|
||||
}
|
||||
|
||||
async getFiles(dossier: Dossier) {
|
||||
const files = await this._filesService.getFor(dossier.id).toPromise();
|
||||
await this._dossierStatsService.getFor([dossier.id]).toPromise();
|
||||
|
||||
const fileAttributes = this._fileAttributesService.getFileAttributeConfig(dossier.dossierTemplateId);
|
||||
const newFiles = files.map(iFile => new File(iFile, this._userService.getNameForId(iFile.currentReviewer), fileAttributes));
|
||||
this._filesMapService.set(dossier.dossierId, newFiles);
|
||||
|
||||
return newFiles;
|
||||
}
|
||||
|
||||
activateDictionary(dictionaryType: string) {
|
||||
if (this._dossierTemplatesService.activeDossierTemplate) {
|
||||
this._appState.activeDictionaryType = dictionaryType;
|
||||
@ -142,12 +103,6 @@ export class AppStateService {
|
||||
this._appState.activeDictionaryType = null;
|
||||
}
|
||||
|
||||
async reloadDossierFiles(dossierId: string) {
|
||||
if (dossierId) {
|
||||
return this.getFiles(this._dossiersService.find(dossierId));
|
||||
}
|
||||
}
|
||||
|
||||
async refreshDossierTemplate(dossierTemplateId: string) {
|
||||
const dossierTemplate = await this._dossierTemplatesService.get(dossierTemplateId).toPromise();
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import { Entity } from '@iqser/common-ui';
|
||||
import { StatusSorter } from '../shared';
|
||||
import { isProcessingStatuses, ProcessingFileStatus, ProcessingFileStatuses, WorkflowFileStatus, WorkflowFileStatuses } from './types';
|
||||
import { IFile } from './file';
|
||||
import { FileAttributes, IFileAttributesConfig } from '../file-attributes';
|
||||
import { FileAttributes } from '../file-attributes';
|
||||
|
||||
export class File extends Entity<IFile> implements IFile {
|
||||
readonly added?: string;
|
||||
@ -54,7 +54,7 @@ export class File extends Entity<IFile> implements IFile {
|
||||
readonly canBeOpened: boolean;
|
||||
readonly canBeOCRed: boolean;
|
||||
|
||||
constructor(file: IFile, readonly reviewerName: string, fileAttributesConfig?: IFileAttributesConfig) {
|
||||
constructor(file: IFile, readonly reviewerName: string) {
|
||||
super(file);
|
||||
this.added = file.added;
|
||||
this.allManualRedactionsApplied = !!file.allManualRedactionsApplied;
|
||||
@ -106,17 +106,6 @@ export class File extends Entity<IFile> implements IFile {
|
||||
this.canBeOpened = !this.isError && !this.isPending && this.numberOfAnalyses > 0;
|
||||
this.canBeOCRed = !this.excluded && !this.lastOCRTime && (this.isUnassigned || this.isUnderReview || this.isUnderApproval);
|
||||
|
||||
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: {} };
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user