243 lines
9.8 KiB
TypeScript
243 lines
9.8 KiB
TypeScript
import {
|
|
ChangeDetectionStrategy,
|
|
Component,
|
|
ElementRef,
|
|
forwardRef,
|
|
HostListener,
|
|
Injector,
|
|
OnDestroy,
|
|
OnInit,
|
|
TemplateRef,
|
|
ViewChild,
|
|
} from '@angular/core';
|
|
import { Dossier, DossierAttributeWithValue, File, IFileAttributeConfig, WorkflowFileStatus } from '@red/domain';
|
|
import { FileDropOverlayService } from '@upload-download/services/file-drop-overlay.service';
|
|
import { FileUploadModel } from '@upload-download/model/file-upload.model';
|
|
import { FileUploadService } from '@upload-download/services/file-upload.service';
|
|
import { StatusOverlayService } from '@upload-download/services/status-overlay.service';
|
|
import { Observable } from 'rxjs';
|
|
import { filter, skip, switchMap, tap } from 'rxjs/operators';
|
|
import { convertFiles, Files, handleFileDrop } from '@utils/index';
|
|
import {
|
|
CircleButtonTypes,
|
|
CustomError,
|
|
DefaultListingServices,
|
|
ErrorService,
|
|
ListingComponent,
|
|
ListingModes,
|
|
LoadingService,
|
|
NestedFilter,
|
|
OnAttach,
|
|
TableColumnConfig,
|
|
TableComponent,
|
|
WorkflowConfig,
|
|
} from '@iqser/common-ui';
|
|
import { DossierAttributesService } from '@shared/services/controller-wrappers/dossier-attributes.service';
|
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
|
import { PermissionsService } from '@services/permissions.service';
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
|
|
import { ConfigService } from '../config.service';
|
|
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
|
|
import { UserPreferenceService } from '@services/user-preference.service';
|
|
import { FilesMapService } from '@services/entity-services/files-map.service';
|
|
import { FilesService } from '@services/entity-services/files.service';
|
|
import { DOSSIER_ID } from '@utils/constants';
|
|
import { BulkActionsService } from '../services/bulk-actions.service';
|
|
import { DossiersService } from '@services/dossiers/dossiers.service';
|
|
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
|
|
|
|
@Component({
|
|
templateUrl: './dossier-overview-screen.component.html',
|
|
styleUrls: ['./dossier-overview-screen.component.scss'],
|
|
providers: [
|
|
...DefaultListingServices,
|
|
ConfigService,
|
|
BulkActionsService,
|
|
{ provide: ListingComponent, useExisting: forwardRef(() => DossierOverviewScreenComponent) },
|
|
dossiersServiceProvider,
|
|
],
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
})
|
|
export class DossierOverviewScreenComponent extends ListingComponent<File> implements OnInit, OnDestroy, OnAttach {
|
|
readonly listingModes = ListingModes;
|
|
readonly circleButtonTypes = CircleButtonTypes;
|
|
readonly tableHeaderLabel = _('dossier-overview.table-header.title');
|
|
|
|
collapsedDetails = false;
|
|
dossierAttributes: DossierAttributeWithValue[] = [];
|
|
tableColumnConfigs: readonly TableColumnConfig<File>[];
|
|
displayedInFileListAttributes: IFileAttributeConfig[] = [];
|
|
displayedAttributes: IFileAttributeConfig[] = [];
|
|
readonly workflowConfig: WorkflowConfig<File, WorkflowFileStatus> = this.configService.workflowConfig;
|
|
readonly dossier$: Observable<Dossier>;
|
|
readonly dossierId: string;
|
|
currentDossier: Dossier;
|
|
dossierTemplateId: string;
|
|
@ViewChild('needsWorkFilterTemplate', { read: TemplateRef, static: true })
|
|
private readonly _needsWorkFilterTemplate: TemplateRef<unknown>;
|
|
@ViewChild('fileInput', { static: true }) private readonly _fileInput: ElementRef;
|
|
@ViewChild(TableComponent) private readonly _tableComponent: TableComponent<Dossier>;
|
|
private _fileAttributeConfigs: IFileAttributeConfig[];
|
|
|
|
constructor(
|
|
protected readonly _injector: Injector,
|
|
private readonly _router: Router,
|
|
private readonly _dossiersService: DossiersService,
|
|
private readonly _loadingService: LoadingService,
|
|
private readonly _dossierTemplatesService: DossierTemplatesService,
|
|
private readonly _fileUploadService: FileUploadService,
|
|
private readonly _filesService: FilesService,
|
|
private readonly _statusOverlayService: StatusOverlayService,
|
|
private readonly _fileDropOverlayService: FileDropOverlayService,
|
|
private readonly _dossierAttributesService: DossierAttributesService,
|
|
private readonly _fileAttributesService: FileAttributesService,
|
|
private readonly _userPreferenceService: UserPreferenceService,
|
|
private readonly _fileMapService: FilesMapService,
|
|
private readonly _errorService: ErrorService,
|
|
private readonly _route: ActivatedRoute,
|
|
readonly permissionsService: PermissionsService,
|
|
readonly configService: ConfigService,
|
|
) {
|
|
super(_injector);
|
|
this.dossierId = _route.snapshot.paramMap.get(DOSSIER_ID);
|
|
this.dossier$ = this._dossiersService
|
|
.getEntityChanged$(this.dossierId)
|
|
.pipe(tap(dossier => (this.dossierTemplateId = dossier.dossierTemplateId)));
|
|
this.currentDossier = this._dossiersService.find(this.dossierId);
|
|
this._updateFileAttributes();
|
|
}
|
|
|
|
get checkedRequiredFilters(): NestedFilter[] {
|
|
return this.filterService.getGroup('quickFilters')?.filters.filter(f => f.required && f.checked);
|
|
}
|
|
|
|
get checkedNotRequiredFilters(): NestedFilter[] {
|
|
return this.filterService.getGroup('quickFilters')?.filters.filter(f => !f.required && f.checked);
|
|
}
|
|
|
|
disabledFn = (file: File) => file.excluded;
|
|
|
|
lastOpenedFn = (file: File) => this._userPreferenceService.getLastOpenedFileForDossier(file.dossierId) === file.id;
|
|
|
|
async ngOnInit(): Promise<void> {
|
|
this._loadEntitiesFromState();
|
|
|
|
this._setRemovableSubscriptions();
|
|
|
|
this.addSubscription = this._fileMapService
|
|
.get$(this.dossierId)
|
|
.pipe(
|
|
tap(files => this.entitiesService.setEntities(files)),
|
|
tap(() => this._computeAllFilters()),
|
|
)
|
|
.subscribe();
|
|
|
|
if (this.currentDossier.isActive) {
|
|
this._fileDropOverlayService.initFileDropHandling(this.dossierId);
|
|
}
|
|
|
|
this.addSubscription = this.configService.listingMode$.subscribe(() => {
|
|
this._computeAllFilters();
|
|
});
|
|
|
|
this.addSubscription = this._dossiersService.dossierFileChanges$
|
|
.pipe(
|
|
filter(dossierId => dossierId === this.dossierId),
|
|
switchMap(dossierId => this._filesService.loadAll(dossierId, this._dossiersService.routerPath)),
|
|
)
|
|
.subscribe();
|
|
|
|
this.addSubscription = this._dossierTemplatesService
|
|
.getEntityChanged$(this.currentDossier.dossierTemplateId)
|
|
.pipe(
|
|
skip(1),
|
|
tap(() => {
|
|
this._updateFileAttributes();
|
|
}),
|
|
)
|
|
.subscribe();
|
|
|
|
try {
|
|
this.dossierAttributes = await this._dossierAttributesService.getWithValues(this.currentDossier);
|
|
} catch (e) {
|
|
console.log('Error from dossier overview screen: ', e);
|
|
}
|
|
|
|
this._loadingService.stop();
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this._fileDropOverlayService.cleanupFileDropHandling();
|
|
super.ngOnDestroy();
|
|
}
|
|
|
|
ngOnAttach() {
|
|
this._fileDropOverlayService.initFileDropHandling(this.dossierId);
|
|
this._setRemovableSubscriptions();
|
|
this._tableComponent?.scrollToLastIndex();
|
|
}
|
|
|
|
@HostListener('drop', ['$event'])
|
|
onDrop(event: DragEvent): void {
|
|
const currentDossier = this._dossiersService.find(this.dossierId);
|
|
handleFileDrop(event, currentDossier, this._uploadFiles.bind(this));
|
|
}
|
|
|
|
@HostListener('dragover', ['$event'])
|
|
onDragOver(event): void {
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
}
|
|
|
|
async uploadFiles(files: Files): Promise<void> {
|
|
await this._uploadFiles(convertFiles(files, this.currentDossier));
|
|
(this._fileInput as any).nativeElement.value = null;
|
|
}
|
|
|
|
private _setRemovableSubscriptions(): void {
|
|
this.addActiveScreenSubscription = this._dossiersService
|
|
.getEntityDeleted$(this.dossierId)
|
|
.pipe(tap(() => this._handleDeletedDossier()))
|
|
.subscribe();
|
|
}
|
|
|
|
private _handleDeletedDossier(): void {
|
|
this._errorService.set(
|
|
new CustomError(_('error.deleted-entity.dossier.label'), _('error.deleted-entity.dossier.action'), 'iqser:expand'),
|
|
);
|
|
}
|
|
|
|
private _updateFileAttributes(): void {
|
|
this._fileAttributeConfigs =
|
|
this._fileAttributesService.getFileAttributeConfig(this.currentDossier.dossierTemplateId)?.fileAttributeConfigs || [];
|
|
this.displayedInFileListAttributes = this._fileAttributeConfigs.filter(config => config.displayedInFileList);
|
|
this.displayedAttributes = this.displayedInFileListAttributes.filter(c => c.displayedInFileList);
|
|
this.tableColumnConfigs = this.configService.tableConfig(this.displayedAttributes);
|
|
this._computeAllFilters();
|
|
}
|
|
|
|
private _loadEntitiesFromState() {
|
|
this.currentDossier = this._dossiersService.find(this.dossierId);
|
|
this._computeAllFilters();
|
|
}
|
|
|
|
private async _uploadFiles(files: FileUploadModel[]) {
|
|
const fileCount = await this._fileUploadService.uploadFiles(files, this.dossierId);
|
|
if (fileCount) {
|
|
this._statusOverlayService.openUploadStatusOverlay();
|
|
}
|
|
}
|
|
|
|
private _computeAllFilters() {
|
|
const filterGroups = this.configService.filterGroups(
|
|
this.entitiesService.all,
|
|
this._fileAttributeConfigs,
|
|
this._needsWorkFilterTemplate,
|
|
() => this.checkedRequiredFilters,
|
|
() => this.checkedNotRequiredFilters,
|
|
);
|
|
this.filterService.addFilterGroups(filterGroups, true);
|
|
}
|
|
}
|