Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
cea0b23b86
@ -5,8 +5,8 @@ import { BaseScreenComponent } from '@components/base-screen/base-screen.compone
|
||||
import { RouteReuseStrategy, RouterModule } from '@angular/router';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { DownloadsListScreenComponent } from '@components/downloads-list-screen/downloads-list-screen.component';
|
||||
import { DossiersGuard } from '@guards/dossiers.guard';
|
||||
import { ACTIVE_DOSSIERS_SERVICE, ARCHIVED_DOSSIERS_SERVICE } from './tokens';
|
||||
import { loadActiveDossiersGuard, loadAllDossiersGuard, loadArchivedDossiersGuard } from '@guards/dossiers.guard';
|
||||
import { ACTIVE_DOSSIERS_SERVICE } from './tokens';
|
||||
import { FeaturesGuard } from '@guards/features-guard.service';
|
||||
import { DossierTemplatesGuard } from '@guards/dossier-templates.guard';
|
||||
import { templateExistsWhenEnteringDossierList } from '@guards/dossier-template-exists.guard';
|
||||
@ -14,7 +14,7 @@ import { DashboardGuard } from '@guards/dashboard-guard.service';
|
||||
import { TrashGuard } from '@guards/trash.guard';
|
||||
import { ARCHIVE_ROUTE, BreadcrumbTypes, DOSSIER_ID, DOSSIER_TEMPLATE_ID, DOSSIERS_ARCHIVE, DOSSIERS_ROUTE, FILE_ID } from '@red/domain';
|
||||
import { DossierFilesGuard } from '@guards/dossier-files-guard';
|
||||
import { WebViewerLoadedGuard } from './modules/pdf-viewer/services/webviewer-loaded.guard';
|
||||
import { webViewerLoadedGuard } from './modules/pdf-viewer/services/webviewer-loaded.guard';
|
||||
import { Roles } from '@users/roles';
|
||||
import { mainResolver } from '@utils/main.resolver';
|
||||
import { hasAnyRoleGuard, IqserAuthGuard } from '@iqser/common-ui/lib/users';
|
||||
@ -26,10 +26,8 @@ import { TenantSelectComponent } from '@iqser/common-ui/lib/tenants';
|
||||
const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
{
|
||||
path: `${DOSSIERS_ROUTE}`,
|
||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
|
||||
canActivate: [loadActiveDossiersGuard(), IqserPermissionsGuard],
|
||||
data: {
|
||||
routeGuards: [DossiersGuard],
|
||||
dossiersService: ACTIVE_DOSSIERS_SERVICE,
|
||||
permissions: {
|
||||
allow: [Roles.files.readStatus],
|
||||
redirectTo: '/auth-error',
|
||||
@ -53,9 +51,9 @@ const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
},
|
||||
{
|
||||
path: `:${DOSSIER_ID}/file/:${FILE_ID}`,
|
||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
|
||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard, webViewerLoadedGuard()],
|
||||
data: {
|
||||
routeGuards: [DossierFilesGuard, WebViewerLoadedGuard],
|
||||
routeGuards: [DossierFilesGuard],
|
||||
breadcrumbs: [BreadcrumbTypes.dossierTemplate, BreadcrumbTypes.dossier, BreadcrumbTypes.file],
|
||||
dossiersService: ACTIVE_DOSSIERS_SERVICE,
|
||||
permissions: {
|
||||
@ -78,10 +76,9 @@ const dossierTemplateIdRoutes: IqserRoutes = [
|
||||
{
|
||||
path: `${ARCHIVE_ROUTE}`,
|
||||
loadChildren: () => import('./modules/archive/archive.module').then(m => m.ArchiveModule),
|
||||
canActivate: [CompositeRouteGuard, WebViewerLoadedGuard],
|
||||
canActivate: [CompositeRouteGuard, webViewerLoadedGuard(), loadArchivedDossiersGuard()],
|
||||
data: {
|
||||
routeGuards: [FeaturesGuard, DossiersGuard],
|
||||
dossiersService: ARCHIVED_DOSSIERS_SERVICE,
|
||||
routeGuards: [FeaturesGuard],
|
||||
features: [DOSSIERS_ARCHIVE],
|
||||
},
|
||||
},
|
||||
@ -150,9 +147,9 @@ const mainRoutes: IqserRoutes = [
|
||||
{
|
||||
path: 'search',
|
||||
loadChildren: () => import('./modules/search/search.module').then(m => m.SearchModule),
|
||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
|
||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard, loadAllDossiersGuard()],
|
||||
data: {
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard, DossiersGuard],
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard],
|
||||
permissions: {
|
||||
allow: [Roles.search],
|
||||
redirectTo: '/auth-error',
|
||||
@ -162,10 +159,9 @@ const mainRoutes: IqserRoutes = [
|
||||
{
|
||||
path: 'trash',
|
||||
loadChildren: () => import('./modules/trash/trash.module').then(m => m.TrashModule),
|
||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard],
|
||||
canActivate: [CompositeRouteGuard, IqserPermissionsGuard, loadActiveDossiersGuard()],
|
||||
data: {
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard, DossiersGuard, TrashGuard],
|
||||
dossiersService: ACTIVE_DOSSIERS_SERVICE,
|
||||
routeGuards: [IqserAuthGuard, RedRoleGuard, TrashGuard],
|
||||
permissions: {
|
||||
allow: [Roles.dossiers.read, Roles.files.readStatus],
|
||||
redirectTo: '/auth-error',
|
||||
|
||||
@ -1,45 +1,57 @@
|
||||
import { Injectable, Injector, ProviderToken } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
|
||||
import { firstValueFrom, forkJoin } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { inject } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, CanActivateFn, Router } from '@angular/router';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { ActiveDossiersService } from '@services/dossiers/active-dossiers.service';
|
||||
import { ArchivedDossiersService } from '@services/dossiers/archived-dossiers.service';
|
||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||
import { ARCHIVE_ROUTE, DOSSIER_TEMPLATE_ID } from '@red/domain';
|
||||
import { DOSSIER_TEMPLATE_ID } from '@red/domain';
|
||||
import { DashboardStatsService } from '@services/dossier-templates/dashboard-stats.service';
|
||||
import { TenantsService } from '@iqser/common-ui/lib/tenants';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { ACTIVE_DOSSIERS_SERVICE, ARCHIVED_DOSSIERS_SERVICE } from '../tokens';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class DossiersGuard implements CanActivate {
|
||||
constructor(
|
||||
private readonly _injector: Injector,
|
||||
private readonly _router: Router,
|
||||
private readonly _tenantsService: TenantsService,
|
||||
private readonly _dashboardStatsService: DashboardStatsService,
|
||||
private readonly _activeDossiersService: ActiveDossiersService,
|
||||
private readonly _archivedDossiersService: ArchivedDossiersService,
|
||||
) {}
|
||||
export function loadAllDossiersGuard(): CanActivateFn {
|
||||
return async () => {
|
||||
const logger = inject(NGXLogger);
|
||||
logger.info('[GUARDS] loadAllDossiersGuard start');
|
||||
|
||||
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
|
||||
const token: ProviderToken<DossiersService> = route.data.dossiersService;
|
||||
if (!token) {
|
||||
const services = [this._archivedDossiersService, this._activeDossiersService];
|
||||
const loading$ = forkJoin(services.map(service => service.loadAll().pipe(take(1))));
|
||||
await firstValueFrom(loading$);
|
||||
return true;
|
||||
}
|
||||
const services = [inject(ArchivedDossiersService), inject(ActiveDossiersService)];
|
||||
const requests = services.map(service => firstValueFrom(service.loadAll()));
|
||||
await Promise.all(requests);
|
||||
|
||||
const dossiersService: DossiersService = this._injector.get<DossiersService>(token);
|
||||
const isArchive = dossiersService.routerPath === ARCHIVE_ROUTE;
|
||||
logger.info('[GUARDS] loadAllDossiersGuard end');
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
export function loadActiveDossiersGuard(): CanActivateFn {
|
||||
return async () => {
|
||||
const logger = inject(NGXLogger);
|
||||
logger.info('[GUARDS] loadDossiersGuard start');
|
||||
|
||||
await firstValueFrom(inject<ActiveDossiersService>(ACTIVE_DOSSIERS_SERVICE).loadAll());
|
||||
|
||||
logger.info('[GUARDS] loadDossiersGuard end');
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
export function loadArchivedDossiersGuard(): CanActivateFn {
|
||||
return async (route: ActivatedRouteSnapshot) => {
|
||||
const logger = inject(NGXLogger);
|
||||
logger.info('[GUARDS] loadArchivedDossiersGuard start');
|
||||
|
||||
const dossiersService = inject<ArchivedDossiersService>(ARCHIVED_DOSSIERS_SERVICE);
|
||||
const dossierTemplateId = route.paramMap.get(DOSSIER_TEMPLATE_ID);
|
||||
const dossierTemplateStats = this._dashboardStatsService.find(dossierTemplateId);
|
||||
const dossierTemplateStats = inject(DashboardStatsService).find(dossierTemplateId);
|
||||
|
||||
if (isArchive && dossierTemplateStats?.numberOfArchivedDossiers === 0) {
|
||||
await this._router.navigate([this._tenantsService.activeTenantId, 'main', dossierTemplateId, 'dossiers']);
|
||||
if (dossierTemplateStats?.numberOfArchivedDossiers === 0) {
|
||||
logger.info('[GUARDS] loadArchivedDossiersGuard no archived dossiers, redirect to active dossiers page');
|
||||
await inject(Router).navigate([inject(TenantsService).activeTenantId, 'main', dossierTemplateId, 'dossiers']);
|
||||
return false;
|
||||
}
|
||||
|
||||
await firstValueFrom(dossiersService.loadAll());
|
||||
logger.info('[GUARDS] loadArchivedDossiersGuard end');
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import { LicenseService } from '@services/license.service';
|
||||
export function ifLoggedIn(): CanActivateFn {
|
||||
return async (route: ActivatedRouteSnapshot) => {
|
||||
const logger = inject(NGXLogger);
|
||||
logger.info('[ROUTES] Check if can activate main');
|
||||
logger.info('[ROUTES] Check if can activate route', route);
|
||||
|
||||
const tenantsService = inject(TenantsService);
|
||||
const keycloakService = inject(KeycloakService);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<div class="content-container">
|
||||
<div #viewer class="viewer" id="viewer"></div>
|
||||
<div #viewer class="viewer"></div>
|
||||
|
||||
<redaction-paginator (changePage)="navigateTo($event)" *ngIf="loaded$ | async"></redaction-paginator>
|
||||
|
||||
@ -54,30 +54,30 @@
|
||||
<div class="iqser-input-group">
|
||||
<label [translate]="'watermark-screen.form.alignment'" class="all-caps-label mb-8"></label>
|
||||
<div class="flex">
|
||||
<div class="alignment-buttons" [class.disabled]="form.controls.horizontalTextAlignment.disabled">
|
||||
<div [class.disabled]="form.controls.horizontalTextAlignment.disabled" class="alignment-buttons">
|
||||
<div
|
||||
(click)="alignHorizontally(alignment)"
|
||||
*ngFor="let alignment of watermarkHorizontalAlignments"
|
||||
[class.active]="currentAlignment.horizontal === alignment"
|
||||
[class.disabled]="form.controls.horizontalTextAlignment.disabled"
|
||||
[matTooltipPosition]="'above'"
|
||||
[matTooltip]="translations.HORIZONTAL[alignment] | translate"
|
||||
[ngClass]="'horizontal-' + alignment.toLowerCase()"
|
||||
[class.disabled]="form.controls.horizontalTextAlignment.disabled"
|
||||
class="alignment"
|
||||
(click)="alignHorizontally(alignment)"
|
||||
>
|
||||
<mat-icon [svgIcon]="'red:align-horizontal-' + alignment.toLowerCase()"></mat-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alignment-buttons" [class.disabled]="form.controls.verticalTextAlignment.disabled">
|
||||
<div [class.disabled]="form.controls.verticalTextAlignment.disabled" class="alignment-buttons">
|
||||
<div
|
||||
(click)="alignVertically(alignment)"
|
||||
*ngFor="let alignment of watermarkVerticalAlignments"
|
||||
[class.active]="currentAlignment.vertical === alignment"
|
||||
[class.disabled]="form.controls.verticalTextAlignment.disabled"
|
||||
[matTooltipPosition]="'above'"
|
||||
[matTooltip]="translations.VERTICAL[alignment] | translate"
|
||||
[ngClass]="'vertical-' + alignment.toLowerCase()"
|
||||
[class.disabled]="form.controls.verticalTextAlignment.disabled"
|
||||
class="alignment"
|
||||
(click)="alignVertically(alignment)"
|
||||
>
|
||||
<mat-icon [svgIcon]="'red:align-vertical-' + alignment.toLowerCase()"></mat-icon>
|
||||
</div>
|
||||
|
||||
@ -11,7 +11,7 @@ import {
|
||||
TemplateRef,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { ActivatedRoute, ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
|
||||
import { ActivatedRouteSnapshot, NavigationExtras, Router } from '@angular/router';
|
||||
import {
|
||||
CircleButtonTypes,
|
||||
ConfirmOption,
|
||||
@ -20,6 +20,7 @@ import {
|
||||
ErrorService,
|
||||
HelpModeService,
|
||||
IConfirmationDialogData,
|
||||
IqserDialog,
|
||||
LoadingService,
|
||||
Toaster,
|
||||
} from '@iqser/common-ui';
|
||||
@ -63,7 +64,6 @@ import { ConfigService } from '@services/config.service';
|
||||
import { ReadableRedactionsService } from '../pdf-viewer/services/readable-redactions.service';
|
||||
import { Roles } from '@users/roles';
|
||||
import { SuggestionsService } from './services/suggestions.service';
|
||||
import { IqserDialog } from '../../../../../../libs/common-ui/src/lib/dialog/iqser-dialog.service';
|
||||
import { RedactTextDialogComponent } from './dialogs/redact-text-dialog/redact-text-dialog.component';
|
||||
import { DossierTemplatesService } from '@services/dossier-templates/dossier-templates.service';
|
||||
import { copyLocalStorageFiltersValues, FilterService, NestedFilter, processFilters } from '@iqser/common-ui/lib/filtering';
|
||||
@ -108,7 +108,6 @@ export class FilePreviewScreenComponent
|
||||
private readonly _annotationManager: REDAnnotationManager,
|
||||
private readonly _errorService: ErrorService,
|
||||
private readonly _filterService: FilterService,
|
||||
private readonly _activatedRoute: ActivatedRoute,
|
||||
private readonly _loadingService: LoadingService,
|
||||
private readonly _filesMapService: FilesMapService,
|
||||
private readonly _dossiersService: DossiersService,
|
||||
@ -161,6 +160,7 @@ export class FilePreviewScreenComponent
|
||||
|
||||
effect(() => {
|
||||
const selectedText = this._documentViewer.selectedText();
|
||||
console.log('selectedText', selectedText);
|
||||
const canPerformActions = this.pdfProxyService.canPerformActions();
|
||||
const isCurrentPageExcluded = this.state.file().isPageExcluded(this.pdf.currentPage());
|
||||
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
<div id="viewer"></div>
|
||||
|
||||
<redaction-compare-file-input></redaction-compare-file-input>
|
||||
|
||||
<redaction-paginator></redaction-paginator>
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
:host {
|
||||
--workload-width: 350px;
|
||||
--header-height: calc(var(--iqser-top-bar-height) + 50px);
|
||||
}
|
||||
|
||||
div {
|
||||
width: calc(100% - var(--workload-width));
|
||||
height: calc(100% - var(--header-height));
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
}
|
||||
@ -11,7 +11,6 @@ import { PaginatorComponent } from './components/paginator/paginator.component';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { AnnotationDrawService } from './services/annotation-draw.service';
|
||||
import { REDDocumentViewer } from './services/document-viewer.service';
|
||||
import { WebViewerLoadedGuard } from './services/webviewer-loaded.guard';
|
||||
import { ReadableRedactionsService } from './services/readable-redactions.service';
|
||||
|
||||
@NgModule({
|
||||
@ -27,7 +26,6 @@ import { ReadableRedactionsService } from './services/readable-redactions.servic
|
||||
ReadableRedactionsService,
|
||||
ViewerHeaderService,
|
||||
AnnotationDrawService,
|
||||
WebViewerLoadedGuard,
|
||||
],
|
||||
})
|
||||
export class PdfViewerModule {}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { inject, Injectable, NgZone, Signal, signal } from '@angular/core';
|
||||
import { effect, inject, Injectable, Signal, signal } from '@angular/core';
|
||||
import { Core } from '@pdftron/webviewer';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { fromEvent, Observable } from 'rxjs';
|
||||
@ -25,7 +25,6 @@ export class REDDocumentViewer {
|
||||
readonly #userPreferenceService = inject(UserPreferenceService);
|
||||
readonly #pdf = inject(PdfViewer);
|
||||
readonly #activatedRoute = inject(ActivatedRoute);
|
||||
readonly #ngZone = inject(NgZone);
|
||||
readonly loaded$: Observable<boolean>;
|
||||
keyUp$: Observable<KeyboardEvent>;
|
||||
readonly selectedText: Signal<string>;
|
||||
@ -37,6 +36,21 @@ export class REDDocumentViewer {
|
||||
this.loaded$ = toObservable(this.#loaded);
|
||||
this.pageComplete = this.#pageComplete.asReadonly();
|
||||
this.selectedText = this.#selectedText.asReadonly();
|
||||
|
||||
effect(() => {
|
||||
const viewerElement = document.getElementById('viewer');
|
||||
if (!viewerElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.loaded()) {
|
||||
this.#logger.info('[PDF] Show viewer');
|
||||
viewerElement.style.visibility = 'visible';
|
||||
} else {
|
||||
this.#logger.info('[PDF] Hide viewer');
|
||||
viewerElement.style.visibility = 'hidden';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get PDFDoc() {
|
||||
|
||||
@ -1,41 +1,42 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CanActivate, Router } from '@angular/router';
|
||||
import { inject } from '@angular/core';
|
||||
import { CanActivateFn, ResolveFn, Router } from '@angular/router';
|
||||
import { REDDocumentViewer } from './document-viewer.service';
|
||||
import { PdfViewer } from './pdf-viewer.service';
|
||||
import { REDAnnotationManager } from './annotation-manager.service';
|
||||
import { ViewerHeaderService } from './viewer-header.service';
|
||||
import { LoadingService } from '@iqser/common-ui';
|
||||
import { WebViewerInstance } from '@pdftron/webviewer';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
|
||||
@Injectable()
|
||||
export class WebViewerLoadedGuard implements CanActivate {
|
||||
constructor(
|
||||
private readonly _documentViewer: REDDocumentViewer,
|
||||
private readonly _pdf: PdfViewer,
|
||||
private readonly _router: Router,
|
||||
private readonly _annotationManager: REDAnnotationManager,
|
||||
private readonly _viewerHeaderService: ViewerHeaderService,
|
||||
private readonly _loadingService: LoadingService,
|
||||
) {}
|
||||
export function webViewerLoadedGuard(): CanActivateFn | ResolveFn<boolean> {
|
||||
return async (_, state) => {
|
||||
const pdf = inject(PdfViewer);
|
||||
const logger = inject(NGXLogger);
|
||||
|
||||
async canActivate(_, state) {
|
||||
if (this._pdf.instance) {
|
||||
if (pdf.instance) {
|
||||
logger.info('[PDF] WebViewerGuard already loaded.');
|
||||
return true;
|
||||
}
|
||||
|
||||
this._loadingService.start();
|
||||
inject(LoadingService).start();
|
||||
const router = inject(Router);
|
||||
const annotationManager = inject(REDAnnotationManager);
|
||||
const documentViewer = inject(REDDocumentViewer);
|
||||
const viewerHeaderService = inject(ViewerHeaderService);
|
||||
|
||||
let instance: WebViewerInstance | undefined;
|
||||
try {
|
||||
instance = await this._pdf.init(document.getElementById('viewer'));
|
||||
} catch {
|
||||
return this._router.navigateByUrl(state.url);
|
||||
instance = await pdf.init(inject(DOCUMENT).getElementById('viewer'));
|
||||
} catch (e) {
|
||||
logger.warn('[PDF] WebViewerGuard error: ', e, 'redirecting to', state.url);
|
||||
return router.navigateByUrl(state.url);
|
||||
}
|
||||
|
||||
this._annotationManager.init(instance.Core.annotationManager);
|
||||
this._documentViewer.init(instance.Core.documentViewer);
|
||||
this._viewerHeaderService.init();
|
||||
annotationManager.init(instance.Core.annotationManager);
|
||||
documentViewer.init(instance.Core.documentViewer);
|
||||
viewerHeaderService.init();
|
||||
|
||||
return !!this._pdf.instance;
|
||||
}
|
||||
return !!pdf.instance;
|
||||
};
|
||||
}
|
||||
|
||||
@ -144,15 +144,11 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
|
||||
this._dialogService.openDialog('confirm', data, async () => {
|
||||
this._loadingService.start();
|
||||
await firstValueFrom(this._trashService.deleteDossier(this.dossier));
|
||||
this._editDossierDialogRef.close();
|
||||
await this._router.navigate([`/${this._tenantsService.activeTenantId}${this.dossier.dossiersListRouterLink}`]);
|
||||
const successful = await this._trashService.deleteDossier(this.dossier);
|
||||
if (successful) {
|
||||
await this.#closeDialogAndRedirectToDossier();
|
||||
}
|
||||
this._loadingService.stop();
|
||||
this._toaster.success(_('edit-dossier-dialog.delete-successful'), {
|
||||
params: {
|
||||
dossierName: this.dossier.dossierName,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -193,6 +189,16 @@ export class EditDossierGeneralInfoComponent implements OnInit, EditDossierSecti
|
||||
return this._dossierStatesMapService.get(this.dossier.dossierTemplateId, stateId).color;
|
||||
}
|
||||
|
||||
async #closeDialogAndRedirectToDossier() {
|
||||
this._editDossierDialogRef.close();
|
||||
await this._router.navigate([`/${this._tenantsService.activeTenantId}${this.dossier.dossiersListRouterLink}`]);
|
||||
this._toaster.success(_('edit-dossier-dialog.delete-successful'), {
|
||||
params: {
|
||||
dossierName: this.dossier.dossierName,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
#getForm(): UntypedFormGroup {
|
||||
const formFieldWithArchivedCheck = value => ({ value, disabled: !this.dossier.isActive });
|
||||
return this._formBuilder.group({
|
||||
|
||||
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
import { EntitiesService, QueryParam, Toaster } from '@iqser/common-ui';
|
||||
import { Dossier, File, IDossier, IFile, TrashDossier, TrashFile, TrashItem } from '@red/domain';
|
||||
import { catchError, switchMap, take, tap } from 'rxjs/operators';
|
||||
import { forkJoin, map, Observable, of } from 'rxjs';
|
||||
import { firstValueFrom, forkJoin, map, Observable, of } from 'rxjs';
|
||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||
import { PermissionsService } from '../permissions.service';
|
||||
import { ActiveDossiersService } from '../dossiers/active-dossiers.service';
|
||||
@ -31,18 +31,20 @@ export class TrashService extends EntitiesService<TrashItem, TrashItem> {
|
||||
super();
|
||||
}
|
||||
|
||||
deleteDossier(dossier: Dossier): Observable<unknown> {
|
||||
deleteDossier(dossier: Dossier) {
|
||||
const showToast = () => {
|
||||
this._toaster.error(_('dossier-listing.delete.delete-failed'), { params: { dossierName: dossier.dossierName } });
|
||||
return of({});
|
||||
return of(undefined);
|
||||
};
|
||||
|
||||
const reloadDossiers$ = dossier.isActive ? this._activeDossiersService.loadAll() : this._archivedDossiersService.loadAll();
|
||||
|
||||
return this.delete(dossier.id, 'dossier').pipe(
|
||||
const request$ = this.delete(dossier.id, 'dossier').pipe(
|
||||
switchMap(() => reloadDossiers$),
|
||||
catchError(showToast),
|
||||
);
|
||||
|
||||
return firstValueFrom(request$);
|
||||
}
|
||||
|
||||
restore(items: TrashItem[]): Observable<unknown> {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { GenericService } from '@iqser/common-ui';
|
||||
import { ILicense, ILicenseReport, ILicenseReportRequest, ILicenses } from '@red/domain';
|
||||
import { BehaviorSubject, firstValueFrom, Observable, of } from 'rxjs';
|
||||
@ -39,6 +39,10 @@ const defaultOnError: ILicenses = {
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class LicenseService extends GenericService<ILicenseReport> {
|
||||
readonly #licenseData$ = new BehaviorSubject<ILicenses | undefined>(undefined);
|
||||
readonly #selectedLicense$ = new BehaviorSubject<ILicense | undefined>(undefined);
|
||||
readonly #logger = inject(NGXLogger);
|
||||
protected readonly _defaultModelPath = 'report';
|
||||
readonly licenseData$: Observable<ILicenses>;
|
||||
readonly selectedLicense$: Observable<ILicense>;
|
||||
activeLicenseId: string;
|
||||
@ -48,9 +52,19 @@ export class LicenseService extends GenericService<ILicenseReport> {
|
||||
unlicensedPages = 0;
|
||||
analyzedPagesInCurrentLicensingPeriod = 0;
|
||||
uploadedBytesCapacity = 0;
|
||||
protected readonly _defaultModelPath = 'report';
|
||||
readonly #licenseData$ = new BehaviorSubject<ILicenses | undefined>(undefined);
|
||||
readonly #selectedLicense$ = new BehaviorSubject<ILicense | undefined>(undefined);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.selectedLicense$ = this.#selectedLicense$.pipe(filter(license => !!license));
|
||||
this.licenseData$ = this.#licenseData$.pipe(
|
||||
filter(licenses => !!licenses),
|
||||
tap(data => (this.activeLicenseId = data.activeLicense)),
|
||||
tap(() => {
|
||||
const uploadedBytesCapacity = this.activeLicense.features.find(f => f.name === 'uploadedBytesCapacity')?.value;
|
||||
this.uploadedBytesCapacity = uploadedBytesCapacity ? parseInt(uploadedBytesCapacity, 10) : 0;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
get selectedLicense() {
|
||||
return this.#selectedLicense$.value;
|
||||
@ -66,20 +80,13 @@ export class LicenseService extends GenericService<ILicenseReport> {
|
||||
}
|
||||
|
||||
get activeLicenseKey(): string {
|
||||
return this.activeLicense.features.find(f => f.name === 'pdftron').value;
|
||||
}
|
||||
const activeLicense = this.activeLicense;
|
||||
if (!activeLicense) {
|
||||
this.#logger.error('[LICENSE] No active license found!');
|
||||
return '';
|
||||
}
|
||||
|
||||
constructor(private readonly _logger: NGXLogger) {
|
||||
super();
|
||||
this.selectedLicense$ = this.#selectedLicense$.pipe(filter(license => !!license));
|
||||
this.licenseData$ = this.#licenseData$.pipe(
|
||||
filter(licenses => !!licenses),
|
||||
tap(data => (this.activeLicenseId = data.activeLicense)),
|
||||
tap(() => {
|
||||
const uploadedBytesCapacity = this.activeLicense.features.find(f => f.name === 'uploadedBytesCapacity')?.value;
|
||||
this.uploadedBytesCapacity = uploadedBytesCapacity ? parseInt(uploadedBytesCapacity, 10) : 0;
|
||||
}),
|
||||
);
|
||||
return activeLicense.features.find(f => f.name === 'pdftron').value;
|
||||
}
|
||||
|
||||
async loadLicenseData(license: ILicense = this.selectedLicense) {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"ADMIN_CONTACT_NAME": null,
|
||||
"ADMIN_CONTACT_URL": null,
|
||||
"API_URL": "https://dev-02.iqser.cloud",
|
||||
"API_URL": "https://dev-04.iqser.cloud",
|
||||
"APP_NAME": "RedactManager",
|
||||
"AUTO_READ_TIME": 3,
|
||||
"BACKEND_APP_VERSION": "4.4.40",
|
||||
@ -11,7 +11,7 @@
|
||||
"MAX_RETRIES_ON_SERVER_ERROR": 3,
|
||||
"OAUTH_CLIENT_ID": "redaction",
|
||||
"OAUTH_IDP_HINT": null,
|
||||
"OAUTH_URL": "https://dev-02.iqser.cloud/auth",
|
||||
"OAUTH_URL": "https://dev-04.iqser.cloud/auth",
|
||||
"RECENT_PERIOD_IN_HOURS": 24,
|
||||
"SELECTION_MODE": "structural",
|
||||
"MANUAL_BASE_URL": "https://docs.redactmanager.com/preview",
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<redaction-root></redaction-root>
|
||||
<div id="viewer"></div>
|
||||
<noscript>Please enable JavaScript to continue using this application.</noscript>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -143,3 +143,11 @@ $dark-accent-10: darken(vars.$accent, 10%);
|
||||
$iqser-app-name-font-size: 13px,
|
||||
$iqser-app-name-color: vars.$white
|
||||
);
|
||||
|
||||
#viewer {
|
||||
width: calc(100% - 350px);
|
||||
height: calc(100% - calc(var(--iqser-top-bar-height) + 50px));
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit f631395f613e6cbeaf71826dac4dc8446be33520
|
||||
Subproject commit da18c68a861a8d343dd3f63298e825543714f743
|
||||
Loading…
x
Reference in New Issue
Block a user