RED-3800, refactor multitenancy
This commit is contained in:
parent
a53d139687
commit
b7a9b5c77c
@ -34,7 +34,6 @@
|
||||
"main": "apps/red-ui/src/main.ts",
|
||||
"polyfills": "apps/red-ui/src/polyfills.ts",
|
||||
"tsConfig": "apps/red-ui/tsconfig.json",
|
||||
"baseHref": "/ui/",
|
||||
"assets": [
|
||||
"apps/red-ui/src/favicon.ico",
|
||||
{
|
||||
|
||||
@ -205,18 +205,13 @@ const routes: IqserRoutes = [
|
||||
component: TenantSelectComponent,
|
||||
},
|
||||
{
|
||||
path: ':tenant',
|
||||
redirectTo: ':tenant/main',
|
||||
pathMatch: 'full',
|
||||
},
|
||||
{
|
||||
path: ':tenant/main',
|
||||
path: 'main',
|
||||
canActivate: [orderedAsyncGuards([ifLoggedIn(), hasAnyRole(), mainGuard()])],
|
||||
component: BaseScreenComponent,
|
||||
children: mainRoutes,
|
||||
},
|
||||
{
|
||||
path: ':tenant/auth-error',
|
||||
path: 'auth-error',
|
||||
component: AuthErrorComponent,
|
||||
canActivate: [doesNotHaveAnyRole()],
|
||||
},
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { DatePipe as BaseDatePipe } from '@angular/common';
|
||||
import { APP_BASE_HREF, DatePipe as BaseDatePipe } from '@angular/common';
|
||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { ENVIRONMENT_INITIALIZER, ErrorHandler, inject, NgModule } from '@angular/core';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
@ -43,7 +43,7 @@ import {
|
||||
} from '@iqser/common-ui';
|
||||
import { CommonUiModule } from '@iqser/common-ui/lib/common-ui.module';
|
||||
import { LogoComponent, SkeletonComponent, ToastComponent } from '@iqser/common-ui/lib/shared';
|
||||
import { TenantPipe, TenantsModule } from '@iqser/common-ui/lib/tenants';
|
||||
import { TenantsModule } from '@iqser/common-ui/lib/tenants';
|
||||
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
|
||||
import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor';
|
||||
import { MissingTranslationHandler } from '@ngx-translate/core';
|
||||
@ -61,13 +61,14 @@ import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { UserService } from '@users/user.service';
|
||||
import { UI_CACHES } from '@utils/constants';
|
||||
import { REDMissingTranslationHandler } from '@utils/missing-translations-handler';
|
||||
import { LoggerModule, NgxLoggerLevel, TOKEN_LOGGER_CONFIG, TOKEN_LOGGER_RULES_SERVICE } from 'ngx-logger';
|
||||
import { LoggerModule, NGXLogger, NgxLoggerLevel, TOKEN_LOGGER_CONFIG, TOKEN_LOGGER_RULES_SERVICE } from 'ngx-logger';
|
||||
import { ToastrModule } from 'ngx-toastr';
|
||||
import * as helpModeKeys from '../assets/help-mode/help-mode-keys.json';
|
||||
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';
|
||||
|
||||
export const appModuleFactory = (config: AppConfig) => {
|
||||
@NgModule({
|
||||
@ -183,11 +184,27 @@ export const appModuleFactory = (config: AppConfig) => {
|
||||
IqserDenyDirective,
|
||||
IqserListingModule,
|
||||
IconButtonComponent,
|
||||
TenantPipe,
|
||||
MatDividerModule,
|
||||
ChevronButtonComponent,
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: UI_ROOT,
|
||||
useValue: '/ui',
|
||||
},
|
||||
{
|
||||
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 appBaseHref = uiRoot + '/' + tenant;
|
||||
|
||||
inject(NGXLogger).info('Provide APP_BASE_HREF:', appBaseHref);
|
||||
return appBaseHref;
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
multi: true,
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<redaction-breadcrumbs></redaction-breadcrumbs>
|
||||
</div>
|
||||
|
||||
<a [matTooltip]="'top-bar.navigation-items.back-to-dashboard' | translate" [routerLink]="['/'] | tenant" class="logo">
|
||||
<a [matTooltip]="'top-bar.navigation-items.back-to-dashboard' | translate" [routerLink]="['/']" class="logo">
|
||||
<div [attr.help-mode-key]="'home'" class="actions">
|
||||
<iqser-logo (iqserHiddenAction)="userPreferenceService.toggleDevFeatures()" icon="iqser:logo"></iqser-logo>
|
||||
<div class="app-name">{{ titleService.getTitle() }}</div>
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
[id]="first ? 'navigateToActiveDossiers' : ''"
|
||||
[matTooltip]="breadcrumb.options.clamp && (breadcrumb.name$ | async)"
|
||||
[routerLinkActiveOptions]="breadcrumb.options.routerLinkActiveOptions || { exact: false }"
|
||||
[routerLink]="breadcrumb.options.routerLink | tenant"
|
||||
[routerLink]="breadcrumb.options.routerLink"
|
||||
class="breadcrumb"
|
||||
routerLinkActive="active"
|
||||
>
|
||||
@ -32,7 +32,7 @@
|
||||
<div id="breadcrumbs-menu-items">
|
||||
<a
|
||||
*ngFor="let option of breadcrumb.options.options"
|
||||
[routerLink]="option.options.routerLink | tenant"
|
||||
[routerLink]="option.options.routerLink"
|
||||
mat-menu-item
|
||||
routerLinkActive="active"
|
||||
>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<div id="user-menu-items">
|
||||
<ng-container *ngFor="let item of userMenuItems; trackBy: trackBy">
|
||||
<a (click)="item.action?.()" *ngIf="item.show" [id]="item.id" [routerLink]="item.routerLink | tenant" mat-menu-item>
|
||||
<a (click)="item.action?.()" *ngIf="item.show" [id]="item.id" [routerLink]="item.routerLink" mat-menu-item>
|
||||
{{ item.name | translate }}
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { Injectable, Injector, ProviderToken } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
|
||||
import { getConfig } from '@iqser/common-ui';
|
||||
import { TenantsService } from '@iqser/common-ui/lib/tenants';
|
||||
import { DOSSIER_ID, DOSSIER_TEMPLATE_ID } from '@red/domain';
|
||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||
import { DictionaryService } from '@services/entity-services/dictionary.service';
|
||||
@ -16,7 +15,6 @@ export class DossierFilesGuard implements CanActivate {
|
||||
|
||||
constructor(
|
||||
private readonly _injector: Injector,
|
||||
private readonly _tenantsService: TenantsService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _filesService: FilesService,
|
||||
private readonly _dictionaryService: DictionaryService,
|
||||
@ -37,7 +35,7 @@ export class DossierFilesGuard implements CanActivate {
|
||||
}
|
||||
|
||||
if (!dossiersService.has(dossierId)) {
|
||||
await this._router.navigate([`/${this._tenantsService.activeTenantId}/main`, dossierTemplateId]);
|
||||
await this._router.navigate(['/main', dossierTemplateId]);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { inject } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivateFn, Router } from '@angular/router';
|
||||
import { TenantsService } from '@iqser/common-ui/lib/tenants';
|
||||
import { DOSSIER_TEMPLATE_ID } from '@red/domain';
|
||||
import { DashboardStatsService } from '@services/dossier-templates/dashboard-stats.service';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
@ -15,7 +14,7 @@ export function templateExistsWhenEnteringAdmin(): CanActivateFn {
|
||||
|
||||
const dossierTemplate = inject(DossierTemplateStatsService).get(dossierTemplateId);
|
||||
if (!dossierTemplate) {
|
||||
await inject(Router).navigate([inject(TenantsService).activeTenantId, 'main', 'admin', 'dossier-templates']);
|
||||
await inject(Router).navigate(['main', 'admin', 'dossier-templates']);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -29,7 +28,6 @@ export function templateExistsWhenEnteringDossierList(): CanActivateFn {
|
||||
const dossierTemplatesService = inject(DossierTemplatesService);
|
||||
const logger = inject(NGXLogger);
|
||||
const router = inject(Router);
|
||||
const tenantsService = inject(TenantsService);
|
||||
const userPreferencesService = inject(UserPreferenceService);
|
||||
|
||||
await firstValueFrom(dashboardStatsService.loadAll());
|
||||
@ -38,7 +36,7 @@ export function templateExistsWhenEnteringDossierList(): CanActivateFn {
|
||||
if (!dossierTemplateStats || dossierTemplateStats.isEmpty) {
|
||||
logger.warn(`[ROUTES] Dossier template ${dossierTemplateId} not found, redirecting to main`);
|
||||
await userPreferencesService.saveLastDossierTemplate(null);
|
||||
await router.navigate([tenantsService.activeTenantId, 'main']);
|
||||
await router.navigate(['main']);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@ -25,19 +25,23 @@ export function ifLoggedIn(): AsyncGuard {
|
||||
const keycloakStatusService = inject(KeycloakStatusService);
|
||||
|
||||
const keycloakInstance = keycloakService.getKeycloakInstance();
|
||||
const tenant = route.paramMap.get('tenant');
|
||||
const pathParams = location.pathname.split('/').filter(Boolean);
|
||||
const uiPathIndex = pathParams.indexOf('ui');
|
||||
const tenant = pathParams[uiPathIndex + 1];
|
||||
const queryParams = new URLSearchParams(window.location.search);
|
||||
const username = queryParams.get('username');
|
||||
const router = inject(Router);
|
||||
|
||||
if (!keycloakInstance) {
|
||||
if (!tenant) {
|
||||
logger.error('[ROUTES] No tenant found, something is wrong...');
|
||||
return inject(Router).navigate(['/']);
|
||||
return router.navigate(['/']);
|
||||
}
|
||||
|
||||
logger.info('[KEYCLOAK] Keycloak init...');
|
||||
await keycloakInitializer(tenant);
|
||||
logger.info('[KEYCLOAK] Keycloak init done!');
|
||||
console.log({ tenant });
|
||||
await tenantsService.selectTenant(tenant);
|
||||
await usersService.initialize();
|
||||
await licenseService.loadLicenses();
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { ActivatedRouteSnapshot, CanActivateFn, Router } from '@angular/router';
|
||||
import { CanActivateFn, Router } from '@angular/router';
|
||||
import { inject } from '@angular/core';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
export function ifNotLoggedIn(): CanActivateFn {
|
||||
return async (route: ActivatedRouteSnapshot) => {
|
||||
return async () => {
|
||||
const logger = inject(NGXLogger);
|
||||
const router = inject(Router);
|
||||
const keycloakService = inject(KeycloakService);
|
||||
@ -16,14 +16,14 @@ export function ifNotLoggedIn(): CanActivateFn {
|
||||
return true;
|
||||
}
|
||||
|
||||
const tenant = route.paramMap.get('tenant') || keycloakService.getKeycloakInstance().realm;
|
||||
const tenant = keycloakService.getKeycloakInstance().realm;
|
||||
if (!tenant) {
|
||||
logger.error('[ROUTES] Tenant not found in route or keycloak realm');
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.warn('[ROUTES] Is logged in for ' + tenant + ', redirecting to /' + tenant);
|
||||
await router.navigate([tenant]);
|
||||
await router.navigate(['/main']);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
@ -55,7 +55,6 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AuditInfoDialogComponent } from './dialogs/audit-info-dialog/audit-info-dialog.component';
|
||||
import { DossierTemplateActionsComponent } from './shared/components/dossier-template-actions/dossier-template-actions.component';
|
||||
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
|
||||
import { TenantPipe } from '@iqser/common-ui/lib/tenants';
|
||||
import { SelectComponent } from '@shared/components/select/select.component';
|
||||
import { PaginationComponent } from '@common-ui/pagination/pagination.component';
|
||||
|
||||
@ -124,7 +123,6 @@ const components = [
|
||||
DetailsRadioComponent,
|
||||
IqserAllowDirective,
|
||||
IqserDenyDirective,
|
||||
TenantPipe,
|
||||
SelectComponent,
|
||||
PaginationComponent,
|
||||
],
|
||||
|
||||
@ -107,7 +107,7 @@
|
||||
|
||||
<iqser-circle-button
|
||||
*ngIf="permissionsService.canEditEntities()"
|
||||
[routerLink]="dict.routerLink | tenant"
|
||||
[routerLink]="dict.routerLink"
|
||||
[tooltip]="'entities-listing.action.edit' | translate"
|
||||
icon="iqser:edit"
|
||||
></iqser-circle-button>
|
||||
|
||||
@ -30,7 +30,7 @@ import { environment } from '@environments/environment';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { watermarkTranslations } from '@translations/watermark-translations';
|
||||
import { getCurrentUser } from '@iqser/common-ui/lib/users';
|
||||
import { AsControl, BASE_HREF_FN, Debounce, getParam, trackByFactory } from '@iqser/common-ui/lib/utils';
|
||||
import { AsControl, Debounce, getParam, trackByFactory, UI_ROOT_PATH_FN } from '@iqser/common-ui/lib/utils';
|
||||
import { TenantsService } from '@iqser/common-ui/lib/tenants';
|
||||
|
||||
export const DEFAULT_WATERMARK: Partial<IWatermark> = {
|
||||
@ -62,13 +62,6 @@ interface WatermarkForm {
|
||||
styleUrls: ['./watermark-screen.component.scss'],
|
||||
})
|
||||
export class WatermarkScreenComponent implements OnInit {
|
||||
@ViewChild('viewer', { static: true }) private readonly _viewer: ElementRef<HTMLDivElement>;
|
||||
private readonly _convertPath = inject(BASE_HREF_FN);
|
||||
readonly #loaded$ = new BehaviorSubject(false);
|
||||
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
|
||||
readonly #watermarkId = Number(getParam(WATERMARK_ID));
|
||||
readonly #config = getConfig<AppConfig>();
|
||||
#watermark: Partial<IWatermark> = {};
|
||||
readonly iconButtonTypes = IconButtonTypes;
|
||||
readonly translations = watermarkTranslations;
|
||||
readonly trackBy = trackByFactory();
|
||||
@ -86,6 +79,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<HTMLDivElement>;
|
||||
readonly #loaded$ = new BehaviorSubject(false);
|
||||
readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID);
|
||||
readonly #watermarkId = Number(getParam(WATERMARK_ID));
|
||||
readonly #config = getConfig<AppConfig>();
|
||||
#watermark: Partial<IWatermark> = {};
|
||||
readonly #convertPath = inject(UI_ROOT_PATH_FN);
|
||||
|
||||
constructor(
|
||||
private readonly _http: HttpClient,
|
||||
@ -222,8 +222,8 @@ export class WatermarkScreenComponent implements OnInit {
|
||||
this.instance = await WebViewer(
|
||||
{
|
||||
licenseKey: this._licenseService.activeLicenseKey,
|
||||
path: this._convertPath('/assets/wv-resources'),
|
||||
css: this._convertPath('/assets/pdftron/stylesheet.css'),
|
||||
path: this.#convertPath('/assets/wv-resources'),
|
||||
css: this.#convertPath('/assets/pdftron/stylesheet.css'),
|
||||
fullAPI: true,
|
||||
isReadOnly: true,
|
||||
backendType: 'ems',
|
||||
@ -242,7 +242,7 @@ export class WatermarkScreenComponent implements OnInit {
|
||||
});
|
||||
|
||||
if (environment.production) {
|
||||
this.instance.Core.setCustomFontURL('https://' + window.location.host + this._convertPath('/assets/pdftron'));
|
||||
this.instance.Core.setCustomFontURL('https://' + window.location.host + this.#convertPath('/assets/pdftron'));
|
||||
}
|
||||
|
||||
this.#disableElements();
|
||||
|
||||
@ -25,7 +25,6 @@ import { ColorPickerModule } from 'ngx-color-picker';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
import { IqserAuthGuard, IqserUsersModule } from '@iqser/common-ui/lib/users';
|
||||
import { TenantPipe } from '@iqser/common-ui/lib/tenants';
|
||||
|
||||
const routes: IqserRoutes = [
|
||||
{
|
||||
@ -72,7 +71,6 @@ const routes: IqserRoutes = [
|
||||
CircleButtonComponent,
|
||||
HasScrollbarDirective,
|
||||
IqserAllowDirective,
|
||||
TenantPipe,
|
||||
MatTooltipModule,
|
||||
],
|
||||
})
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
*allow="roles.watermarks.write; if: currentUser.isAdmin"
|
||||
[attr.help-mode-key]="'create_new_watermark'"
|
||||
[label]="'watermarks-listing.add-new' | translate"
|
||||
[routerLink]="getRouterLink() | tenant"
|
||||
[routerLink]="getRouterLink()"
|
||||
[type]="iconButtonTypes.primary"
|
||||
icon="iqser:plus"
|
||||
></iqser-icon-button>
|
||||
@ -44,13 +44,13 @@
|
||||
|
||||
<div class="cell">
|
||||
<div class="small-label">
|
||||
{{ entity.dateAdded | date : 'd MMM yyyy' }}
|
||||
{{ entity.dateAdded | date: 'd MMM yyyy' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<div class="small-label">
|
||||
{{ entity.dateModified | date : 'd MMM yyyy' }}
|
||||
{{ entity.dateModified | date: 'd MMM yyyy' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -58,7 +58,7 @@
|
||||
<div class="action-buttons">
|
||||
<div [attr.help-mode-key]="'edit_delete_watermark'">
|
||||
<iqser-circle-button
|
||||
[routerLink]="getRouterLink(entity) | tenant"
|
||||
[routerLink]="getRouterLink(entity)"
|
||||
[tooltip]="'watermarks-listing.action.edit' | translate"
|
||||
icon="iqser:edit"
|
||||
></iqser-circle-button>
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
<ng-container *ngFor="let item of items[type]">
|
||||
<a
|
||||
*ngIf="item.show"
|
||||
[attr.help-mode-key]="item.helpModeKey"
|
||||
[class.disabled]="isDisabled(item.screen)"
|
||||
[routerLinkActiveOptions]="{ exact: false }"
|
||||
[routerLink]="prefix + item.screen | tenant"
|
||||
[attr.help-mode-key]="item.helpModeKey"
|
||||
[routerLink]="prefix + item.screen"
|
||||
class="item"
|
||||
routerLinkActive="active"
|
||||
>
|
||||
|
||||
@ -4,7 +4,6 @@ import { ActivatedRoute, RouterLink, RouterLinkActive } from '@angular/router';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { getConfig, IqserHelpModeModule, IqserPermissionsService, isIqserDevMode } from '@iqser/common-ui';
|
||||
import { SideNavComponent } from '@iqser/common-ui/lib/shared';
|
||||
import { TenantPipe } from '@iqser/common-ui/lib/tenants';
|
||||
import { getCurrentUser } from '@iqser/common-ui/lib/users';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AdminSideNavType, AdminSideNavTypes, AppConfig, DOSSIER_TEMPLATE_ID, ENTITY_TYPE, User, WATERMARK_ID } from '@red/domain';
|
||||
@ -23,10 +22,9 @@ interface NavItem {
|
||||
templateUrl: './admin-side-nav.component.html',
|
||||
styleUrls: ['./admin-side-nav.component.scss'],
|
||||
standalone: true,
|
||||
imports: [TranslateModule, NgIf, IqserHelpModeModule, RouterLink, RouterLinkActive, NgForOf, SideNavComponent, TenantPipe],
|
||||
imports: [TranslateModule, NgIf, IqserHelpModeModule, RouterLink, RouterLinkActive, NgForOf, SideNavComponent],
|
||||
})
|
||||
export class AdminSideNavComponent implements OnInit {
|
||||
readonly #config = getConfig<AppConfig>();
|
||||
readonly isIqserDevMode = isIqserDevMode();
|
||||
@Input() type: AdminSideNavType;
|
||||
@Input() disabledItems: string[] = [];
|
||||
@ -34,6 +32,7 @@ export class AdminSideNavComponent implements OnInit {
|
||||
readonly currentUser = getCurrentUser<User>();
|
||||
readonly roles = Roles;
|
||||
prefix: string;
|
||||
readonly #config = getConfig<AppConfig>();
|
||||
readonly isDocumine = this.#config.IS_DOCUMINE;
|
||||
readonly canAccessRulesInDocumine = this.isDocumine && !this.#config.RULE_EDITOR_DEV_ONLY;
|
||||
readonly items: { readonly [key in AdminSideNavType]: NavItem[] } = {
|
||||
@ -102,7 +101,10 @@ export class AdminSideNavComponent implements OnInit {
|
||||
{
|
||||
screen: 'component-rules',
|
||||
label: _('admin-side-nav.component-rule-editor'),
|
||||
show: this.isDocumine && (this.isIqserDevMode || this.canAccessRulesInDocumine) && this._permissionsService.has(Roles.rules.read),
|
||||
show:
|
||||
this.isDocumine &&
|
||||
(this.isIqserDevMode || this.canAccessRulesInDocumine) &&
|
||||
this._permissionsService.has(Roles.rules.read),
|
||||
},
|
||||
{
|
||||
screen: 'default-colors',
|
||||
|
||||
@ -2,29 +2,25 @@
|
||||
<ng-container *ngIf="dossierTemplate$ | async as dossierTemplate">
|
||||
<a
|
||||
*ngIf="root || dossierTemplate"
|
||||
[routerLink]="'/main/admin/dossier-templates' | tenant"
|
||||
[routerLink]="'/main/admin/dossier-templates'"
|
||||
class="breadcrumb"
|
||||
translate="dossier-templates.label"
|
||||
></a>
|
||||
|
||||
<mat-icon svgIcon="iqser:arrow-right"></mat-icon>
|
||||
|
||||
<a
|
||||
[class.active]="(activeDictionary$ | async) === undefined"
|
||||
[routerLink]="dossierTemplate.routerLink | tenant"
|
||||
class="breadcrumb ml-0"
|
||||
>
|
||||
<a [class.active]="(activeDictionary$ | async) === undefined" [routerLink]="dossierTemplate.routerLink" class="breadcrumb ml-0">
|
||||
{{ dossierTemplate.name }}
|
||||
</a>
|
||||
|
||||
<ng-container *ngIf="activeDictionary$ | async as activeDictionary">
|
||||
<mat-icon svgIcon="iqser:arrow-right"></mat-icon>
|
||||
<a [routerLink]="dossierTemplate.routerLink + '/entities' | tenant" class="breadcrumb ml-0">
|
||||
<a [routerLink]="dossierTemplate.routerLink + '/entities'" class="breadcrumb ml-0">
|
||||
{{ 'admin-side-nav.entities' | translate }}
|
||||
</a>
|
||||
|
||||
<mat-icon svgIcon="iqser:arrow-right"></mat-icon>
|
||||
<a [routerLink]="activeDictionary.routerLink | tenant" class="breadcrumb ml-0" routerLinkActive="active">
|
||||
<a [routerLink]="activeDictionary.routerLink" class="breadcrumb ml-0" routerLinkActive="active">
|
||||
{{ activeDictionary.label }}
|
||||
</a>
|
||||
</ng-container>
|
||||
|
||||
@ -8,14 +8,13 @@ import { DictionariesMapService } from '@services/entity-services/dictionaries-m
|
||||
import { AsyncPipe, NgIf } from '@angular/common';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { TenantPipe } from '@iqser/common-ui/lib/tenants';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-dossier-template-breadcrumbs',
|
||||
templateUrl: './dossier-template-breadcrumbs.component.html',
|
||||
styleUrls: ['./dossier-template-breadcrumbs.component.scss'],
|
||||
standalone: true,
|
||||
imports: [NgIf, AsyncPipe, RouterLink, MatIconModule, TranslateModule, RouterLinkActive, TenantPipe],
|
||||
imports: [NgIf, AsyncPipe, RouterLink, MatIconModule, TranslateModule, RouterLinkActive],
|
||||
})
|
||||
export class DossierTemplateBreadcrumbsComponent {
|
||||
@Input() root = false;
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
<div
|
||||
(mousedown)="fileAttributesService.resetEdit()"
|
||||
[class.help-mode-active]="helpModeService?.isHelpModeActive$ | async"
|
||||
class="workflow-item"
|
||||
(mousedown)="fileAttributesService.resetEdit()"
|
||||
>
|
||||
<div class="details-wrapper">
|
||||
<div class="details">
|
||||
<div
|
||||
[attr.help-mode-key]="'workflow_view'"
|
||||
[matTooltip]="file.filename"
|
||||
[routerLink]="file.routerLink | tenant"
|
||||
[routerLink]="file.routerLink"
|
||||
class="filename pointer"
|
||||
matTooltipPosition="above"
|
||||
>
|
||||
|
||||
@ -28,7 +28,6 @@ import { FileAttributeComponent } from './components/file-attribute/file-attribu
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
|
||||
import { StatusBarComponent } from '@iqser/common-ui/lib/shared';
|
||||
import { TenantPipe } from '@iqser/common-ui/lib/tenants';
|
||||
|
||||
const routes: IqserRoutes = [
|
||||
{
|
||||
@ -69,7 +68,6 @@ const routes: IqserRoutes = [
|
||||
HasScrollbarDirective,
|
||||
DynamicInputComponent,
|
||||
IqserAllowDirective,
|
||||
TenantPipe,
|
||||
DisableStopPropagationDirective,
|
||||
FileAttributeComponent,
|
||||
],
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { Component, computed, Inject } from '@angular/core';
|
||||
import { BASE_HREF } from '@iqser/common-ui/lib/utils';
|
||||
import { Component, computed } from '@angular/core';
|
||||
import { ViewMode, ViewModes } from '@red/domain';
|
||||
import { Roles } from '@users/roles';
|
||||
import { FileDataService } from '../../services/file-data.service';
|
||||
@ -30,7 +29,6 @@ export class ViewSwitchComponent {
|
||||
});
|
||||
|
||||
constructor(
|
||||
@Inject(BASE_HREF) private readonly _baseHref: string,
|
||||
readonly viewModeService: ViewModeService,
|
||||
private readonly _state: FilePreviewStateService,
|
||||
private readonly _fileDataService: FileDataService,
|
||||
|
||||
@ -26,17 +26,17 @@
|
||||
<iqser-circle-button
|
||||
(action)="openComponentLogView()"
|
||||
*allow="roles.getRss"
|
||||
[attr.help-mode-key]="'editor_scm'"
|
||||
[tooltip]="'file-preview.open-rss-view' | translate"
|
||||
class="ml-8"
|
||||
icon="red:extract"
|
||||
tooltipPosition="below"
|
||||
[attr.help-mode-key]="'editor_scm'"
|
||||
></iqser-circle-button>
|
||||
|
||||
<redaction-file-actions
|
||||
[dossier]="state.dossier()"
|
||||
[helpModeKeyPrefix]="'editor'"
|
||||
[file]="file"
|
||||
[helpModeKeyPrefix]="'editor'"
|
||||
[minWidth]="width"
|
||||
type="file-preview"
|
||||
></redaction-file-actions>
|
||||
@ -51,10 +51,10 @@
|
||||
|
||||
<iqser-circle-button
|
||||
(action)="toggleFullScreen()"
|
||||
[attr.help-mode-key]="'editor_full_screen'"
|
||||
[icon]="fullScreen ? 'red:exit-fullscreen' : 'red:fullscreen'"
|
||||
[tooltip]="'file-preview.fullscreen' | translate"
|
||||
class="ml-2"
|
||||
[attr.help-mode-key]="'editor_full_screen'"
|
||||
></iqser-circle-button>
|
||||
|
||||
<!-- Dev Mode Features-->
|
||||
@ -71,11 +71,11 @@
|
||||
|
||||
<iqser-circle-button
|
||||
*ngIf="!fullScreen"
|
||||
[routerLink]="state.dossier().routerLink | tenant"
|
||||
[attr.help-mode-key]="'editor_close'"
|
||||
[routerLink]="state.dossier().routerLink"
|
||||
[tooltip]="'common.close' | translate"
|
||||
class="ml-8"
|
||||
icon="iqser:close"
|
||||
[attr.help-mode-key]="'editor_close'"
|
||||
></iqser-circle-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -26,7 +26,6 @@ import {
|
||||
} from '@iqser/common-ui';
|
||||
import { IqserFiltersModule } from '@iqser/common-ui/lib/filtering';
|
||||
import { StatusBarComponent } from '@iqser/common-ui/lib/shared';
|
||||
import { TenantPipe } from '@iqser/common-ui/lib/tenants';
|
||||
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { SharedModule } from '@shared/shared.module';
|
||||
@ -151,7 +150,6 @@ const components = [
|
||||
RoundCheckboxComponent,
|
||||
IqserAllowDirective,
|
||||
IqserDenyDirective,
|
||||
TenantPipe,
|
||||
LogPipe,
|
||||
ReplaceNbspPipe,
|
||||
],
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { inject, Injectable, NgZone } from '@angular/core';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { getConfig, IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
|
||||
import { AnnotationPermissions } from '@models/file/annotation.permissions';
|
||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
@ -17,7 +16,6 @@ export class PdfAnnotationActionsService {
|
||||
readonly #state = inject(FilePreviewStateService);
|
||||
readonly #translateService = inject(TranslateService);
|
||||
readonly #ngZone = inject(NgZone);
|
||||
readonly #convertPath = inject(BASE_HREF_FN);
|
||||
readonly #annotationActionsService = inject(AnnotationActionsService);
|
||||
readonly #iqserPermissionsService = inject(IqserPermissionsService);
|
||||
readonly #annotationManager = inject(REDAnnotationManager);
|
||||
@ -107,7 +105,7 @@ export class PdfAnnotationActionsService {
|
||||
#getButton(icon: string, title: string, action: () => void | Promise<void>): IHeaderElement {
|
||||
return {
|
||||
type: 'actionButton',
|
||||
img: this.#convertPath(`/assets/icons/general/${icon}.svg`),
|
||||
img: `ui/assets/icons/general/${icon}.svg`,
|
||||
title: this.#translateService.instant(title),
|
||||
onClick: () => this.#ngZone.run(async () => action()),
|
||||
};
|
||||
@ -121,7 +119,7 @@ export class PdfAnnotationActionsService {
|
||||
button.className = 'Button';
|
||||
button.style.setProperty('pointer-events', 'none');
|
||||
const img = document.createElement('img');
|
||||
img.src = this.#convertPath('/assets/icons/general/disabled-check.svg');
|
||||
img.src = 'ui/assets/icons/general/disabled-check.svg';
|
||||
button.appendChild(img);
|
||||
|
||||
return button;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { computed, effect, inject, Injectable, NgZone } from '@angular/core';
|
||||
import { getConfig, IqserPermissionsService } from '@iqser/common-ui';
|
||||
import { getCurrentUser } from '@iqser/common-ui/lib/users';
|
||||
import { BASE_HREF_FN, isJustOne, shareDistinctLast } from '@iqser/common-ui/lib/utils';
|
||||
import { isJustOne, shareDistinctLast, UI_ROOT_PATH_FN } from '@iqser/common-ui/lib/utils';
|
||||
import {
|
||||
ManualRedactionEntryType,
|
||||
ManualRedactionEntryTypes,
|
||||
@ -43,15 +43,6 @@ import Quad = Core.Math.Quad;
|
||||
|
||||
@Injectable()
|
||||
export class PdfProxyService {
|
||||
readonly #convertPath = inject(BASE_HREF_FN);
|
||||
readonly #visibilityOffIcon = this.#convertPath('/assets/icons/general/visibility-off.svg');
|
||||
readonly #visibilityIcon = this.#convertPath('/assets/icons/general/visibility.svg');
|
||||
readonly #falsePositiveIcon = this.#convertPath('/assets/icons/general/pdftron-action-false-positive.svg');
|
||||
readonly #addRedactionIcon = this._iqserPermissionsService.has(Roles.getRss)
|
||||
? this.#convertPath('/assets/icons/general/pdftron-action-add-annotation.svg')
|
||||
: this.#convertPath('/assets/icons/general/pdftron-action-add-redaction.svg');
|
||||
readonly #isDocumine = getConfig().IS_DOCUMINE;
|
||||
readonly #addHintIcon = this.#convertPath('/assets/icons/general/pdftron-action-add-hint.svg');
|
||||
readonly annotationSelected$ = this.#annotationSelected$;
|
||||
readonly manualAnnotationRequested$ = new Subject<ManualRedactionEntryWrapper>();
|
||||
readonly redactTextRequested$ = new Subject<ManualRedactionEntryWrapper>();
|
||||
@ -70,6 +61,15 @@ export class PdfProxyService {
|
||||
const isAllowed = this._permissionsService.canPerformAnnotationActions(this._state.file(), this._state.dossier());
|
||||
return isAllowed && isStandard;
|
||||
});
|
||||
readonly #convertPath = inject(UI_ROOT_PATH_FN);
|
||||
readonly #visibilityOffIcon = this.#convertPath('/assets/icons/general/visibility-off.svg');
|
||||
readonly #visibilityIcon = this.#convertPath('/assets/icons/general/visibility.svg');
|
||||
readonly #falsePositiveIcon = this.#convertPath('/assets/icons/general/pdftron-action-false-positive.svg');
|
||||
readonly #addRedactionIcon = this._iqserPermissionsService.has(Roles.getRss)
|
||||
? this.#convertPath('/assets/icons/general/pdftron-action-add-annotation.svg')
|
||||
: this.#convertPath('/assets/icons/general/pdftron-action-add-redaction.svg');
|
||||
readonly #isDocumine = getConfig().IS_DOCUMINE;
|
||||
readonly #addHintIcon = this.#convertPath('/assets/icons/general/pdftron-action-add-hint.svg');
|
||||
|
||||
constructor(
|
||||
private readonly _translateService: TranslateService,
|
||||
|
||||
@ -5,13 +5,13 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { PdfViewer } from './pdf-viewer.service';
|
||||
import { REDDocumentViewer } from './document-viewer.service';
|
||||
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
|
||||
import { UI_ROOT_PATH_FN } from '@common-ui/utils';
|
||||
|
||||
@Injectable()
|
||||
export class LayersService {
|
||||
private readonly _convertPath = inject(BASE_HREF_FN);
|
||||
readonly #enableIcon = this._convertPath('/assets/icons/general/pdftron-action-disable-layers.svg');
|
||||
readonly #disableIcon = this._convertPath('/assets/icons/general/pdftron-action-enable-layers.svg');
|
||||
readonly #convertPath = inject(UI_ROOT_PATH_FN);
|
||||
readonly #enableIcon = this.#convertPath('/assets/icons/general/pdftron-action-disable-layers.svg');
|
||||
readonly #disableIcon = this.#convertPath('/assets/icons/general/pdftron-action-enable-layers.svg');
|
||||
|
||||
private _active = false;
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import { ActivatedRoute } from '@angular/router';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { environment } from '@environments/environment';
|
||||
import { ErrorService, getConfig } from '@iqser/common-ui';
|
||||
import { BASE_HREF_FN, shareDistinctLast } from '@iqser/common-ui/lib/utils';
|
||||
import { shareDistinctLast, UI_ROOT_PATH_FN } from '@iqser/common-ui/lib/utils';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import WebViewer, { Core, WebViewerInstance, WebViewerOptions } from '@pdftron/webviewer';
|
||||
import { AppConfig, File, IHeaderElement } from '@red/domain';
|
||||
@ -16,17 +16,37 @@ import { map, startWith } from 'rxjs/operators';
|
||||
import { DISABLED_HOTKEYS, DOCUMENT_LOADING_ERROR, USELESS_ELEMENTS } from '../utils/constants';
|
||||
import { asList } from '../utils/functions';
|
||||
import { Rgb } from '../utils/types';
|
||||
import { REDAnnotationManager } from './annotation-manager.service';
|
||||
import Annotation = Core.Annotations.Annotation;
|
||||
import TextHighlightAnnotation = Core.Annotations.TextHighlightAnnotation;
|
||||
import DocumentViewer = Core.DocumentViewer;
|
||||
import Quad = Core.Math.Quad;
|
||||
import TextTool = Core.Tools.TextTool;
|
||||
import { REDAnnotationManager } from './annotation-manager.service';
|
||||
|
||||
@Injectable()
|
||||
export class PdfViewer {
|
||||
readonly #convertPath = inject(BASE_HREF_FN);
|
||||
readonly currentPage$ = inject(ActivatedRoute).queryParamMap.pipe(
|
||||
map(params => Number(params.get('page') ?? '1')),
|
||||
shareDistinctLast(),
|
||||
);
|
||||
readonly currentPage = toSignal(this.currentPage$);
|
||||
documentViewer: DocumentViewer;
|
||||
fileId: string;
|
||||
dossierId: string;
|
||||
pageChanged$: Observable<number>;
|
||||
readonly isCompareMode: Signal<boolean>;
|
||||
readonly totalPages: Signal<number>;
|
||||
searchOptions = {
|
||||
caseSensitive: false, // match case
|
||||
wholeWord: false, // match whole words only
|
||||
wildcard: false, // allow using '*' as a wildcard value
|
||||
regex: false, // string is treated as a regular expression
|
||||
searchUp: false, // search from the end of the document upwards
|
||||
ambientString: true, // return ambient string as part of the result
|
||||
};
|
||||
selectedText = '';
|
||||
#instance: WebViewerInstance;
|
||||
readonly #convertPath = inject(UI_ROOT_PATH_FN);
|
||||
readonly #licenseKey = inject(LicenseService).activeLicenseKey;
|
||||
readonly #config = getConfig<AppConfig>();
|
||||
readonly #isCompareMode = signal(false);
|
||||
@ -44,27 +64,6 @@ export class PdfViewer {
|
||||
};
|
||||
readonly #destroyRef = inject(DestroyRef);
|
||||
readonly #totalPages = signal<number>(0);
|
||||
readonly currentPage$ = inject(ActivatedRoute).queryParamMap.pipe(
|
||||
map(params => Number(params.get('page') ?? '1')),
|
||||
shareDistinctLast(),
|
||||
);
|
||||
readonly currentPage = toSignal(this.currentPage$);
|
||||
documentViewer: DocumentViewer;
|
||||
fileId: string;
|
||||
dossierId: string;
|
||||
pageChanged$: Observable<number>;
|
||||
readonly isCompareMode: Signal<boolean>;
|
||||
readonly totalPages: Signal<number>;
|
||||
|
||||
searchOptions = {
|
||||
caseSensitive: false, // match case
|
||||
wholeWord: false, // match whole words only
|
||||
wildcard: false, // allow using '*' as a wildcard value
|
||||
regex: false, // string is treated as a regular expression
|
||||
searchUp: false, // search from the end of the document upwards
|
||||
ambientString: true, // return ambient string as part of the result
|
||||
};
|
||||
selectedText = '';
|
||||
|
||||
constructor(
|
||||
private readonly _logger: NGXLogger,
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Core } from '@pdftron/webviewer';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { HeaderElements } from '../../file-preview/utils/constants';
|
||||
import { AnnotationDrawService } from './annotation-draw.service';
|
||||
import { PdfViewer } from './pdf-viewer.service';
|
||||
import { UI_ROOT_PATH_FN } from '@common-ui/utils';
|
||||
import Annotation = Core.Annotations.Annotation;
|
||||
|
||||
@Injectable()
|
||||
export class ReadableRedactionsService {
|
||||
private readonly _convertPath = inject(BASE_HREF_FN);
|
||||
readonly #enableIcon = this._convertPath('/assets/icons/general/redaction-preview.svg');
|
||||
readonly #disableIcon = this._convertPath('/assets/icons/general/redaction-final.svg');
|
||||
readonly #active$ = new BehaviorSubject<boolean>(true);
|
||||
readonly active$: Observable<boolean>;
|
||||
readonly #convertPath = inject(UI_ROOT_PATH_FN);
|
||||
readonly #enableIcon = this.#convertPath('/assets/icons/general/redaction-preview.svg');
|
||||
readonly #disableIcon = this.#convertPath('/assets/icons/general/redaction-final.svg');
|
||||
readonly #active$ = new BehaviorSubject<boolean>(true);
|
||||
|
||||
constructor(
|
||||
private readonly _pdf: PdfViewer,
|
||||
|
||||
@ -5,13 +5,13 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { PdfViewer } from './pdf-viewer.service';
|
||||
import { REDDocumentViewer } from './document-viewer.service';
|
||||
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
|
||||
import { UI_ROOT_PATH_FN } from '@common-ui/utils';
|
||||
|
||||
@Injectable()
|
||||
export class TooltipsService {
|
||||
private readonly _convertPath = inject(BASE_HREF_FN);
|
||||
readonly #enableIcon = this._convertPath('/assets/icons/general/pdftron-action-enable-tooltips.svg');
|
||||
readonly #disableIcon = this._convertPath('/assets/icons/general/pdftron-action-disable-tooltips.svg');
|
||||
readonly #convertPath = inject(UI_ROOT_PATH_FN);
|
||||
readonly #enableIcon = this.#convertPath('/assets/icons/general/pdftron-action-enable-tooltips.svg');
|
||||
readonly #disableIcon = this.#convertPath('/assets/icons/general/pdftron-action-disable-tooltips.svg');
|
||||
|
||||
constructor(
|
||||
private readonly _pdf: PdfViewer,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { inject, Injectable, NgZone } from '@angular/core';
|
||||
import { getConfig, HelpModeService, IqserPermissionsService, isIqserDevMode } from '@iqser/common-ui';
|
||||
import { BASE_HREF_FN } from '@iqser/common-ui/lib/utils';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { IHeaderElement, RotationTypes } from '@red/domain';
|
||||
import { FilesMapService } from '@services/files/files-map.service';
|
||||
@ -16,6 +15,7 @@ import { PageRotationService } from './page-rotation.service';
|
||||
import { PdfViewer } from './pdf-viewer.service';
|
||||
import { ReadableRedactionsService } from './readable-redactions.service';
|
||||
import { TooltipsService } from './tooltips.service';
|
||||
import { UI_ROOT_PATH_FN } from '@common-ui/utils';
|
||||
|
||||
const divider: IHeaderElement = {
|
||||
type: 'divider',
|
||||
@ -23,7 +23,9 @@ const divider: IHeaderElement = {
|
||||
|
||||
@Injectable()
|
||||
export class ViewerHeaderService {
|
||||
readonly #convertPath = inject(BASE_HREF_FN);
|
||||
readonly events$: Observable<ViewerEvent>;
|
||||
toggleLoadAnnotations$: Observable<boolean>;
|
||||
#convertPath = inject(UI_ROOT_PATH_FN);
|
||||
readonly #iqserPermissionService = inject(IqserPermissionsService);
|
||||
readonly #isDocumine = getConfig().IS_DOCUMINE;
|
||||
#buttons: Map<HeaderElementType, IHeaderElement>;
|
||||
@ -43,8 +45,6 @@ export class ViewerHeaderService {
|
||||
[HeaderElements.APPLY_ROTATION, false],
|
||||
[HeaderElements.DISCARD_ROTATION, false],
|
||||
]);
|
||||
readonly events$: Observable<ViewerEvent>;
|
||||
toggleLoadAnnotations$: Observable<boolean>;
|
||||
|
||||
constructor(
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
@ -329,6 +329,10 @@ export class ViewerHeaderService {
|
||||
this.enable([HeaderElements.COMPARE_BUTTON]);
|
||||
}
|
||||
|
||||
resetLayers() {
|
||||
this._layersService.resetLayers();
|
||||
}
|
||||
|
||||
#closeCompareMode() {
|
||||
this._pdf.closeCompareMode();
|
||||
const { dossierId, fileId } = this._pdf;
|
||||
@ -377,8 +381,4 @@ export class ViewerHeaderService {
|
||||
this.disable(ROTATION_ACTION_BUTTONS);
|
||||
}
|
||||
}
|
||||
|
||||
resetLayers() {
|
||||
this._layersService.resetLayers();
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
<div class="cell small-label full-opacity stats-subtitle">
|
||||
<div>
|
||||
<mat-icon *ngIf="item.archived" svgIcon="red:archive"></mat-icon>
|
||||
<a [routerLink]="routerLink | tenant" iqserStopPropagation> {{ item.dossierName }}</a>
|
||||
<a [routerLink]="routerLink" iqserStopPropagation> {{ item.dossierName }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { SearchItemTemplateComponent } from './search-item-template/search-item-template.component';
|
||||
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
|
||||
import { StatusBarComponent } from '@iqser/common-ui/lib/shared';
|
||||
import { TenantPipe } from '@iqser/common-ui/lib/tenants';
|
||||
|
||||
const routes = [{ path: '', component: SearchScreenComponent }];
|
||||
|
||||
@ -23,7 +22,6 @@ const routes = [{ path: '', component: SearchScreenComponent }];
|
||||
IqserListingModule,
|
||||
StatusBarComponent,
|
||||
StopPropagationDirective,
|
||||
TenantPipe,
|
||||
],
|
||||
})
|
||||
export class SearchModule {}
|
||||
|
||||
@ -20,11 +20,7 @@
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<a
|
||||
*ngIf="item.isFile && fileDossier$ | async as fileDossier"
|
||||
[routerLink]="fileDossier.routerLink | tenant"
|
||||
class="small-label link-action"
|
||||
>
|
||||
<a *ngIf="item.isFile && fileDossier$ | async as fileDossier" [routerLink]="fileDossier.routerLink" class="small-label link-action">
|
||||
{{ fileDossier.dossierName }}
|
||||
</a>
|
||||
|
||||
@ -33,13 +29,13 @@
|
||||
|
||||
<div class="cell">
|
||||
<span class="small-label">
|
||||
{{ item.softDeletedTime | date : 'exactDate' }}
|
||||
{{ item.softDeletedTime | date: 'exactDate' }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<div class="small-label">
|
||||
{{ item.restoreDate | date : 'timeFromNow' }}
|
||||
{{ item.restoreDate | date: 'timeFromNow' }}
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<iqser-circle-button
|
||||
|
||||
@ -8,7 +8,6 @@ import { SharedModule } from '@shared/shared.module';
|
||||
import { TrashDialogService } from './services/trash-dialog.service';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { IqserUsersModule } from '@iqser/common-ui/lib/users';
|
||||
import { TenantPipe } from '@iqser/common-ui/lib/tenants';
|
||||
|
||||
const routes = [{ path: '', component: TrashScreenComponent }];
|
||||
|
||||
@ -22,7 +21,6 @@ const routes = [{ path: '', component: TrashScreenComponent }];
|
||||
TranslateModule,
|
||||
IqserListingModule,
|
||||
CircleButtonComponent,
|
||||
TenantPipe,
|
||||
],
|
||||
providers: [TrashDialogService],
|
||||
})
|
||||
|
||||
@ -10,8 +10,9 @@ import { UserService } from '@users/user.service';
|
||||
import { CHANGED_CHECK_INTERVAL } from '@utils/constants';
|
||||
import { DossiersCacheService } from './dossiers/dossiers-cache.service';
|
||||
import dayjs from 'dayjs';
|
||||
import { BASE_HREF, List, mapEach } from '@iqser/common-ui/lib/utils';
|
||||
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;
|
||||
|
||||
@ -23,13 +24,13 @@ const NOTIFICATIONS_THRESHOLD = 1000;
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class NotificationsService extends EntitiesService<INotification, Notification> implements OnDestroy {
|
||||
readonly #config = getConfig<AppConfig>();
|
||||
readonly #subscription = new Subscription();
|
||||
protected readonly _defaultModelPath = 'notification';
|
||||
protected readonly _entityClass = Notification;
|
||||
readonly #config = getConfig<AppConfig>();
|
||||
readonly #subscription = new Subscription();
|
||||
|
||||
constructor(
|
||||
@Inject(BASE_HREF) private readonly _baseHref: string,
|
||||
@Inject(APP_BASE_HREF) private readonly _baseHref: string,
|
||||
private readonly _translateService: TranslateService,
|
||||
private readonly _tenantsService: TenantsService,
|
||||
private readonly _userService: UserService,
|
||||
@ -96,7 +97,7 @@ export class NotificationsService extends EntitiesService<INotification, Notific
|
||||
}
|
||||
|
||||
private _getDossierHref(dossier: Dossier): string {
|
||||
return dossier ? `${this._baseHref}/${this._tenantsService.activeTenantId}${dossier.routerLink}` : null;
|
||||
return dossier ? `${this._baseHref}/${dossier.routerLink}` : null;
|
||||
}
|
||||
|
||||
private _getUsername(userId: string | undefined) {
|
||||
|
||||
@ -18,7 +18,7 @@ export class RedRoleGuard extends IqserRoleGuard {
|
||||
|
||||
if (!currentUser?.hasAnyRole) {
|
||||
this._logger.warn('[GUARD] User has no roles, redirect to auth-error');
|
||||
await this._router.navigate([`/${this._tenantsService.activeTenantId}/auth-error`]);
|
||||
await this._router.navigate(['/auth-error']);
|
||||
this._loadingService.stop();
|
||||
return false;
|
||||
}
|
||||
@ -26,7 +26,7 @@ export class RedRoleGuard extends IqserRoleGuard {
|
||||
// we have at least 1 RED Role -> if it's not user he must be an admin
|
||||
if (currentUser.isUserAdmin && !currentUser.isAdmin && state.url.includes('admin') && !state.url.includes('users')) {
|
||||
this._logger.warn('[GUARD] Redirect to users page');
|
||||
await this._router.navigate([`/${this._tenantsService.activeTenantId}/main/admin/users`]);
|
||||
await this._router.navigate(['/main/admin/users']);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ export class RedRoleGuard extends IqserRoleGuard {
|
||||
!currentUser.isUser &&
|
||||
!(state.url.includes('/main/admin/users') || state.url.includes('/main/account'))
|
||||
) {
|
||||
await this._router.navigate([`/${this._tenantsService.activeTenantId}/main/admin/users`]);
|
||||
await this._router.navigate(['/main/admin/users']);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -45,10 +45,10 @@ export class RedRoleGuard extends IqserRoleGuard {
|
||||
return true;
|
||||
}
|
||||
if (!currentUser.isUser) {
|
||||
await this._router.navigate([`/${this._tenantsService.activeTenantId}/main/admin`]);
|
||||
await this._router.navigate(['/main/admin']);
|
||||
} else {
|
||||
this._logger.warn('[GUARD] Redirect to tenant route');
|
||||
await this._router.navigate([`/${this._tenantsService.activeTenantId}`]);
|
||||
await this._router.navigate(['']);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ import { inject } from '@angular/core';
|
||||
import { Router, RouterStateSnapshot } from '@angular/router';
|
||||
import { AsyncGuard, IqserPermissionsService, LoadingService } from '@iqser/common-ui';
|
||||
import { TenantsService } from '@iqser/common-ui/lib/tenants';
|
||||
import { BASE_HREF } from '@iqser/common-ui/lib/utils';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { DossiersChangesService } from '@services/dossiers/dossier-changes.service';
|
||||
import { FeaturesService } from '@services/features.service';
|
||||
@ -13,6 +12,7 @@ import { UserPreferenceService } from '@users/user-preference.service';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { APP_BASE_HREF } from '@angular/common';
|
||||
|
||||
async function redirectToLastDossierTemplate(
|
||||
router: Router,
|
||||
@ -45,7 +45,7 @@ export function mainGuard(): AsyncGuard {
|
||||
const tenantsService = inject(TenantsService);
|
||||
const loadingService = inject(LoadingService);
|
||||
const configService = inject(ConfigService);
|
||||
const baseHref = inject(BASE_HREF);
|
||||
const baseHref = inject(APP_BASE_HREF);
|
||||
|
||||
const generalConfig$ = inject(GeneralSettingsService).getGeneralConfigurations();
|
||||
const updatedDisplayName$ = generalConfig$.pipe(tap(config => configService.updateDisplayName(config.displayName)));
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"ADMIN_CONTACT_NAME": null,
|
||||
"ADMIN_CONTACT_URL": null,
|
||||
"API_URL": "https://dan1.iqser.cloud",
|
||||
"API_URL": "https://dan.iqser.cloud",
|
||||
"APP_NAME": "RedactManager",
|
||||
"IS_DOCUMINE": false,
|
||||
"RULE_EDITOR_DEV_ONLY": false,
|
||||
@ -13,7 +13,7 @@
|
||||
"MAX_RETRIES_ON_SERVER_ERROR": 3,
|
||||
"OAUTH_CLIENT_ID": "redaction",
|
||||
"OAUTH_IDP_HINT": null,
|
||||
"OAUTH_URL": "https://dan1.iqser.cloud/auth",
|
||||
"OAUTH_URL": "https://dan.iqser.cloud/auth",
|
||||
"RECENT_PERIOD_IN_HOURS": 24,
|
||||
"SELECTION_MODE": "structural",
|
||||
"MANUAL_BASE_URL": "https://docs.redactmanager.com/preview",
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 2bb459961af80944c5cd56bac8bff1fc786dbebc
|
||||
Subproject commit d1c0559099be64cb608b87afde6b4ee57de2604f
|
||||
Loading…
x
Reference in New Issue
Block a user