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