RED-3796: Removed routerPath
This commit is contained in:
parent
fadbf34894
commit
06c9b2bbc7
@ -9,7 +9,7 @@ import { DownloadsListScreenComponent } from '@components/downloads-list-screen/
|
||||
import { DossiersGuard } from '@guards/dossiers.guard';
|
||||
import { ACTIVE_DOSSIERS_SERVICE, ARCHIVED_DOSSIERS_SERVICE } from './tokens';
|
||||
import { FeaturesGuard } from '@guards/features-guard.service';
|
||||
import { DOSSIER_TEMPLATE_ID, DOSSIERS_ARCHIVE } from '@utils/constants';
|
||||
import { ARCHIVE_ROUTE, DOSSIER_TEMPLATE_ID, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE } from '@utils/constants';
|
||||
import { DossierTemplatesGuard } from '@guards/dossier-templates.guard';
|
||||
import { DossierTemplateExistsGuard } from '@guards/dossier-template-exists.guard';
|
||||
|
||||
@ -46,24 +46,37 @@ const routes: Routes = [
|
||||
},
|
||||
},
|
||||
{
|
||||
path: `:${DOSSIER_TEMPLATE_ID}/dossiers`,
|
||||
loadChildren: () => import('./modules/dossier/dossiers.module').then(m => m.DossiersModule),
|
||||
path: `:${DOSSIER_TEMPLATE_ID}`,
|
||||
children: [
|
||||
{
|
||||
path: `${DOSSIERS_ROUTE}`,
|
||||
loadChildren: () => import('./modules/dossier/dossiers.module').then(m => m.DossiersModule),
|
||||
canActivate: [CompositeRouteGuard],
|
||||
data: {
|
||||
routeGuards: [DossiersGuard],
|
||||
dossiersService: ACTIVE_DOSSIERS_SERVICE,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: `${ARCHIVE_ROUTE}`,
|
||||
loadChildren: () => import('./modules/archive/archive.module').then(m => m.ArchiveModule),
|
||||
canActivate: [CompositeRouteGuard],
|
||||
data: {
|
||||
routeGuards: [FeaturesGuard, DossiersGuard],
|
||||
dossiersService: ARCHIVED_DOSSIERS_SERVICE,
|
||||
features: [DOSSIERS_ARCHIVE],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
redirectTo: `${DOSSIERS_ROUTE}`,
|
||||
pathMatch: 'full',
|
||||
},
|
||||
],
|
||||
canActivate: [CompositeRouteGuard],
|
||||
data: {
|
||||
routeGuards: [AuthGuard, RedRoleGuard, DossierTemplatesGuard, DossierTemplateExistsGuard, DossiersGuard],
|
||||
routeGuards: [AuthGuard, RedRoleGuard, DossierTemplatesGuard, DossierTemplateExistsGuard],
|
||||
requiredRoles: ['RED_USER', 'RED_MANAGER'],
|
||||
dossiersService: ACTIVE_DOSSIERS_SERVICE,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: `:${DOSSIER_TEMPLATE_ID}/archive`,
|
||||
loadChildren: () => import('./modules/archive/archive.module').then(m => m.ArchiveModule),
|
||||
canActivate: [CompositeRouteGuard],
|
||||
data: {
|
||||
routeGuards: [FeaturesGuard, AuthGuard, RedRoleGuard, DossierTemplatesGuard, DossierTemplateExistsGuard, DossiersGuard],
|
||||
requiredRoles: ['RED_USER', 'RED_MANAGER'],
|
||||
dossiersService: ARCHIVED_DOSSIERS_SERVICE,
|
||||
features: [DOSSIERS_ARCHIVE],
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -83,11 +96,6 @@ const routes: Routes = [
|
||||
requiredRoles: ['RED_USER', 'RED_MANAGER'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: `:${DOSSIER_TEMPLATE_ID}`,
|
||||
redirectTo: `:${DOSSIER_TEMPLATE_ID}/dossiers`,
|
||||
pathMatch: 'full',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@ -7,10 +7,10 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { SpotlightSearchAction } from '@components/spotlight-search/spotlight-search-action';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { filter, map, startWith } from 'rxjs/operators';
|
||||
import { HelpModeService, shareDistinctLast } from '@iqser/common-ui';
|
||||
import { shareDistinctLast } from '@iqser/common-ui';
|
||||
import { BreadcrumbsService } from '@services/breadcrumbs.service';
|
||||
import { FeaturesService } from '@services/features.service';
|
||||
import { DOSSIERS_ARCHIVE } from '@utils/constants';
|
||||
import { ARCHIVE_ROUTE, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE } from '@utils/constants';
|
||||
|
||||
interface MenuItem {
|
||||
readonly id: string;
|
||||
@ -91,7 +91,6 @@ export class BaseScreenComponent {
|
||||
readonly userPreferenceService: UserPreferenceService,
|
||||
readonly titleService: Title,
|
||||
readonly breadcrumbsService: BreadcrumbsService,
|
||||
readonly helpModeService: HelpModeService,
|
||||
) {}
|
||||
|
||||
private get _hideSearchThisDossier() {
|
||||
@ -100,7 +99,7 @@ export class BaseScreenComponent {
|
||||
return true;
|
||||
}
|
||||
|
||||
const isDossierOverview = (routerLink.includes('dossiers') || routerLink.includes('archive')) && routerLink.length === 3;
|
||||
const isDossierOverview = (routerLink.includes(DOSSIERS_ROUTE) || routerLink.includes(ARCHIVE_ROUTE)) && routerLink.length === 3;
|
||||
return !isDossierOverview;
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
|
||||
import { FilesMapService } from '@services/entity-services/files-map.service';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { DOSSIER_ID } from '@utils/constants';
|
||||
import { DOSSIER_ID, DOSSIER_TEMPLATE_ID } from '@utils/constants';
|
||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
@ -17,16 +17,17 @@ export class DossierFilesGuard implements CanActivate {
|
||||
|
||||
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
|
||||
const dossierId = route.paramMap.get(DOSSIER_ID);
|
||||
const dossierTemplateId = route.paramMap.get(DOSSIER_TEMPLATE_ID);
|
||||
const token: ProviderToken<DossiersService> = route.data.dossiersService;
|
||||
const dossiersService: DossiersService = this._injector.get<DossiersService>(token);
|
||||
|
||||
if (!dossiersService.has(dossierId)) {
|
||||
await this._router.navigate(['/main', dossiersService.routerPath]);
|
||||
await this._router.navigate(['/main', dossierTemplateId]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this._filesMapService.has(dossierId)) {
|
||||
await firstValueFrom(this._filesService.loadAll(dossierId, dossiersService.routerPath));
|
||||
await firstValueFrom(this._filesService.loadAll(dossierId));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ export class DossierTemplateExistsGuard implements CanActivate {
|
||||
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
|
||||
const dossierTemplateId: string = route.paramMap.get(DOSSIER_TEMPLATE_ID);
|
||||
if (!this._dossierTemplatesService.find(dossierTemplateId)) {
|
||||
const adminView = !(route.routeConfig.path.includes('dossiers') || route.routeConfig.path.includes('archive'));
|
||||
const adminView = !!route.pathFromRoot.find(r => r.routeConfig?.path === 'admin');
|
||||
const routerPath = adminView ? ['main', 'admin', 'dossier-templates'] : [''];
|
||||
await this._router.navigate(routerPath);
|
||||
return false;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { DossierTemplatesService } from '../../../../services/entity-services/dossier-templates.service';
|
||||
import { DossierTemplate, IDossierTemplate } from '../../../../../../../../libs/red-domain/src';
|
||||
import { LoadingService, Toaster } from '../../../../../../../../libs/common-ui/src';
|
||||
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
|
||||
import { DossierTemplate } from '@red/domain';
|
||||
import { LoadingService, Toaster } from '@iqser/common-ui';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
|
||||
@ -11,8 +11,8 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
styleUrls: ['./clone-dossier-template-dialog.component.scss'],
|
||||
})
|
||||
export class CloneDossierTemplateDialogComponent {
|
||||
private readonly _dossierTemplate: DossierTemplate;
|
||||
nameOfClonedDossierTemplate: string;
|
||||
private readonly _dossierTemplate: DossierTemplate;
|
||||
|
||||
constructor(
|
||||
private readonly _toaster: Toaster,
|
||||
@ -25,6 +25,17 @@ export class CloneDossierTemplateDialogComponent {
|
||||
this.nameOfClonedDossierTemplate = this._getCloneName();
|
||||
}
|
||||
|
||||
async save() {
|
||||
this._loadingService.start();
|
||||
try {
|
||||
await firstValueFrom(this._dossierTemplatesService.clone(this.dossierTemplateId, this.nameOfClonedDossierTemplate));
|
||||
this._dialogRef.close(true);
|
||||
} catch (error: any) {
|
||||
this._toaster.error(_('clone-dossier-template.error.generic'), { error });
|
||||
}
|
||||
this._loadingService.stop();
|
||||
}
|
||||
|
||||
private _getCloneName(): string | null {
|
||||
const templateName = this._dossierTemplate.name.trim();
|
||||
|
||||
@ -47,15 +58,4 @@ export class CloneDossierTemplateDialogComponent {
|
||||
}
|
||||
return `Clone of ${nameOfClonedTemplate}`;
|
||||
}
|
||||
|
||||
async save() {
|
||||
this._loadingService.start();
|
||||
try {
|
||||
await firstValueFrom(this._dossierTemplatesService.clone(this.dossierTemplateId, this.nameOfClonedDossierTemplate));
|
||||
this._dialogRef.close(true);
|
||||
} catch (error: any) {
|
||||
this._toaster.error(_('clone-dossier-template.error.generic'), { error });
|
||||
}
|
||||
this._loadingService.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,18 +49,16 @@ export class RedRoleGuard implements CanActivate {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._userService.currentUser.isUser && state.url.startsWith('/main/dossiers')) {
|
||||
this._router.navigate(['/main/admin']);
|
||||
obs.next(false);
|
||||
obs.complete();
|
||||
return;
|
||||
}
|
||||
if (route.data.requiredRoles) {
|
||||
if (this._userService.hasAnyRole(route.data.requiredRoles)) {
|
||||
obs.next(true);
|
||||
obs.complete();
|
||||
} else {
|
||||
this._router.navigate(['/main/dossiers']);
|
||||
if (!this._userService.currentUser.isUser) {
|
||||
this._router.navigate(['/main/admin']);
|
||||
} else {
|
||||
this._router.navigate(['/']);
|
||||
}
|
||||
obs.next(false);
|
||||
obs.complete();
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ export class DossierDetailsStatsComponent implements OnInit {
|
||||
openEditDossierDialog(section: string): void {
|
||||
const data = { dossierId: this.dossier.dossierId, section };
|
||||
this._dialogService.openDialog('editDossier', null, data, async () => {
|
||||
await firstValueFrom(this._filesService.loadAll(this.dossier.dossierId, this.dossier.routerPath));
|
||||
await firstValueFrom(this._filesService.loadAll(this.dossier.dossierId));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<iqser-page-header
|
||||
(closeAction)="router.navigate(['/main', dossiersService.routerPath])"
|
||||
(closeAction)="router.navigate([dossier.dossiersListRouterLink])"
|
||||
[actionConfigs]="actionConfigs"
|
||||
[helpModeKey]="'document'"
|
||||
[showCloseButton]="true"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Component, ElementRef, forwardRef, HostListener, Injector, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { Component, ElementRef, forwardRef, HostListener, Injector, 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';
|
||||
@ -126,7 +126,7 @@ export class DossierOverviewScreenComponent extends ListingComponent<File> imple
|
||||
get #dossierFilesChange$() {
|
||||
return this._dossiersService.dossierFileChanges$.pipe(
|
||||
filter(dossierId => dossierId === this.dossierId),
|
||||
switchMap(dossierId => this._filesService.loadAll(dossierId, this._dossiersService.routerPath)),
|
||||
switchMap(dossierId => this._filesService.loadAll(dossierId)),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -139,7 +139,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(this._trashService.deleteDossier(this.dossier));
|
||||
this._editDossierDialogRef.close();
|
||||
await this._router.navigate(['main', 'dossiers']);
|
||||
await this._router.navigate([this.dossier.dossiersListRouterLink]);
|
||||
this._loadingService.stop();
|
||||
this._toaster.success(_('edit-dossier-dialog.delete-successful'), { params: this.dossier });
|
||||
});
|
||||
@ -161,7 +161,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
if (result === ConfirmOptions.CONFIRM) {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(this._archivedDossiersService.archive([this.dossier]));
|
||||
await this._router.navigate(['main', 'dossiers']);
|
||||
await this._router.navigate([this.dossier.dossiersListRouterLink]);
|
||||
this._toaster.success(_('dossier-listing.archive.archive-succeeded'), { params: this.dossier });
|
||||
this._editDossierDialogRef.close();
|
||||
this._loadingService.stop();
|
||||
|
||||
@ -81,7 +81,7 @@ export class FilePreviewStateService {
|
||||
#dossierFilesChange$() {
|
||||
return this._dossiersService.dossierFileChanges$.pipe(
|
||||
filter(dossierId => dossierId === this.dossierId),
|
||||
switchMap(dossierId => this._filesService.loadAll(dossierId, this._dossiersService.routerPath)),
|
||||
switchMap(dossierId => this._filesService.loadAll(dossierId)),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<a [routerLinkActive]="'active'" [routerLink]="['..', 'dossiers']" class="red-tab">
|
||||
<a [routerLinkActive]="'active'" [routerLink]="['..', DOSSIERS_ROUTE]" class="red-tab">
|
||||
{{ 'dossiers-type-switch.active' | translate }}
|
||||
</a>
|
||||
|
||||
<a [routerLinkActive]="'active'" [routerLink]="['..', 'archive']" class="red-tab">
|
||||
<a [routerLinkActive]="'active'" [routerLink]="['..', ARCHIVE_ROUTE]" class="red-tab">
|
||||
{{ 'dossiers-type-switch.archive' | translate }}
|
||||
</a>
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
import { ARCHIVE_ROUTE, DOSSIERS_ROUTE } from '@utils/constants';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossiers-type-switch',
|
||||
@ -6,4 +7,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
styleUrls: ['./dossiers-type-switch.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class DossiersTypeSwitchComponent {}
|
||||
export class DossiersTypeSwitchComponent {
|
||||
readonly DOSSIERS_ROUTE = DOSSIERS_ROUTE;
|
||||
readonly ARCHIVE_ROUTE = ARCHIVE_ROUTE;
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ export class FileUploadService extends GenericService<IFileUploadResult> impleme
|
||||
super(_injector, 'upload');
|
||||
const fileFetch$ = this._fetchFiles$.pipe(
|
||||
throttleTime(250),
|
||||
switchMap(dossierId => this._filesService.loadAll(dossierId, 'dossiers')),
|
||||
switchMap(dossierId => this._filesService.loadAll(dossierId)),
|
||||
);
|
||||
this._subscriptions.add(fileFetch$.subscribe());
|
||||
const interval$ = interval(2500).pipe(tap(() => this._handleUploads()));
|
||||
|
||||
@ -136,7 +136,7 @@ export class BreadcrumbsService {
|
||||
name$: this._dossierTemplatesService.getEntityChanged$(dossierTemplateId).pipe(pluck('name')),
|
||||
type: 'text' as BreadcrumbDisplayType,
|
||||
options: {
|
||||
routerLink: ['/main', dossierTemplateId],
|
||||
routerLink: ['/main', dossierTemplateId, this._dossiersService.routerPath],
|
||||
routerLinkActiveOptions: { exact: true },
|
||||
clamp: true,
|
||||
},
|
||||
@ -146,12 +146,11 @@ export class BreadcrumbsService {
|
||||
private _addDossierBreadcrumb(params: Record<string, string>): void {
|
||||
const dossiersService = this._dossiersService;
|
||||
const dossierId: string = params[DOSSIER_ID];
|
||||
const dossierTemplateId: string = params[DOSSIER_TEMPLATE_ID];
|
||||
this._append({
|
||||
name$: dossiersService.getEntityChanged$(dossierId).pipe(pluck('dossierName')),
|
||||
type: 'text' as BreadcrumbDisplayType,
|
||||
options: {
|
||||
routerLink: ['/main', dossierTemplateId, dossiersService.routerPath, dossierId],
|
||||
routerLink: [dossiersService.find(dossierId).routerLink],
|
||||
routerLinkActiveOptions: { exact: true },
|
||||
clamp: true,
|
||||
},
|
||||
@ -159,15 +158,13 @@ export class BreadcrumbsService {
|
||||
}
|
||||
|
||||
private _addFileBreadcrumb(params: Record<string, string>): void {
|
||||
const dossierTemplateId: string = params[DOSSIER_TEMPLATE_ID];
|
||||
const dossierId: string = params[DOSSIER_ID];
|
||||
const fileId: string = params[FILE_ID];
|
||||
const dossiersService = this._dossiersService;
|
||||
this._append({
|
||||
name$: this._filesMapService.watch$(dossierId, fileId).pipe(pluck('filename')),
|
||||
type: 'text' as BreadcrumbDisplayType,
|
||||
options: {
|
||||
routerLink: ['/main', dossierTemplateId, dossiersService.routerPath, dossierId, 'file', fileId],
|
||||
routerLink: [this._filesMapService.get(dossierId, fileId).routerLink],
|
||||
clamp: true,
|
||||
},
|
||||
});
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { switchMap, tap } from 'rxjs/operators';
|
||||
import { timer } from 'rxjs';
|
||||
import { CHANGED_CHECK_INTERVAL } from '@utils/constants';
|
||||
import { CHANGED_CHECK_INTERVAL, DOSSIERS_ROUTE } from '@utils/constants';
|
||||
import { DossiersService } from './dossiers.service';
|
||||
|
||||
export interface IDossiersStats {
|
||||
@ -14,7 +14,7 @@ export interface IDossiersStats {
|
||||
})
|
||||
export class ActiveDossiersService extends DossiersService {
|
||||
constructor(protected readonly _injector: Injector) {
|
||||
super(_injector, 'dossier', 'dossiers');
|
||||
super(_injector, 'dossier', DOSSIERS_ROUTE);
|
||||
|
||||
timer(CHANGED_CHECK_INTERVAL, CHANGED_CHECK_INTERVAL)
|
||||
.pipe(
|
||||
|
||||
@ -7,7 +7,7 @@ import { ActiveDossiersService } from './active-dossiers.service';
|
||||
import { DossiersService } from './dossiers.service';
|
||||
import { FilesMapService } from '../entity-services/files-map.service';
|
||||
import { FeaturesService } from '@services/features.service';
|
||||
import { DOSSIERS_ARCHIVE } from '@utils/constants';
|
||||
import { ARCHIVE_ROUTE, DOSSIERS_ARCHIVE } from '@utils/constants';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ArchivedDossiersService extends DossiersService {
|
||||
@ -17,7 +17,7 @@ export class ArchivedDossiersService extends DossiersService {
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _featuresService: FeaturesService,
|
||||
) {
|
||||
super(_injector, 'archived-dossiers', 'archive');
|
||||
super(_injector, 'archived-dossiers', ARCHIVE_ROUTE);
|
||||
}
|
||||
|
||||
archive(dossiers: Dossier[]): Observable<unknown> {
|
||||
|
||||
@ -61,7 +61,7 @@ export abstract class DossiersService extends EntitiesService<Dossier, IDossier>
|
||||
loadAll(): Observable<Dossier[]> {
|
||||
const dossierIds = (dossiers: Dossier[]) => dossiers.map(d => d.id);
|
||||
return this.getAll().pipe(
|
||||
mapEach(entity => new Dossier(entity, this.routerPath)),
|
||||
mapEach(entity => new Dossier(entity)),
|
||||
/* Load stats before updating entities */
|
||||
switchMap(dossiers => this._dossierStatsService.getFor(dossierIds(dossiers)).pipe(map(() => dossiers))),
|
||||
switchMap(dossiers => this._dossierStateService.loadAllForAllTemplates().pipe(map(() => dossiers))),
|
||||
@ -81,7 +81,7 @@ export abstract class DossiersService extends EntitiesService<Dossier, IDossier>
|
||||
private _load(id: string): Observable<DossierStats[]> {
|
||||
const queryParams: List<QueryParam> = [{ key: 'includeArchived', value: this._path === 'archived-dossiers' }];
|
||||
return super._getOne([id], this._defaultModelPath, queryParams).pipe(
|
||||
map(entity => new Dossier(entity, 'dossiers')),
|
||||
map(entity => new Dossier(entity)),
|
||||
tap(dossier => this.replace(dossier)),
|
||||
switchMap(dossier => this._dossierStatsService.getFor([dossier.dossierId])),
|
||||
);
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { GenericService, HeadersConfiguration, IRouterPath, List, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { GenericService, HeadersConfiguration, List, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { HttpHeaders, HttpResponse } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { FilesService } from '@services/entity-services/files.service';
|
||||
import { DossierStatsService } from '@services/dossiers/dossier-stats.service';
|
||||
import { IPageRotationRequest } from '@red/domain';
|
||||
import { File, IPageRotationRequest } from '@red/domain';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@ -20,10 +20,9 @@ export class FileManagementService extends GenericService<unknown> {
|
||||
}
|
||||
|
||||
@Validate()
|
||||
delete(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string) {
|
||||
delete(@RequiredParam() files: List<File>, @RequiredParam() dossierId: string) {
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return super._post(fileIds, `delete/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId, routerPath)));
|
||||
return super._post(fileIds, `delete/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
|
||||
@ -12,11 +12,7 @@ export class FilesMapService extends EntitiesMapService<File, IFile> {
|
||||
replaceFiles(files: File[], property: keyof IFile, generateValue: Function) {
|
||||
const newFiles = files.map(
|
||||
file =>
|
||||
new File(
|
||||
{ ...file, [property]: generateValue(file[property]), lastUpdated: new Date().toISOString() },
|
||||
file.reviewerName,
|
||||
file.routerPath,
|
||||
),
|
||||
new File({ ...file, [property]: generateValue(file[property]), lastUpdated: new Date().toISOString() }, file.reviewerName),
|
||||
);
|
||||
this.replace(newFiles);
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { EntitiesService, IRouterPath, List, mapEach, 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 { UserService } from '../user.service';
|
||||
@ -23,9 +23,9 @@ export class FilesService extends EntitiesService<File, IFile> {
|
||||
}
|
||||
|
||||
/** Reload dossier files + stats. */
|
||||
loadAll(dossierId: string, routerPath: string) {
|
||||
loadAll(dossierId: string) {
|
||||
const files$ = this.getFor(dossierId).pipe(
|
||||
mapEach(file => new File(file, this._userService.getNameForId(file.assignee), routerPath)),
|
||||
mapEach(file => new File(file, this._userService.getNameForId(file.assignee))),
|
||||
tap(() => this._logger.info('[FILE] Loaded')),
|
||||
);
|
||||
const loadStats$ = files$.pipe(switchMap(files => this._dossierStatsService.getFor([dossierId]).pipe(map(() => files))));
|
||||
@ -34,7 +34,7 @@ export class FilesService extends EntitiesService<File, IFile> {
|
||||
|
||||
reload(dossierId: string, file: File): Observable<boolean> {
|
||||
return super._getOne([dossierId, file.id]).pipe(
|
||||
map(_file => new File(_file, this._userService.getNameForId(_file.assignee), file.routerPath)),
|
||||
map(_file => new File(_file, this._userService.getNameForId(_file.assignee))),
|
||||
switchMap(_file => this._dossierStatsService.getFor([dossierId]).pipe(map(() => _file))),
|
||||
map(_file => this._filesMapService.replace([_file])),
|
||||
tap(() => this._logger.info('[FILE] Reloaded')),
|
||||
@ -42,56 +42,46 @@ export class FilesService extends EntitiesService<File, IFile> {
|
||||
}
|
||||
|
||||
@Validate()
|
||||
setUnassigned(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string) {
|
||||
setUnassigned(@RequiredParam() files: List<File>, @RequiredParam() dossierId: string) {
|
||||
const url = `${this._defaultModelPath}/set-assignee/${dossierId}/bulk`;
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post<unknown>(fileIds, url).pipe(switchMap(() => this.loadAll(dossierId, routerPath)));
|
||||
return this._post<unknown>(fileIds, url).pipe(switchMap(() => this.loadAll(dossierId)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
setToNewFor(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string) {
|
||||
setToNewFor(@RequiredParam() files: List<File>, @RequiredParam() dossierId: string) {
|
||||
const url = `${this._defaultModelPath}/new/${dossierId}/bulk`;
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post<unknown>(fileIds, url).pipe(switchMap(() => this.loadAll(dossierId, routerPath)));
|
||||
return this._post<unknown>(fileIds, url).pipe(switchMap(() => this.loadAll(dossierId)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
setUnderApprovalFor(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string, assigneeId: string) {
|
||||
setUnderApprovalFor(@RequiredParam() files: List<File>, @RequiredParam() dossierId: string, assigneeId: string) {
|
||||
const url = `${this._defaultModelPath}/under-approval/${dossierId}/bulk`;
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post<unknown>(fileIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe(
|
||||
switchMap(() => this.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
return this._post<unknown>(fileIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe(switchMap(() => this.loadAll(dossierId)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
setReviewerFor(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string, assigneeId: string) {
|
||||
setReviewerFor(@RequiredParam() files: List<File>, @RequiredParam() dossierId: string, assigneeId: string) {
|
||||
const url = `${this._defaultModelPath}/under-review/${dossierId}/bulk`;
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post<unknown>(fileIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe(
|
||||
switchMap(() => this.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
return this._post<unknown>(fileIds, url, [{ key: 'assigneeId', value: assigneeId }]).pipe(switchMap(() => this.loadAll(dossierId)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
setApprovedFor(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string) {
|
||||
setApprovedFor(@RequiredParam() files: List<File>, @RequiredParam() dossierId: string) {
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post<unknown>(fileIds, `${this._defaultModelPath}/approved/${dossierId}/bulk`).pipe(
|
||||
switchMap(() => this.loadAll(dossierId, routerPath)),
|
||||
switchMap(() => this.loadAll(dossierId)),
|
||||
);
|
||||
}
|
||||
|
||||
@Validate()
|
||||
setUnderReviewFor(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string) {
|
||||
setUnderReviewFor(@RequiredParam() files: List<File>, @RequiredParam() dossierId: string) {
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post<unknown>(fileIds, `${this._defaultModelPath}/under-review/${dossierId}/bulk`).pipe(
|
||||
switchMap(() => this.loadAll(dossierId, routerPath)),
|
||||
switchMap(() => this.loadAll(dossierId)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,6 +56,6 @@ export class PlatformSearchService extends GenericService<ISearchResponse> {
|
||||
}
|
||||
|
||||
private _loadFilesFor$(dossiers: Dossier[]) {
|
||||
return zip(...dossiers.map(dossier => this._filesService.loadAll(dossier.id, dossier.routerPath)));
|
||||
return zip(...dossiers.map(dossier => this._filesService.loadAll(dossier.id)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ export class TrashService extends GenericService<TrashItem> {
|
||||
getFiles(dossierIds = this._activeDossiersService.all.map(d => d.id)): Observable<TrashFile[]> {
|
||||
return this._post<Record<string, IFile[]>>(dossierIds, 'status/softdeleted').pipe(
|
||||
map(res => flatMap(Object.values(res))),
|
||||
mapEach(file => new File(file, this._userService.getNameForId(file.assignee), this._activeDossiersService.routerPath)),
|
||||
mapEach(file => new File(file, this._userService.getNameForId(file.assignee))),
|
||||
mapEach(file => {
|
||||
const dossier = this._activeDossiersService.find(file.dossierId);
|
||||
return new TrashFile(
|
||||
@ -133,6 +133,6 @@ export class TrashService extends GenericService<TrashItem> {
|
||||
}
|
||||
|
||||
private _restoreFiles(@RequiredParam() dossierId: string, @RequiredParam() fileIds: List) {
|
||||
return this._post(fileIds, `delete/restore/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId, 'dossiers')));
|
||||
return this._post(fileIds, `delete/restore/${dossierId}`).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { GenericService, IRouterPath, List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
|
||||
import { GenericService, List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
|
||||
import { Dossier, File, IPageExclusionRequest } from '@red/domain';
|
||||
import { catchError, switchMap, tap } from 'rxjs/operators';
|
||||
import { FilesService } from './entity-services/files.service';
|
||||
@ -36,9 +36,8 @@ export class ReanalysisService extends GenericService<unknown> {
|
||||
}
|
||||
|
||||
@Validate()
|
||||
reanalyzeFilesForDossier(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string, params?: ReanalyzeQueryParams) {
|
||||
reanalyzeFilesForDossier(@RequiredParam() files: List<File>, @RequiredParam() dossierId: string, params?: ReanalyzeQueryParams) {
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
const queryParams: QueryParam[] = [];
|
||||
if (params?.force) {
|
||||
queryParams.push({ key: 'force', value: true });
|
||||
@ -47,22 +46,19 @@ export class ReanalysisService extends GenericService<unknown> {
|
||||
queryParams.push({ key: 'triggeredByUser', value: true });
|
||||
}
|
||||
|
||||
return this._post(fileIds, `reanalyze/${dossierId}/bulk`, queryParams).pipe(
|
||||
switchMap(() => this._filesService.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
return this._post(fileIds, `reanalyze/${dossierId}/bulk`, queryParams).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
toggleAnalysis(@RequiredParam() dossierId: string, @RequiredParam() files: List<IRouterPath>, excluded?: boolean) {
|
||||
toggleAnalysis(@RequiredParam() dossierId: string, @RequiredParam() files: List<File>, excluded?: boolean) {
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
const queryParams: QueryParam[] = [];
|
||||
if (excluded) {
|
||||
queryParams.push({ key: 'excluded', value: excluded });
|
||||
}
|
||||
|
||||
return this._post(fileIds, `toggle-analysis/${dossierId}/bulk`, queryParams).pipe(
|
||||
switchMap(() => this._filesService.loadAll(dossierId, routerPath)),
|
||||
switchMap(() => this._filesService.loadAll(dossierId)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -86,24 +82,19 @@ export class ReanalysisService extends GenericService<unknown> {
|
||||
}
|
||||
|
||||
@Validate()
|
||||
ocrFiles(@RequiredParam() files: List<IRouterPath>, @RequiredParam() dossierId: string) {
|
||||
ocrFiles(@RequiredParam() files: List<File>, @RequiredParam() dossierId: string) {
|
||||
const fileIds = files.map(f => f.id);
|
||||
const routerPath: string = files[0].routerPath;
|
||||
return this._post(fileIds, `ocr/reanalyze/${dossierId}/bulk`).pipe(
|
||||
switchMap(() => this._filesService.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
return this._post(fileIds, `ocr/reanalyze/${dossierId}/bulk`).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
}
|
||||
|
||||
@Validate()
|
||||
reanalyzeDossier(@RequiredParam() dossier: Dossier, force?: boolean) {
|
||||
const { dossierId, routerPath } = dossier;
|
||||
const { dossierId } = dossier;
|
||||
const queryParams: QueryParam[] = [];
|
||||
if (force) {
|
||||
queryParams.push({ key: 'force', value: force });
|
||||
}
|
||||
|
||||
return this._post({}, `reanalyze/${dossierId}`, queryParams).pipe(
|
||||
switchMap(() => this._filesService.loadAll(dossierId, routerPath)),
|
||||
);
|
||||
return this._post({}, `reanalyze/${dossierId}`, queryParams).pipe(switchMap(() => this._filesService.loadAll(dossierId)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,3 +5,6 @@ export const FILE_ID = 'fileId';
|
||||
export const DOSSIER_TEMPLATE_ID = 'dossierTemplateId';
|
||||
export const ENTITY_TYPE = 'entity';
|
||||
export const DOSSIERS_ARCHIVE = 'DOSSIERS_ARCHIVE';
|
||||
|
||||
export const ARCHIVE_ROUTE = 'archive';
|
||||
export const DOSSIERS_ROUTE = 'dossiers';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"ADMIN_CONTACT_NAME": null,
|
||||
"ADMIN_CONTACT_URL": null,
|
||||
"API_URL": "https://dev-08.iqser.cloud/redaction-gateway-v1",
|
||||
"API_URL": "https://dev-04.iqser.cloud/redaction-gateway-v1",
|
||||
"APP_NAME": "RedactManager",
|
||||
"AUTO_READ_TIME": 3,
|
||||
"BACKEND_APP_VERSION": "4.4.40",
|
||||
@ -17,7 +17,7 @@
|
||||
"MAX_RETRIES_ON_SERVER_ERROR": 3,
|
||||
"OAUTH_CLIENT_ID": "redaction",
|
||||
"OAUTH_IDP_HINT": null,
|
||||
"OAUTH_URL": "https://dev-08.iqser.cloud/auth/realms/redaction",
|
||||
"OAUTH_URL": "https://dev-04.iqser.cloud/auth/realms/redaction",
|
||||
"RECENT_PERIOD_IN_HOURS": 24,
|
||||
"SELECTION_MODE": "structural",
|
||||
"MANUAL_BASE_URL": "https://docs.redactmanager.com/preview"
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 7bc942ae164164dadba94045f1f249a6cbb17284
|
||||
Subproject commit f06c007bec1a7da5c257e68d6df8c806419ceb2b
|
||||
@ -1,8 +1,9 @@
|
||||
import { IListable, IRouterPath, List } from '@iqser/common-ui';
|
||||
import { IListable, List } from '@iqser/common-ui';
|
||||
import { IDossier } from './dossier';
|
||||
import { DownloadFileType } from '../shared';
|
||||
import { ARCHIVE_ROUTE, DOSSIERS_ROUTE } from '@utils/constants';
|
||||
|
||||
export class Dossier implements IDossier, IListable, IRouterPath {
|
||||
export class Dossier implements IDossier, IListable {
|
||||
readonly dossierId: string;
|
||||
readonly dossierTemplateId: string;
|
||||
readonly ownerId: string;
|
||||
@ -23,7 +24,7 @@ export class Dossier implements IDossier, IListable, IRouterPath {
|
||||
readonly archivedTime: string;
|
||||
readonly hasReviewers: boolean;
|
||||
|
||||
constructor(dossier: IDossier, readonly routerPath: string) {
|
||||
constructor(dossier: IDossier) {
|
||||
this.dossierId = dossier.dossierId;
|
||||
this.approverIds = dossier.approverIds;
|
||||
this.date = dossier.date;
|
||||
@ -50,7 +51,12 @@ export class Dossier implements IDossier, IListable, IRouterPath {
|
||||
}
|
||||
|
||||
get routerLink(): string {
|
||||
return `/main/${this.dossierTemplateId}/${this.routerPath}/${this.dossierId}`;
|
||||
return `${this.dossiersListRouterLink}/${this.dossierId}`;
|
||||
}
|
||||
|
||||
get dossiersListRouterLink(): string {
|
||||
const routerPath = this.isArchived ? ARCHIVE_ROUTE : DOSSIERS_ROUTE;
|
||||
return `/main/${this.dossierTemplateId}/${routerPath}`;
|
||||
}
|
||||
|
||||
get searchKey(): string {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Entity, IRouterPath } from '@iqser/common-ui';
|
||||
import { Entity } from '@iqser/common-ui';
|
||||
import { StatusSorter } from '../shared';
|
||||
import {
|
||||
isFullProcessingStatuses,
|
||||
@ -10,8 +10,9 @@ import {
|
||||
} from './types';
|
||||
import { IFile } from './file';
|
||||
import { FileAttributes } from '../file-attributes';
|
||||
import { ARCHIVE_ROUTE, DOSSIERS_ROUTE } from '@utils/constants';
|
||||
|
||||
export class File extends Entity<IFile> implements IFile, IRouterPath {
|
||||
export class File extends Entity<IFile> implements IFile {
|
||||
readonly added?: string;
|
||||
readonly allManualRedactionsApplied: boolean;
|
||||
readonly analysisDuration?: number;
|
||||
@ -51,6 +52,8 @@ export class File extends Entity<IFile> implements IFile, IRouterPath {
|
||||
readonly redactionModificationDate: string;
|
||||
readonly lastManualChangeDate?: string;
|
||||
readonly hasHighlights: boolean;
|
||||
readonly dossierArchived: boolean;
|
||||
readonly dossierTemplateId: string;
|
||||
|
||||
readonly statusSort: number;
|
||||
readonly cacheIdentifier?: string;
|
||||
@ -70,7 +73,7 @@ export class File extends Entity<IFile> implements IFile, IRouterPath {
|
||||
readonly canBeOpened: boolean;
|
||||
readonly canBeOCRed: boolean;
|
||||
|
||||
constructor(file: IFile, readonly reviewerName: string, readonly routerPath: string, readonly dossierTemplateId?: string) {
|
||||
constructor(file: IFile, readonly reviewerName: string) {
|
||||
super(file);
|
||||
this.added = file.added;
|
||||
this.allManualRedactionsApplied = !!file.allManualRedactionsApplied;
|
||||
@ -112,6 +115,8 @@ export class File extends Entity<IFile> implements IFile, IRouterPath {
|
||||
this.redactionModificationDate = file.redactionModificationDate ?? '';
|
||||
this.lastManualChangeDate = file.lastManualChangeDate;
|
||||
this.hasHighlights = file.hasHighlights;
|
||||
this.dossierArchived = file.dossierArchived;
|
||||
this.dossierTemplateId = file.dossierTemplateId;
|
||||
|
||||
this.statusSort = StatusSorter[this.workflowStatus];
|
||||
this.cacheIdentifier = btoa(this.fileManipulationDate ?? '');
|
||||
@ -146,6 +151,7 @@ export class File extends Entity<IFile> implements IFile, IRouterPath {
|
||||
}
|
||||
|
||||
get routerLink(): string | undefined {
|
||||
return this.canBeOpened ? `/main/${this.dossierTemplateId}/${this.routerPath}/${this.dossierId}/file/${this.fileId}` : undefined;
|
||||
const routerPath = this.dossierArchived ? ARCHIVE_ROUTE : DOSSIERS_ROUTE;
|
||||
return this.canBeOpened ? `/main/${this.dossierTemplateId}/${routerPath}/${this.dossierId}/file/${this.fileId}` : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,6 +149,10 @@ export interface IFile {
|
||||
|
||||
readonly hasHighlights: boolean;
|
||||
|
||||
readonly dossierArchived: boolean;
|
||||
|
||||
readonly dossierTemplateId: string;
|
||||
|
||||
/**
|
||||
* Last time the actual file was touched
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user