diff --git a/apps/red-ui/src/app/app.module.ts b/apps/red-ui/src/app/app.module.ts index c1fa904c3..43417d861 100644 --- a/apps/red-ui/src/app/app.module.ts +++ b/apps/red-ui/src/app/app.module.ts @@ -68,7 +68,7 @@ import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { PdfViewerModule } from './modules/pdf-viewer/pdf-viewer.module'; import { ACTIVE_DOSSIERS_SERVICE, ARCHIVED_DOSSIERS_SERVICE } from './tokens'; -import { UI_ROOT } from '@common-ui/utils'; +import { GET_TENANT_FROM_PATH_FN, UI_ROOT } from '@common-ui/utils'; export const appModuleFactory = (config: AppConfig) => { @NgModule({ @@ -196,9 +196,8 @@ export const appModuleFactory = (config: AppConfig) => { provide: APP_BASE_HREF, useFactory: () => { const uiRoot = inject(UI_ROOT); - const pathParams = location.pathname.split('/').filter(Boolean); - const uiRootPathIndex = pathParams.indexOf(uiRoot.replace('/', '')); - const tenant = pathParams[uiRootPathIndex + 1] ?? ''; + const tenant = inject(GET_TENANT_FROM_PATH_FN)(); + console.log(tenant); const appBaseHref = uiRoot + '/' + tenant; inject(NGXLogger).info('Provide APP_BASE_HREF:', appBaseHref); diff --git a/apps/red-ui/src/app/components/base-screen/base-screen.component.ts b/apps/red-ui/src/app/components/base-screen/base-screen.component.ts index bc504493e..d0b3e4df2 100644 --- a/apps/red-ui/src/app/components/base-screen/base-screen.component.ts +++ b/apps/red-ui/src/app/components/base-screen/base-screen.component.ts @@ -14,7 +14,6 @@ import { Roles } from '@users/roles'; import { REDDocumentViewer } from '../../modules/pdf-viewer/services/document-viewer.service'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { List, shareDistinctLast } from '@iqser/common-ui/lib/utils'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; const isNavigationStart = (event: unknown): event is NavigationStart => event instanceof NavigationStart; const isSearchScreen: (url: string) => boolean = url => url.includes('/search'); @@ -24,12 +23,6 @@ const isSearchScreen: (url: string) => boolean = url => url.includes('/search'); styleUrls: ['./base-screen.component.scss'], }) export class BaseScreenComponent { - readonly #navigationStart$ = this._router.events.pipe( - filter(isNavigationStart), - map(event => event.url), - startWith(this._router.url), - shareDistinctLast(), - ); readonly roles = Roles; readonly documentViewer = inject(REDDocumentViewer); readonly currentUser = this.userService.currentUser; @@ -52,15 +45,20 @@ export class BaseScreenComponent { action: (query): void => this.#search(query, []), }, ]; - readonly isSearchScreen$ = this.#navigationStart$.pipe(map(isSearchScreen)); readonly config = getConfig(); + readonly #navigationStart$ = this._router.events.pipe( + filter(isNavigationStart), + map(event => event.url), + startWith(this._router.url), + shareDistinctLast(), + ); + readonly isSearchScreen$ = this.#navigationStart$.pipe(map(isSearchScreen)); constructor( private readonly _router: Router, activatedRoute: ActivatedRoute, private readonly _translateService: TranslateService, private readonly _featuresService: FeaturesService, - protected readonly _tenantsService: TenantsService, readonly permissionsService: IqserPermissionsService, readonly userService: UserService, readonly userPreferenceService: UserPreferenceService, @@ -94,7 +92,7 @@ export class BaseScreenComponent { #search(query: string, dossierIds: string[], onlyActive = false) { const queryParams = { query, dossierIds: dossierIds.join(','), onlyActive }; - this._router.navigate([`/${this._tenantsService.activeTenantId}/main/search`], { queryParams }).then(); + this._router.navigate(['/main/search'], { queryParams }).then(); } #searchThisDossier(query: string) { diff --git a/apps/red-ui/src/app/components/user-menu/user-menu.component.ts b/apps/red-ui/src/app/components/user-menu/user-menu.component.ts index 3ff2442e5..09b82eaf6 100644 --- a/apps/red-ui/src/app/components/user-menu/user-menu.component.ts +++ b/apps/red-ui/src/app/components/user-menu/user-menu.component.ts @@ -6,7 +6,6 @@ import { User } from '@red/domain'; import { UserService } from '@users/user.service'; import { getCurrentUser } from '@iqser/common-ui/lib/users'; import { List } from '@iqser/common-ui/lib/utils'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; interface MenuItem { readonly id: string; @@ -23,10 +22,9 @@ interface MenuItem { styleUrls: ['./user-menu.component.scss'], }) export class UserMenuComponent { - readonly #permissionsService = inject(IqserPermissionsService); readonly currentUser = getCurrentUser(); - readonly tenantsService = inject(TenantsService); readonly userService = inject(UserService); + readonly #permissionsService = inject(IqserPermissionsService); readonly userMenuItems: List = [ { id: 'account', diff --git a/apps/red-ui/src/app/guards/if-logged-in.guard.ts b/apps/red-ui/src/app/guards/if-logged-in.guard.ts index f92675e8a..b081d408e 100644 --- a/apps/red-ui/src/app/guards/if-logged-in.guard.ts +++ b/apps/red-ui/src/app/guards/if-logged-in.guard.ts @@ -8,6 +8,7 @@ import { UserService } from '@users/user.service'; import { jwtDecode } from 'jwt-decode'; import { KeycloakService } from 'keycloak-angular'; import { NGXLogger } from 'ngx-logger'; +import { GET_TENANT_FROM_PATH_FN } from '@common-ui/utils'; export interface JwtToken { auth_time: number; @@ -25,8 +26,9 @@ export function ifLoggedIn(): AsyncGuard { const licenseService = inject(LicenseService); const keycloakStatusService = inject(KeycloakStatusService); + const tenant = inject(GET_TENANT_FROM_PATH_FN)(); const keycloakInstance = keycloakService.getKeycloakInstance(); - const tenant = getRouteTenant(); + const queryParams = new URLSearchParams(window.location.search); const username = queryParams.get('username'); const router = inject(Router); diff --git a/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts b/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts index 6772443c4..1bd8db957 100644 --- a/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/base-entity-screen/base-entity-screen.component.ts @@ -10,17 +10,16 @@ import { DictionariesMapService } from '@services/entity-services/dictionaries-m import { map } from 'rxjs/operators'; import { PermissionsService } from '@services/permissions.service'; import { getParam } from '@iqser/common-ui/lib/utils'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; @Component({ templateUrl: './base-entity-screen.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class BaseEntityScreenComponent implements OnInit { - readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); - readonly #entityType = getParam(ENTITY_TYPE); readonly disabledItems$: Observable; readonly canDeleteEntity$: Observable; + readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); + readonly #entityType = getParam(ENTITY_TYPE); constructor( private readonly _router: Router, @@ -29,7 +28,6 @@ export class BaseEntityScreenComponent implements OnInit { private readonly _dialogService: AdminDialogService, private readonly _dictionaryService: DictionaryService, private readonly _permissionsService: PermissionsService, - private readonly _tenantsService: TenantsService, private readonly _dossierTemplatesService: DossierTemplatesService, ) { const entity$ = dictionaryMapService.watch$(this.#dossierTemplateId, this.#entityType); @@ -50,7 +48,7 @@ export class BaseEntityScreenComponent implements OnInit { this._loadingService.start(); const dossierTemplate = this._dossierTemplatesService.find(this.#dossierTemplateId); await firstValueFrom(this._dictionaryService.deleteDictionaries([this.#entityType], this.#dossierTemplateId)); - await this._router.navigate([`/${this._tenantsService.activeTenantId}/${dossierTemplate.routerLink}/entities`]); + await this._router.navigate([`/${dossierTemplate.routerLink}/entities`]); this._loadingService.stop(); }); } diff --git a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts index aebafb230..5e8d8d0b7 100644 --- a/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/watermark/watermark-screen/watermark-screen.component.ts @@ -5,7 +5,6 @@ import { Router } from '@angular/router'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { environment } from '@environments/environment'; import { getConfig, IconButtonTypes, IqserPermissionsService, LoadingService, Toaster } from '@iqser/common-ui'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; import { getCurrentUser } from '@iqser/common-ui/lib/users'; import { AsControl, Debounce, getParam, trackByFactory, UI_ROOT_PATH_FN } from '@iqser/common-ui/lib/utils'; import WebViewer, { WebViewerInstance } from '@pdftron/webviewer'; @@ -62,13 +61,6 @@ interface WatermarkForm { styleUrls: ['./watermark-screen.component.scss'], }) export class WatermarkScreenComponent implements OnInit { - @ViewChild('viewer', { static: true }) private readonly _viewer: ElementRef; - readonly #loaded$ = new BehaviorSubject(false); - readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); - readonly #watermarkId = Number(getParam(WATERMARK_ID)); - readonly #config = getConfig(); - #watermark: Partial = {}; - readonly #convertPath = inject(UI_ROOT_PATH_FN); readonly iconButtonTypes = IconButtonTypes; readonly translations = watermarkTranslations; readonly trackBy = trackByFactory(); @@ -86,6 +78,13 @@ export class WatermarkScreenComponent implements OnInit { readonly watermarkHorizontalAlignments = Object.values(WATERMARK_HORIZONTAL_ALIGNMENTS); readonly watermarkVerticalAlignments = Object.values(WATERMARK_VERTICAL_ALIGNMENTS); currentAlignment: WatermarkAlignment; + @ViewChild('viewer', { static: true }) private readonly _viewer: ElementRef; + readonly #loaded$ = new BehaviorSubject(false); + readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); + readonly #watermarkId = Number(getParam(WATERMARK_ID)); + readonly #config = getConfig(); + #watermark: Partial = {}; + readonly #convertPath = inject(UI_ROOT_PATH_FN); constructor( private readonly _http: HttpClient, @@ -93,7 +92,6 @@ export class WatermarkScreenComponent implements OnInit { private readonly _formBuilder: FormBuilder, readonly permissionsService: IqserPermissionsService, private readonly _loadingService: LoadingService, - private readonly _tenantsService: TenantsService, private readonly _licenseService: LicenseService, private readonly _watermarkService: WatermarkService, private readonly _userPreferenceService: UserPreferenceService, @@ -169,11 +167,7 @@ export class WatermarkScreenComponent implements OnInit { watermark.id ? _('watermark-screen.action.change-success') : _('watermark-screen.action.created-success'), ); if (!watermark.id) { - await this._router.navigate([ - `/${this._tenantsService.activeTenantId}/main/admin/dossier-templates/${this.#dossierTemplateId}/watermarks/${ - updatedWatermark.id - }`, - ]); + await this._router.navigate([`/main/admin/dossier-templates/${this.#dossierTemplateId}/watermarks/${updatedWatermark.id}`]); } } catch (error) { this._toaster.error(_('watermark-screen.action.error')); diff --git a/apps/red-ui/src/app/modules/admin/shared/components/dossier-template-actions/dossier-template-actions.component.ts b/apps/red-ui/src/app/modules/admin/shared/components/dossier-template-actions/dossier-template-actions.component.ts index d1442c0bd..468cb8e48 100644 --- a/apps/red-ui/src/app/modules/admin/shared/components/dossier-template-actions/dossier-template-actions.component.ts +++ b/apps/red-ui/src/app/modules/admin/shared/components/dossier-template-actions/dossier-template-actions.component.ts @@ -2,7 +2,6 @@ import { NgIf } from '@angular/common'; import { Component, Input, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { CircleButtonComponent, IqserHelpModeModule, LoadingService } from '@iqser/common-ui'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; import { getCurrentUser } from '@iqser/common-ui/lib/users'; import { TranslateModule } from '@ngx-translate/core'; import { DOSSIER_TEMPLATE_ID, type User } from '@red/domain'; @@ -27,7 +26,6 @@ export class DossierTemplateActionsComponent implements OnInit { private readonly _route: ActivatedRoute, private readonly _loadingService: LoadingService, private readonly _dialogService: AdminDialogService, - private readonly _tenantsService: TenantsService, private readonly _dossierTemplatesService: DossierTemplatesService, ) {} @@ -45,7 +43,7 @@ export class DossierTemplateActionsComponent implements OnInit { const success = await firstValueFrom(this._dossierTemplatesService.delete([this.dossierTemplateId])); if (success) { - await this._router.navigate([this._tenantsService.activeTenantId, 'main', 'admin']); + await this._router.navigate(['main', 'admin']); } this._loadingService.stop(); diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html b/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html index 91a65850e..ea7faab92 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html +++ b/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.html @@ -1,5 +1,5 @@ - - + + diff --git a/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.ts b/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.ts index f59fcc8fc..ceb2006b9 100644 --- a/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.ts +++ b/apps/red-ui/src/app/modules/dossier-overview/components/screen-header/dossier-overview-screen-header.component.ts @@ -13,7 +13,6 @@ import { Router } from '@angular/router'; import { Roles } from '@users/roles'; import { SortingService } from '@iqser/common-ui/lib/sorting'; import { List, some } from '@iqser/common-ui/lib/utils'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; import { ComponentLogService } from '@services/files/component-log.service'; @Component({ @@ -39,7 +38,6 @@ export class DossierOverviewScreenHeaderComponent implements OnInit { readonly sortingService: SortingService, readonly permissionsService: PermissionsService, readonly entitiesService: EntitiesService, - readonly tenantsService: TenantsService, private readonly _reanalysisService: ReanalysisService, private readonly _loadingService: LoadingService, private readonly _primaryFileAttributeService: PrimaryFileAttributeService, diff --git a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts index 55f89f721..bd208d4c2 100644 --- a/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts +++ b/apps/red-ui/src/app/modules/file-preview/file-preview-screen.component.ts @@ -32,7 +32,6 @@ import { Toaster, } from '@iqser/common-ui'; import { copyLocalStorageFiltersValues, FilterService, NestedFilter, processFilters } from '@iqser/common-ui/lib/filtering'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; import { AutoUnsubscribe, Bind, bool, Debounce, List, OnAttach, OnDetach } from '@iqser/common-ui/lib/utils'; import { AnnotationWrapper } from '@models/file/annotation.wrapper'; import { ManualRedactionEntryTypes, ManualRedactionEntryWrapper } from '@models/file/manual-redaction-entry.wrapper'; @@ -108,34 +107,6 @@ export class FilePreviewScreenComponent @ViewChild('actionsWrapper', { static: false }) private readonly _actionsWrapper: ElementRef; readonly #isDocumine = getConfig().IS_DOCUMINE; - get changed() { - return this._pageRotationService.hasRotations(); - } - - get #earmarks$() { - const isEarmarksViewMode$ = this._viewModeService.viewMode$.pipe(filter(() => this._viewModeService.isEarmarks())); - - const earmarks$ = isEarmarksViewMode$.pipe( - tap(() => this._loadingService.start()), - switchMap(() => this._fileDataService.loadEarmarks()), - tap(() => this.updateViewMode().then(() => this._loadingService.stop())), - ); - - const currentPageIfEarmarksView$ = combineLatest([this.pdf.currentPage$, this._viewModeService.viewMode$]).pipe( - filter(() => this._viewModeService.isEarmarks()), - map(([page]) => page), - ); - - const currentPageEarmarks$ = combineLatest([currentPageIfEarmarksView$, earmarks$]).pipe( - map(([page, earmarks]) => earmarks.get(page)), - ); - - return currentPageEarmarks$.pipe( - map(earmarks => [earmarks, this._skippedService.hideSkipped(), this.state.dossierTemplateId] as const), - tap(args => this._annotationDrawService.draw(...args)), - ); - } - constructor( readonly pdf: PdfViewer, readonly state: FilePreviewStateService, @@ -159,7 +130,6 @@ export class FilePreviewScreenComponent private readonly _viewModeService: ViewModeService, private readonly _documentViewer: REDDocumentViewer, private readonly _changeRef: ChangeDetectorRef, - private readonly _tenantsService: TenantsService, private readonly _dialogService: FilePreviewDialogService, private readonly _iqserDialog: IqserDialog, private readonly _pageRotationService: PageRotationService, @@ -212,6 +182,34 @@ export class FilePreviewScreenComponent }); } + get changed() { + return this._pageRotationService.hasRotations(); + } + + get #earmarks$() { + const isEarmarksViewMode$ = this._viewModeService.viewMode$.pipe(filter(() => this._viewModeService.isEarmarks())); + + const earmarks$ = isEarmarksViewMode$.pipe( + tap(() => this._loadingService.start()), + switchMap(() => this._fileDataService.loadEarmarks()), + tap(() => this.updateViewMode().then(() => this._loadingService.stop())), + ); + + const currentPageIfEarmarksView$ = combineLatest([this.pdf.currentPage$, this._viewModeService.viewMode$]).pipe( + filter(() => this._viewModeService.isEarmarks()), + map(([page]) => page), + ); + + const currentPageEarmarks$ = combineLatest([currentPageIfEarmarksView$, earmarks$]).pipe( + map(([page, earmarks]) => earmarks.get(page)), + ); + + return currentPageEarmarks$.pipe( + map(earmarks => [earmarks, this._skippedService.hideSkipped(), this.state.dossierTemplateId] as const), + tap(args => this._annotationDrawService.draw(...args)), + ); + } + getLastAssignee() { const { isApproved, lastReviewer, lastApprover } = this.state.file(); const isRss = this._iqserPermissionsService.has(this.roles.getRss); @@ -853,7 +851,7 @@ export class FilePreviewScreenComponent #navigateToDossier() { this._logger.info('Navigating to ', this.state.dossier().dossierName); - return this._router.navigate([`/${this._tenantsService.activeTenantId}${this.state.dossier().routerLink}`]); + return this._router.navigate([this.state.dossier().routerLink]); } #highlightSelectedAnnotations(newAnnotations: AnnotationWrapper[]) { diff --git a/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts b/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts index bd8c49d66..157a7e963 100644 --- a/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts +++ b/apps/red-ui/src/app/modules/file-preview/services/pdf-annotation-actions.service.ts @@ -9,6 +9,7 @@ import { PermissionsService } from '@services/permissions.service'; import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service'; import { AnnotationActionsService } from './annotation-actions.service'; import { FilePreviewStateService } from './file-preview-state.service'; +import { UI_ROOT_PATH_FN } from '@common-ui/utils'; @Injectable() export class PdfAnnotationActionsService { @@ -20,6 +21,7 @@ export class PdfAnnotationActionsService { readonly #iqserPermissionsService = inject(IqserPermissionsService); readonly #annotationManager = inject(REDAnnotationManager); readonly #isDocumine = getConfig().IS_DOCUMINE; + readonly #convertPath = inject(UI_ROOT_PATH_FN); get(annotations: AnnotationWrapper[], annotationChangesAllowed: boolean): IHeaderElement[] { const availableActions: IHeaderElement[] = []; @@ -105,7 +107,7 @@ export class PdfAnnotationActionsService { #getButton(icon: string, title: string, action: () => void | Promise): IHeaderElement { return { type: 'actionButton', - img: `ui/assets/icons/general/${icon}.svg`, + img: this.#convertPath(`/assets/icons/general/${icon}.svg`), title: this.#translateService.instant(title), onClick: () => this.#ngZone.run(async () => action()), }; diff --git a/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts index fe0d4c8e7..878f56a19 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts +++ b/apps/red-ui/src/app/modules/shared-dossiers/components/file-actions/file-actions.component.ts @@ -11,7 +11,6 @@ import { LoadingService, Toaster, } from '@iqser/common-ui'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; import { getCurrentUser } from '@iqser/common-ui/lib/users'; import { IqserTooltipPositions } from '@iqser/common-ui/lib/utils'; import { Action, ActionTypes, Dossier, File, ProcessingFileStatuses, User } from '@red/domain'; @@ -42,9 +41,6 @@ import { FileAssignService } from '../../services/file-assign.service'; styleUrls: ['./file-actions.component.scss'], }) export class FileActionsComponent implements OnChanges { - @ViewChild(ExpandableFileActionsComponent) - private readonly _expandableActionsComponent: ExpandableFileActionsComponent; - readonly #isDocumine = getConfig().IS_DOCUMINE; @Input({ required: true }) file: File; @Input({ required: true }) dossier: Dossier; @Input({ required: true }) type: 'file-preview' | 'dossier-overview-list' | 'dossier-overview-workflow'; @@ -79,6 +75,9 @@ export class FileActionsComponent implements OnChanges { isFilePreview = false; tooltipPosition = IqserTooltipPositions.above; buttons: Action[]; + @ViewChild(ExpandableFileActionsComponent) + private readonly _expandableActionsComponent: ExpandableFileActionsComponent; + readonly #isDocumine = getConfig().IS_DOCUMINE; constructor( private readonly _injector: Injector, @@ -87,7 +86,6 @@ export class FileActionsComponent implements OnChanges { private readonly _loadingService: LoadingService, private readonly _dialogService: DossiersDialogService, private readonly _iqserDialog: IqserDialog, - private readonly _tenantsService: TenantsService, private readonly _fileAssignService: FileAssignService, private readonly _reanalysisService: ReanalysisService, private readonly _permissionsService: PermissionsService, @@ -346,7 +344,7 @@ export class FileActionsComponent implements OnChanges { try { const dossier = this._activeDossiersService.find(this.file.dossierId); await firstValueFrom(this._fileManagementService.delete([this.file], this.file.dossierId)); - await this._injector.get(Router).navigate([`/${this._tenantsService.activeTenantId}${dossier.routerLink}`]); + await this._injector.get(Router).navigate([dossier.routerLink]); } catch (error) { this._injector.get(Toaster).error(_('error.http.generic'), { params: error }); } diff --git a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts index de8abc536..21a78a38c 100644 --- a/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts +++ b/apps/red-ui/src/app/modules/shared-dossiers/dialogs/edit-dossier-dialog/general-info/edit-dossier-general-info.component.ts @@ -19,7 +19,6 @@ import { ArchivedDossiersService } from '@services/dossiers/archived-dossiers.se import { DossierStatesMapService } from '@services/entity-services/dossier-states-map.service'; import dayjs from 'dayjs'; import { dateWithoutTime } from '@utils/functions'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; @Component({ selector: 'redaction-edit-dossier-general-info', @@ -38,6 +37,23 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti dossierTemplates: IDossierTemplate[]; states: string[]; + constructor( + readonly permissionsService: PermissionsService, + private readonly _dossierStatesMapService: DossierStatesMapService, + private readonly _dossierTemplatesService: DossierTemplatesService, + private readonly _dossiersService: DossiersService, + private readonly _trashService: TrashService, + private readonly _dossierStatsService: DossierStatsService, + private readonly _formBuilder: UntypedFormBuilder, + private readonly _dialogService: DossiersDialogService, + private readonly _router: Router, + private readonly _editDossierDialogRef: MatDialogRef, + private readonly _toaster: Toaster, + private readonly _loadingService: LoadingService, + private readonly _translateService: TranslateService, + private readonly _archivedDossiersService: ArchivedDossiersService, + ) {} + get changed(): boolean { for (const key of Object.keys(this.form.getRawValue())) { if (key === 'dueDate') { @@ -71,24 +87,6 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti ) as string; } - constructor( - readonly permissionsService: PermissionsService, - private readonly _dossierStatesMapService: DossierStatesMapService, - private readonly _dossierTemplatesService: DossierTemplatesService, - private readonly _dossiersService: DossiersService, - private readonly _trashService: TrashService, - private readonly _dossierStatsService: DossierStatsService, - private readonly _formBuilder: UntypedFormBuilder, - private readonly _dialogService: DossiersDialogService, - private readonly _router: Router, - private readonly _tenantsService: TenantsService, - private readonly _editDossierDialogRef: MatDialogRef, - private readonly _toaster: Toaster, - private readonly _loadingService: LoadingService, - private readonly _translateService: TranslateService, - private readonly _archivedDossiersService: ArchivedDossiersService, - ) {} - ngOnInit() { this.states = [null, ...this._dossierStatesMapService.get(this.dossier.dossierTemplateId).map(s => s.id)]; this.statusPlaceholder = this.#statusPlaceholder; @@ -126,7 +124,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti const updatedDossier = await firstValueFrom(this._dossiersService.createOrUpdate(dossier)); if (updatedDossier && updatedDossier.dossierTemplateId !== this.dossier.dossierTemplateId) { - await this._router.navigate([`/${this._tenantsService.activeTenantId}${updatedDossier.routerLink}`]); + await this._router.navigate([updatedDossier.routerLink]); } return { success: !!updatedDossier }; } @@ -194,7 +192,7 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti async #closeDialogAndRedirectToDossier() { this._editDossierDialogRef.close(); - await this._router.navigate([`/${this._tenantsService.activeTenantId}${this.dossier.dossiersListRouterLink}`]); + await this._router.navigate([this.dossier.dossiersListRouterLink]); this._toaster.success(_('edit-dossier-dialog.delete-successful'), { params: { dossierName: this.dossier.dossierName, diff --git a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts index eac1cd16a..5a58c1260 100644 --- a/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/buttons/file-download-btn/file-download-btn.component.ts @@ -1,11 +1,11 @@ -import { Component, Input, OnChanges } from '@angular/core'; +import { Component, inject, Input, OnChanges } from '@angular/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { CircleButtonType, CircleButtonTypes, IqserDialog, Toaster } from '@iqser/common-ui'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; import { Dossier, File, ProcessingFileStatuses } from '@red/domain'; import { PermissionsService } from '@services/permissions.service'; import { DownloadDialogComponent } from '@shared/dialogs/download-dialog/download-dialog.component'; import { FileDownloadService } from '@upload-download/services/file-download.service'; +import { APP_BASE_HREF } from '@angular/common'; @Component({ selector: 'redaction-file-download-btn', @@ -19,14 +19,13 @@ export class FileDownloadBtnComponent implements OnChanges { @Input() type: CircleButtonType = CircleButtonTypes.default; @Input() tooltipClass: string; @Input() disabled = false; - tooltip: string; canDownloadFiles: boolean; invalidDownload = false; + readonly #appBaseHref = inject(APP_BASE_HREF); constructor( private readonly _permissionsService: PermissionsService, - private readonly _tenantsService: TenantsService, private readonly _fileDownloadService: FileDownloadService, private readonly _dialog: IqserDialog, private readonly _toaster: Toaster, @@ -56,7 +55,7 @@ export class FileDownloadBtnComponent implements OnChanges { await downloadRequest .then(() => this._toaster.info(_('download-status.queued'), { - params: { downloadHref: `/ui/${this._tenantsService.activeTenantId}/main/downloads` }, + params: { downloadHref: `${this.#appBaseHref}/main/downloads` }, }), ) .catch(() => this._toaster.error(_('download-status.error'))); diff --git a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts index e7b8fd5a5..7d2ab4a41 100644 --- a/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts +++ b/apps/red-ui/src/app/modules/shared/components/expandable-file-actions/expandable-file-actions.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnChanges, SimpleChanges, ViewChild } from '@angular/core'; +import { Component, inject, Input, OnChanges, SimpleChanges, ViewChild } from '@angular/core'; import { Action, ActionTypes, Dossier, File } from '@red/domain'; import { CircleButtonType, IqserDialog, Toaster } from '@iqser/common-ui'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; @@ -7,7 +7,7 @@ import { PermissionsService } from '@services/permissions.service'; import { MatMenuTrigger } from '@angular/material/menu'; import { DownloadDialogComponent } from '@shared/dialogs/download-dialog/download-dialog.component'; import { IqserTooltipPosition, trackByFactory } from '@iqser/common-ui/lib/utils'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; +import { APP_BASE_HREF } from '@angular/common'; @Component({ selector: 'redaction-expandable-file-actions', @@ -22,17 +22,15 @@ export class ExpandableFileActionsComponent implements OnChanges { @Input() tooltipPosition: IqserTooltipPosition; @Input() helpModeKeyPrefix: 'dossier' | 'editor'; @Input() isDossierOverviewWorkflow = false; - displayedButtons: Action[]; hiddenButtons: Action[]; expanded = false; - @ViewChild(MatMenuTrigger) readonly matMenu: MatMenuTrigger; readonly trackBy = trackByFactory(); + readonly #appBaseHref = inject(APP_BASE_HREF); constructor( private readonly _fileDownloadService: FileDownloadService, - private readonly _tenantsService: TenantsService, private readonly _toaster: Toaster, private readonly _permissionsService: PermissionsService, private readonly _dialog: IqserDialog, @@ -101,7 +99,7 @@ export class ExpandableFileActionsComponent implements OnChanges { ...result, }); this._toaster.info(_('download-status.queued'), { - params: { downloadHref: `/ui/${this._tenantsService.activeTenantId}/main/downloads` }, + params: { downloadHref: `${this.#appBaseHref}/main/downloads` }, }); } } diff --git a/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts b/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts index 2b4b29235..e7bb8ebce 100644 --- a/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts +++ b/apps/red-ui/src/app/modules/shared/dialogs/add-dossier-dialog/add-dossier-dialog.component.ts @@ -3,7 +3,6 @@ import { Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Router } from '@angular/router'; import { BaseDialogComponent, getConfig, IconButtonTypes, IqserPermissionsService, SaveOptions } from '@iqser/common-ui'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; import { DOSSIER_TEMPLATE_ID, DownloadFileType, IDossierRequest, IDossierTemplate, IReportTemplate } from '@red/domain'; import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service'; import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service'; @@ -39,7 +38,6 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On constructor( readonly permissionsService: IqserPermissionsService, - private readonly _tenantsService: TenantsService, private readonly _activeDossiersService: ActiveDossiersService, private readonly _dossierTemplatesService: DossierTemplatesService, private readonly _reportTemplateService: ReportTemplateService, @@ -80,7 +78,7 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On this._loadingService.start(); const savedDossier = await firstValueFrom(this._activeDossiersService.createOrUpdate(this.#formToObject())); if (savedDossier) { - await this._router.navigate([`/${this._tenantsService.activeTenantId}${savedDossier.routerLink}`]); + await this._router.navigate([savedDossier.routerLink]); if (options?.addMembers) { this._dialogService.openDialog('editDossier', { dossierId: savedDossier.id, diff --git a/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts b/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts index abdcb784a..bc8e9b2fe 100644 --- a/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts +++ b/apps/red-ui/src/app/services/dossiers/archived-dossiers.service.ts @@ -8,17 +8,15 @@ import { DossiersService } from './dossiers.service'; import { FilesMapService } from '../files/files-map.service'; import { FeaturesService } from '../features.service'; import { Router } from '@angular/router'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; @Injectable({ providedIn: 'root' }) export class ArchivedDossiersService extends DossiersService { + readonly routerPath = ARCHIVE_ROUTE; + protected readonly _defaultModelPath = 'archived-dossiers'; readonly #activeDossiersService = inject(ActiveDossiersService); readonly #filesMapService = inject(FilesMapService); readonly #featuresService = inject(FeaturesService); - readonly #tenantsService = inject(TenantsService); readonly #router = inject(Router); - protected readonly _defaultModelPath = 'archived-dossiers'; - readonly routerPath = ARCHIVE_ROUTE; archive(dossiers: Dossier[]): Observable { const showArchiveFailedToast = () => { @@ -41,7 +39,7 @@ export class ArchivedDossiersService extends DossiersService { if (!this.#activeDossiersService.all.find(d => d.dossierTemplateId === dossierTemplateId)) { route = route.replace(DOSSIERS_ROUTE, ARCHIVE_ROUTE); } - await this.#router.navigate([`/${this.#tenantsService.activeTenantId}${route}`]); + await this.#router.navigate([route]); }), catchError(showArchiveFailedToast), ); diff --git a/apps/red-ui/src/app/services/notifications.service.ts b/apps/red-ui/src/app/services/notifications.service.ts index 7a15ea5a8..232e14721 100644 --- a/apps/red-ui/src/app/services/notifications.service.ts +++ b/apps/red-ui/src/app/services/notifications.service.ts @@ -1,4 +1,4 @@ -import { Inject, Injectable, OnDestroy } from '@angular/core'; +import { inject, Injectable, OnDestroy } from '@angular/core'; import { EntitiesService, getConfig, QueryParam } from '@iqser/common-ui'; import { TranslateService } from '@ngx-translate/core'; import { EMPTY, firstValueFrom, iif, merge, Observable, of, Subscription, timer } from 'rxjs'; @@ -11,7 +11,6 @@ import { CHANGED_CHECK_INTERVAL } from '@utils/constants'; import { DossiersCacheService } from './dossiers/dossiers-cache.service'; import dayjs from 'dayjs'; import { List, mapEach } from '@iqser/common-ui/lib/utils'; -import { TenantsService } from '@iqser/common-ui/lib/tenants'; import { APP_BASE_HREF } from '@angular/common'; const INCLUDE_SEEN = false; @@ -28,11 +27,10 @@ export class NotificationsService extends EntitiesService(); readonly #subscription = new Subscription(); + readonly #appBaseHref = inject(APP_BASE_HREF); constructor( - @Inject(APP_BASE_HREF) private readonly _baseHref: string, private readonly _translateService: TranslateService, - private readonly _tenantsService: TenantsService, private readonly _userService: UserService, private readonly _dossiersCacheService: DossiersCacheService, ) { @@ -80,7 +78,7 @@ export class NotificationsService extends EntitiesService