RED-4634, RED-3800: Refactor watermarks
This commit is contained in:
parent
a1940aaa45
commit
02b0d96012
@ -1,37 +0,0 @@
|
|||||||
<div class="container" *ngIf="watermarks$ | async as watermarks">
|
|
||||||
<div class="iqser-input-group watermark">
|
|
||||||
<mat-checkbox color="primary" [checked]="!!watermarkId" (change)="toggleWatermarkSelection($event.checked, documentTypes.REDACTED)">
|
|
||||||
{{ 'dossier-watermark-selector.watermark' | translate }}
|
|
||||||
</mat-checkbox>
|
|
||||||
<mat-select *ngIf="!!watermarkId" [(value)]="watermarkId" (selectionChange)="emitNewValues()">
|
|
||||||
<mat-select-trigger>
|
|
||||||
<mat-icon svgIcon="red:warning" *ngIf="!selectedWatermark(watermarkId, watermarks).enabled"></mat-icon>
|
|
||||||
<span> {{ selectedWatermark(watermarkId, watermarks).name }} </span>
|
|
||||||
</mat-select-trigger>
|
|
||||||
<mat-option *ngFor="let watermark of watermarks" [value]="watermark.id" [disabled]="!watermark.enabled">
|
|
||||||
<mat-icon svgIcon="red:warning" *ngIf="!watermark.enabled"></mat-icon>
|
|
||||||
{{ watermark.name }}
|
|
||||||
</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="iqser-input-group watermark">
|
|
||||||
<mat-checkbox
|
|
||||||
color="primary"
|
|
||||||
[checked]="!!previewWatermarkId"
|
|
||||||
(change)="toggleWatermarkSelection($event.checked, documentTypes.PREVIEW)"
|
|
||||||
>
|
|
||||||
{{ 'dossier-watermark-selector.preview' | translate }}
|
|
||||||
</mat-checkbox>
|
|
||||||
<mat-select *ngIf="!!previewWatermarkId" [(value)]="previewWatermarkId" (selectionChange)="emitNewValues()">
|
|
||||||
<mat-select-trigger>
|
|
||||||
<mat-icon svgIcon="red:warning" *ngIf="!selectedWatermark(previewWatermarkId, watermarks).enabled"></mat-icon>
|
|
||||||
<span> {{ selectedWatermark(previewWatermarkId, watermarks).name }} </span>
|
|
||||||
</mat-select-trigger>
|
|
||||||
<mat-option *ngFor="let watermark of watermarks" [value]="watermark.id">
|
|
||||||
<mat-icon svgIcon="red:warning" *ngIf="!watermark.enabled"></mat-icon>
|
|
||||||
{{ watermark.name }}
|
|
||||||
</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { IWatermark } from '@red/domain';
|
|
||||||
import { WatermarkService } from '@services/entity-services/watermark.service';
|
|
||||||
import { mapEach, Required } from '@iqser/common-ui';
|
|
||||||
import { OptionWatermark } from '@components/dossier-watermark-selector/option-watermark.model';
|
|
||||||
import { map, tap } from 'rxjs/operators';
|
|
||||||
|
|
||||||
const DocumentTypes = {
|
|
||||||
REDACTED: 'REDACTED',
|
|
||||||
PREVIEW: 'PREVIEW',
|
|
||||||
} as const;
|
|
||||||
type DocumentType = keyof typeof DocumentTypes;
|
|
||||||
|
|
||||||
export interface UpdateWatermarkIdsEvent {
|
|
||||||
watermarkId: string | null;
|
|
||||||
previewWatermarkId: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'redaction-dossier-watermark-selector',
|
|
||||||
templateUrl: './dossier-watermark-selector.component.html',
|
|
||||||
styleUrls: ['./dossier-watermark-selector.component.scss'],
|
|
||||||
})
|
|
||||||
export class DossierWatermarkSelectorComponent implements OnInit {
|
|
||||||
@Input() @Required() dossierTemplateId!: string;
|
|
||||||
@Input() watermarkId: string | null;
|
|
||||||
@Input() previewWatermarkId: string | null;
|
|
||||||
@Output() readonly idsUpdate = new EventEmitter<UpdateWatermarkIdsEvent>();
|
|
||||||
watermarks$: Observable<OptionWatermark[]>;
|
|
||||||
readonly documentTypes = DocumentTypes;
|
|
||||||
#oldWatermarkId: string | null;
|
|
||||||
#oldPreviewWatermarkId: string | null;
|
|
||||||
|
|
||||||
constructor(private readonly _watermarkService: WatermarkService) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.watermarks$ = this._watermarkService.getWatermarks(this.dossierTemplateId).pipe(
|
|
||||||
map((watermarks: IWatermark[]) => watermarks.sort(this.sortByStatusFn)),
|
|
||||||
mapEach((watermark: IWatermark) => new OptionWatermark(watermark)),
|
|
||||||
tap((watermarks: OptionWatermark[]) => (this.#oldWatermarkId = watermarks[0].id)),
|
|
||||||
tap((watermarks: OptionWatermark[]) => (this.#oldPreviewWatermarkId = watermarks[0].id)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
sortByStatusFn = (a, b) => {
|
|
||||||
if (a.enabled === b.enabled) {
|
|
||||||
return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
|
|
||||||
}
|
|
||||||
return a.enabled ? -1 : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
toggleWatermarkSelection(checked: boolean, documentType: DocumentType): void {
|
|
||||||
if (checked) {
|
|
||||||
if (documentType === DocumentTypes.REDACTED) {
|
|
||||||
this.watermarkId = this.#oldWatermarkId;
|
|
||||||
} else {
|
|
||||||
this.previewWatermarkId = this.#oldPreviewWatermarkId;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (documentType === DocumentTypes.REDACTED) {
|
|
||||||
this.#oldWatermarkId = this.watermarkId;
|
|
||||||
this.watermarkId = null;
|
|
||||||
} else {
|
|
||||||
this.#oldPreviewWatermarkId = this.previewWatermarkId;
|
|
||||||
this.previewWatermarkId = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.emitNewValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
emitNewValues(): void {
|
|
||||||
this.idsUpdate.emit({
|
|
||||||
watermarkId: this.watermarkId,
|
|
||||||
previewWatermarkId: this.previewWatermarkId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedWatermark(id: string, watermarks: OptionWatermark[]): OptionWatermark {
|
|
||||||
return watermarks.find(watermark => watermark.id === id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import { IWatermark } from '@red/domain';
|
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
|
||||||
|
|
||||||
export class OptionWatermark {
|
|
||||||
id!: string;
|
|
||||||
name!: string;
|
|
||||||
enabled!: boolean;
|
|
||||||
|
|
||||||
constructor(watermark: IWatermark) {
|
|
||||||
this.id = watermark.id;
|
|
||||||
this.name = watermark.enabled ? watermark.name : `${_('disabled')} - ${watermark.name}`;
|
|
||||||
this.enabled = watermark.enabled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
21
apps/red-ui/src/app/guards/watermark-exists.guard.ts
Normal file
21
apps/red-ui/src/app/guards/watermark-exists.guard.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';
|
||||||
|
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
|
||||||
|
import { DOSSIER_TEMPLATE_ID, WATERMARK_ID } from '@red/domain';
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class WatermarkExistsGuard implements CanActivate {
|
||||||
|
constructor(private readonly _watermarksMapService: WatermarksMapService, private readonly _router: Router) {}
|
||||||
|
|
||||||
|
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean> {
|
||||||
|
const dossierTemplateId = route.parent.paramMap.get(DOSSIER_TEMPLATE_ID);
|
||||||
|
const watermarkId = route.paramMap.get(WATERMARK_ID);
|
||||||
|
|
||||||
|
if (this._watermarksMapService.get(dossierTemplateId, watermarkId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this._router.navigate(['main', 'admin', 'dossier-templates', dossierTemplateId, 'watermarks']);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,14 +15,12 @@ import { GeneralConfigScreenComponent } from './screens/general-config/general-c
|
|||||||
import { BaseAdminScreenComponent } from './base-admin-screen/base-admin-screen.component';
|
import { BaseAdminScreenComponent } from './base-admin-screen/base-admin-screen.component';
|
||||||
import { BaseDossierTemplateScreenComponent } from './base-dossier-templates-screen/base-dossier-template-screen.component';
|
import { BaseDossierTemplateScreenComponent } from './base-dossier-templates-screen/base-dossier-template-screen.component';
|
||||||
import { DossierTemplatesGuard } from '@guards/dossier-templates.guard';
|
import { DossierTemplatesGuard } from '@guards/dossier-templates.guard';
|
||||||
import { DOSSIER_TEMPLATE_ID, ENTITY_TYPE, WATERMARK_ID } from '@red/domain';
|
import { DOSSIER_TEMPLATE_ID, ENTITY_TYPE } from '@red/domain';
|
||||||
import { DossierTemplateExistsGuard } from '@guards/dossier-template-exists.guard';
|
import { DossierTemplateExistsGuard } from '@guards/dossier-template-exists.guard';
|
||||||
import { EntityExistsGuard } from '@guards/entity-exists-guard.service';
|
import { EntityExistsGuard } from '@guards/entity-exists-guard.service';
|
||||||
import { DossierStatesListingScreenComponent } from './screens/dossier-states-listing/dossier-states-listing-screen.component';
|
import { DossierStatesListingScreenComponent } from './screens/dossier-states-listing/dossier-states-listing-screen.component';
|
||||||
import { BaseEntityScreenComponent } from './base-entity-screen/base-entity-screen.component';
|
import { BaseEntityScreenComponent } from './base-entity-screen/base-entity-screen.component';
|
||||||
import { PermissionsGuard } from '../../guards/permissions-guard';
|
import { PermissionsGuard } from '@guards/permissions-guard';
|
||||||
import { WatermarksListingScreenComponent } from './screens/watermarks-listing/watermarks-listing-screen.component';
|
|
||||||
import { BaseWatermarkScreenComponent } from './base-watermark-screen/base-watermark-screen.component';
|
|
||||||
|
|
||||||
const dossierTemplateIdRoutes: Routes = [
|
const dossierTemplateIdRoutes: Routes = [
|
||||||
{
|
{
|
||||||
@ -72,34 +70,8 @@ const dossierTemplateIdRoutes: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'watermarks',
|
path: 'watermarks',
|
||||||
children: [
|
component: BaseDossierTemplateScreenComponent,
|
||||||
{
|
loadChildren: () => import('./screens/watermark/watermark.module').then(m => m.WatermarkModule),
|
||||||
path: '',
|
|
||||||
component: WatermarksListingScreenComponent,
|
|
||||||
canActivate: [CompositeRouteGuard],
|
|
||||||
data: {
|
|
||||||
routeGuards: [AuthGuard, RedRoleGuard],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
component: BaseWatermarkScreenComponent,
|
|
||||||
canActivate: [CompositeRouteGuard],
|
|
||||||
loadChildren: () => import('./screens/watermark/watermark.module').then(m => m.WatermarkModule),
|
|
||||||
data: {
|
|
||||||
routeGuards: [AuthGuard, RedRoleGuard],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: `:${WATERMARK_ID}`,
|
|
||||||
component: BaseWatermarkScreenComponent,
|
|
||||||
canActivate: [CompositeRouteGuard],
|
|
||||||
loadChildren: () => import('./screens/watermark/watermark.module').then(m => m.WatermarkModule),
|
|
||||||
data: {
|
|
||||||
routeGuards: [AuthGuard, RedRoleGuard],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'reports',
|
path: 'reports',
|
||||||
|
|||||||
@ -45,8 +45,6 @@ import { SystemPreferencesFormComponent } from './screens/general-config/system-
|
|||||||
import { ConfigureCertificateDialogComponent } from './dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component';
|
import { ConfigureCertificateDialogComponent } from './dialogs/configure-digital-signature-dialog/configure-certificate-dialog.component';
|
||||||
import { PkcsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component';
|
import { PkcsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/form/pkcs-signature-configuration/pkcs-signature-configuration.component';
|
||||||
import { KmsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component';
|
import { KmsSignatureConfigurationComponent } from './dialogs/configure-digital-signature-dialog/form/kms-signature-configuration/kms-signature-configuration.component';
|
||||||
import { WatermarksListingScreenComponent } from './screens/watermarks-listing/watermarks-listing-screen.component';
|
|
||||||
import { BaseWatermarkScreenComponent } from './base-watermark-screen/base-watermark-screen.component';
|
|
||||||
|
|
||||||
const dialogs = [
|
const dialogs = [
|
||||||
AddEditCloneDossierTemplateDialogComponent,
|
AddEditCloneDossierTemplateDialogComponent,
|
||||||
@ -74,7 +72,6 @@ const screens = [
|
|||||||
GeneralConfigScreenComponent,
|
GeneralConfigScreenComponent,
|
||||||
DossierAttributesListingScreenComponent,
|
DossierAttributesListingScreenComponent,
|
||||||
DossierStatesListingScreenComponent,
|
DossierStatesListingScreenComponent,
|
||||||
WatermarksListingScreenComponent,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const components = [
|
const components = [
|
||||||
@ -87,7 +84,6 @@ const components = [
|
|||||||
BaseAdminScreenComponent,
|
BaseAdminScreenComponent,
|
||||||
BaseDossierTemplateScreenComponent,
|
BaseDossierTemplateScreenComponent,
|
||||||
BaseEntityScreenComponent,
|
BaseEntityScreenComponent,
|
||||||
BaseWatermarkScreenComponent,
|
|
||||||
GeneralConfigFormComponent,
|
GeneralConfigFormComponent,
|
||||||
SmtpFormComponent,
|
SmtpFormComponent,
|
||||||
SystemPreferencesFormComponent,
|
SystemPreferencesFormComponent,
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
<section>
|
|
||||||
<div class="page-header">
|
|
||||||
<redaction-dossier-template-breadcrumbs class="flex-1"></redaction-dossier-template-breadcrumbs>
|
|
||||||
|
|
||||||
<div class="flex-1 actions">
|
|
||||||
<iqser-circle-button
|
|
||||||
*ngIf="editMode"
|
|
||||||
(action)="openDeleteWatermarkDialog($event)"
|
|
||||||
[tooltip]="'watermarks-listing.action.delete' | translate"
|
|
||||||
icon="iqser:trash"
|
|
||||||
></iqser-circle-button>
|
|
||||||
|
|
||||||
<iqser-circle-button
|
|
||||||
[routerLink]="['../../watermarks']"
|
|
||||||
[tooltip]="'common.close' | translate"
|
|
||||||
icon="iqser:close"
|
|
||||||
tooltipPosition="below"
|
|
||||||
></iqser-circle-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content-inner">
|
|
||||||
<div class="overlay-shadow"></div>
|
|
||||||
|
|
||||||
<router-outlet></router-outlet>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
||||||
import { firstValueFrom } from 'rxjs';
|
|
||||||
import { AdminDialogService } from '../services/admin-dialog.service';
|
|
||||||
import { ConfirmationDialogInput, getParam, LoadingService, Toaster } from '@iqser/common-ui';
|
|
||||||
import { WatermarkService } from '../../../services/entity-services/watermark.service';
|
|
||||||
import { DOSSIER_TEMPLATE_ID, WATERMARK_ID } from '@red/domain';
|
|
||||||
import { Router } from '@angular/router';
|
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
templateUrl: './base-watermark-screen.component.html',
|
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
||||||
})
|
|
||||||
export class BaseWatermarkScreenComponent {
|
|
||||||
readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID);
|
|
||||||
readonly #watermarkId: string = getParam(WATERMARK_ID);
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private readonly _dialogService: AdminDialogService,
|
|
||||||
private readonly _loadingService: LoadingService,
|
|
||||||
private readonly _watermarkService: WatermarkService,
|
|
||||||
private readonly _toaster: Toaster,
|
|
||||||
private readonly _router: Router,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
get editMode(): boolean {
|
|
||||||
return !!Number(this.#watermarkId);
|
|
||||||
}
|
|
||||||
|
|
||||||
async openDeleteWatermarkDialog($event: MouseEvent): Promise<void> {
|
|
||||||
const isUsed = await firstValueFrom(this._watermarkService.isWatermarkUsed(this.#watermarkId));
|
|
||||||
|
|
||||||
if (!isUsed) {
|
|
||||||
await this._deleteWatermark(this.#watermarkId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = new ConfirmationDialogInput({
|
|
||||||
question: _('watermarks-listing.watermark-is-used'),
|
|
||||||
});
|
|
||||||
this._dialogService.openDialog('confirm', $event, data, async () => {
|
|
||||||
await this._deleteWatermark(this.#watermarkId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _deleteWatermark(watermarkId: string): Promise<void> {
|
|
||||||
this._loadingService.start();
|
|
||||||
await firstValueFrom(this._watermarkService.deleteWatermark(watermarkId));
|
|
||||||
this._toaster.success(_('watermarks-listing.action.delete-success'));
|
|
||||||
await this._router.navigate([`/main/admin/dossier-templates/${this.#dossierTemplateId}/watermarks`]);
|
|
||||||
this._loadingService.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="right-container" iqserHasScrollbar>
|
<div *ngIf="watermark$ | async" class="right-container" iqserHasScrollbar>
|
||||||
<form (keyup)="configChanged()" [formGroup]="form">
|
<form (keyup)="configChanged()" [formGroup]="form">
|
||||||
<div class="iqser-input-group required w-300">
|
<div class="iqser-input-group required w-300">
|
||||||
<label translate="watermark-screen.form.name-label"></label>
|
<label translate="watermark-screen.form.name-label"></label>
|
||||||
|
|||||||
@ -1,34 +1,29 @@
|
|||||||
import { ChangeDetectorRef, Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
|
import { ChangeDetectorRef, Component, ElementRef, Inject, ViewChild } from '@angular/core';
|
||||||
import { PermissionsService } from '@services/permissions.service';
|
import { PermissionsService } from '@services/permissions.service';
|
||||||
import WebViewer, { WebViewerInstance } from '@pdftron/webviewer';
|
import WebViewer, { WebViewerInstance } from '@pdftron/webviewer';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||||
import { Debounce, getParam, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
import { Debounce, getParam, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
|
||||||
import { DOSSIER_TEMPLATE_ID, IWatermark, WATERMARK_ID, WatermarkOrientation, WatermarkOrientations } from '@red/domain';
|
import { DOSSIER_TEMPLATE_ID, IWatermark, Watermark, WATERMARK_ID, WatermarkOrientation, WatermarkOrientations } from '@red/domain';
|
||||||
import { BASE_HREF_FN, BaseHrefFn } from '../../../../../tokens';
|
import { BASE_HREF_FN, BaseHrefFn } from '../../../../../tokens';
|
||||||
import { stampPDFPage } from '@utils/page-stamper';
|
import { stampPDFPage } from '@utils/page-stamper';
|
||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { WatermarkService } from '@services/entity-services/watermark.service';
|
import { WatermarkService } from '@services/entity-services/watermark.service';
|
||||||
import { firstValueFrom, Observable, of } from 'rxjs';
|
import { firstValueFrom, Observable, of } from 'rxjs';
|
||||||
import { catchError, tap } from 'rxjs/operators';
|
import { tap } from 'rxjs/operators';
|
||||||
import { LicenseService } from '@services/license.service';
|
import { LicenseService } from '@services/license.service';
|
||||||
import { UserPreferenceService } from '@services/user-preference.service';
|
import { UserPreferenceService } from '@services/user-preference.service';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
|
||||||
|
|
||||||
export const DEFAULT_WATERMARK: IWatermark = {
|
export const DEFAULT_WATERMARK: Partial<IWatermark> = {
|
||||||
id: null,
|
|
||||||
dossierTemplateId: null,
|
|
||||||
text: 'Watermark',
|
text: 'Watermark',
|
||||||
name: '',
|
name: '',
|
||||||
enabled: true,
|
|
||||||
hexColor: '#000000',
|
hexColor: '#000000',
|
||||||
opacity: 30,
|
opacity: 30,
|
||||||
fontSize: 40,
|
fontSize: 40,
|
||||||
fontType: 'sans-serif',
|
fontType: 'helvetica',
|
||||||
orientation: WatermarkOrientations.HORIZONTAL,
|
orientation: WatermarkOrientations.HORIZONTAL,
|
||||||
createdBy: null,
|
|
||||||
dateAdded: null,
|
|
||||||
dateModified: null,
|
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -36,13 +31,14 @@ export const DEFAULT_WATERMARK: IWatermark = {
|
|||||||
templateUrl: './watermark-screen.component.html',
|
templateUrl: './watermark-screen.component.html',
|
||||||
styleUrls: ['./watermark-screen.component.scss'],
|
styleUrls: ['./watermark-screen.component.scss'],
|
||||||
})
|
})
|
||||||
export class WatermarkScreenComponent implements OnInit {
|
export class WatermarkScreenComponent {
|
||||||
readonly iconButtonTypes = IconButtonTypes;
|
readonly iconButtonTypes = IconButtonTypes;
|
||||||
readonly form: UntypedFormGroup = this._getForm();
|
readonly form: UntypedFormGroup = this._getForm();
|
||||||
|
readonly watermark$: Observable<Partial<IWatermark>>;
|
||||||
readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID);
|
readonly #dossierTemplateId: string = getParam(DOSSIER_TEMPLATE_ID);
|
||||||
readonly #watermarkId = getParam(WATERMARK_ID);
|
readonly #watermarkId = getParam(WATERMARK_ID);
|
||||||
private _instance: WebViewerInstance;
|
private _instance: WebViewerInstance;
|
||||||
private _watermark: IWatermark = {} as IWatermark;
|
private _watermark: Partial<IWatermark> = {};
|
||||||
@ViewChild('viewer', { static: true })
|
@ViewChild('viewer', { static: true })
|
||||||
private _viewer: ElementRef;
|
private _viewer: ElementRef;
|
||||||
|
|
||||||
@ -58,12 +54,16 @@ export class WatermarkScreenComponent implements OnInit {
|
|||||||
private readonly _changeDetectorRef: ChangeDetectorRef,
|
private readonly _changeDetectorRef: ChangeDetectorRef,
|
||||||
private readonly _userPreferenceService: UserPreferenceService,
|
private readonly _userPreferenceService: UserPreferenceService,
|
||||||
private readonly _router: Router,
|
private readonly _router: Router,
|
||||||
|
private readonly _watermarksMapService: WatermarksMapService,
|
||||||
) {
|
) {
|
||||||
this._loadingService.start();
|
const obs$: Observable<Partial<IWatermark>> = this.#watermarkId
|
||||||
|
? _watermarksMapService.watch$(this.#dossierTemplateId, this.#watermarkId)
|
||||||
|
: of(DEFAULT_WATERMARK);
|
||||||
|
this.watermark$ = obs$.pipe(tap(wm => this._initForm(wm)));
|
||||||
}
|
}
|
||||||
|
|
||||||
get changed(): boolean {
|
get changed(): boolean {
|
||||||
for (const key of Object.keys(this._watermark)) {
|
for (const key of Object.keys(this.form.getRawValue())) {
|
||||||
if (this._watermark[key] !== this.form.get(key)?.value) {
|
if (this._watermark[key] !== this.form.get(key)?.value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -78,22 +78,19 @@ export class WatermarkScreenComponent implements OnInit {
|
|||||||
return this.form.valid;
|
return this.form.valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
|
||||||
if (!this.#watermarkId) {
|
|
||||||
this._initForm(DEFAULT_WATERMARK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await firstValueFrom(this._loadWatermark());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Debounce()
|
@Debounce()
|
||||||
async configChanged() {
|
async configChanged() {
|
||||||
await this._drawWatermark();
|
await this._drawWatermark();
|
||||||
}
|
}
|
||||||
|
|
||||||
async save(): Promise<void> {
|
async save(): Promise<void> {
|
||||||
const watermark: IWatermark = this.form.getRawValue();
|
const watermark: IWatermark = {
|
||||||
|
id: this._watermark.id,
|
||||||
|
enabled: this._watermark.id ? this._watermark.enabled : true,
|
||||||
|
dossierTemplateId: this.#dossierTemplateId,
|
||||||
|
...this.form.getRawValue(),
|
||||||
|
};
|
||||||
|
this._loadingService.start();
|
||||||
try {
|
try {
|
||||||
await firstValueFrom(
|
await firstValueFrom(
|
||||||
this._watermarkService.saveWatermark(watermark).pipe(
|
this._watermarkService.saveWatermark(watermark).pipe(
|
||||||
@ -102,11 +99,11 @@ export class WatermarkScreenComponent implements OnInit {
|
|||||||
watermark.id ? _('watermark-screen.action.change-success') : _('watermark-screen.action.created-success'),
|
watermark.id ? _('watermark-screen.action.change-success') : _('watermark-screen.action.created-success'),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
tap(async () => {
|
tap(async updatedWatermark => {
|
||||||
if (!watermark.id) {
|
if (!watermark.id) {
|
||||||
await this._router.navigate([`/main/admin/dossier-templates/${this.#dossierTemplateId}/watermarks`]);
|
await this._router.navigate([
|
||||||
} else {
|
`/main/admin/dossier-templates/${this.#dossierTemplateId}/watermarks/${updatedWatermark.id}`,
|
||||||
await firstValueFrom(this._loadWatermark());
|
]);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
@ -114,10 +111,11 @@ export class WatermarkScreenComponent implements OnInit {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
this._toaster.error(_('watermark-screen.action.error'));
|
this._toaster.error(_('watermark-screen.action.error'));
|
||||||
}
|
}
|
||||||
|
this._loadingService.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
async revert() {
|
async revert() {
|
||||||
this.form.setValue({ ...this._watermark });
|
this.form.patchValue({ ...this._watermark });
|
||||||
await this.configChanged();
|
await this.configChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,17 +126,9 @@ export class WatermarkScreenComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _loadWatermark(): Observable<IWatermark> {
|
private _initForm(watermark: Partial<IWatermark>) {
|
||||||
return this._watermarkService.getWatermark(this.#watermarkId).pipe(
|
this._watermark = { ...watermark, dossierTemplateId: this.#dossierTemplateId };
|
||||||
catchError(() => of(DEFAULT_WATERMARK)),
|
this.form.patchValue({ ...watermark });
|
||||||
tap(watermark => this._initForm(watermark)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _initForm(watermark: IWatermark) {
|
|
||||||
this._watermark = watermark;
|
|
||||||
this._watermark.dossierTemplateId = this.#dossierTemplateId;
|
|
||||||
this.form.setValue({ ...watermark });
|
|
||||||
this._loadViewer();
|
this._loadViewer();
|
||||||
this._changeDetectorRef.markForCheck();
|
this._changeDetectorRef.markForCheck();
|
||||||
}
|
}
|
||||||
@ -211,26 +201,20 @@ export class WatermarkScreenComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _getForm(): UntypedFormGroup {
|
private _getForm(): UntypedFormGroup {
|
||||||
const defaultValue = {
|
const form = this._formBuilder.group({
|
||||||
value: null,
|
name: [null],
|
||||||
disabled: !this.permissionsService.isAdmin(),
|
text: [null],
|
||||||
};
|
hexColor: [null],
|
||||||
const defaultFormControl = [{ ...defaultValue }, Validators.required];
|
opacity: [null],
|
||||||
|
fontSize: [null],
|
||||||
return this._formBuilder.group({
|
fontType: [null],
|
||||||
id: [{ ...defaultValue }],
|
orientation: [null],
|
||||||
name: [{ ...defaultFormControl }],
|
|
||||||
enabled: [{ ...defaultValue }],
|
|
||||||
dossierTemplateId: [{ ...defaultValue }],
|
|
||||||
text: [{ ...defaultFormControl }],
|
|
||||||
hexColor: [...defaultFormControl],
|
|
||||||
opacity: [...defaultFormControl],
|
|
||||||
fontSize: [...defaultFormControl],
|
|
||||||
fontType: [...defaultFormControl],
|
|
||||||
orientation: [...defaultFormControl],
|
|
||||||
createdBy: [{ ...defaultValue }],
|
|
||||||
dateAdded: [{ ...defaultValue }],
|
|
||||||
dateModified: [{ ...defaultValue }],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!this.permissionsService.isAdmin()) {
|
||||||
|
form.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
return form;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,11 +3,42 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { SharedModule } from '@shared/shared.module';
|
import { SharedModule } from '@shared/shared.module';
|
||||||
import { WatermarkScreenComponent } from './watermark-screen/watermark-screen.component';
|
import { WatermarkScreenComponent } from './watermark-screen/watermark-screen.component';
|
||||||
|
import { WatermarksListingScreenComponent } from './watermarks-listing/watermarks-listing-screen.component';
|
||||||
|
import { CompositeRouteGuard } from '@iqser/common-ui';
|
||||||
|
import { AuthGuard } from '../../../auth/auth.guard';
|
||||||
|
import { RedRoleGuard } from '../../../auth/red-role.guard';
|
||||||
|
import { WATERMARK_ID } from '@red/domain';
|
||||||
|
import { WatermarkExistsGuard } from '@guards/watermark-exists.guard';
|
||||||
|
|
||||||
const routes = [{ path: '', component: WatermarkScreenComponent }];
|
const routes = [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: WatermarksListingScreenComponent,
|
||||||
|
canActivate: [CompositeRouteGuard],
|
||||||
|
data: {
|
||||||
|
routeGuards: [AuthGuard, RedRoleGuard],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'create',
|
||||||
|
component: WatermarkScreenComponent,
|
||||||
|
canActivate: [CompositeRouteGuard],
|
||||||
|
data: {
|
||||||
|
routeGuards: [AuthGuard, RedRoleGuard],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: `:${WATERMARK_ID}`,
|
||||||
|
component: WatermarkScreenComponent,
|
||||||
|
canActivate: [CompositeRouteGuard],
|
||||||
|
data: {
|
||||||
|
routeGuards: [AuthGuard, RedRoleGuard, WatermarkExistsGuard],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [WatermarkScreenComponent],
|
declarations: [WatermarkScreenComponent, WatermarksListingScreenComponent],
|
||||||
imports: [RouterModule.forChild(routes), CommonModule, SharedModule],
|
imports: [RouterModule.forChild(routes), CommonModule, SharedModule],
|
||||||
})
|
})
|
||||||
export class WatermarkModule {}
|
export class WatermarkModule {}
|
||||||
|
|||||||
@ -0,0 +1,71 @@
|
|||||||
|
<div class="content-container">
|
||||||
|
<iqser-table
|
||||||
|
[headerTemplate]="headerTemplate"
|
||||||
|
[itemSize]="80"
|
||||||
|
[noDataText]="'watermarks-listing.no-data.title' | translate"
|
||||||
|
[tableColumnConfigs]="tableColumnConfigs"
|
||||||
|
emptyColumnWidth="1fr"
|
||||||
|
noDataIcon="red:attribute"
|
||||||
|
></iqser-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ng-template #headerTemplate>
|
||||||
|
<div class="table-header-actions">
|
||||||
|
<iqser-icon-button
|
||||||
|
*ngIf="currentUser.isAdmin"
|
||||||
|
[label]="'watermarks-listing.add-new' | translate"
|
||||||
|
[routerLink]="getRouterLink()"
|
||||||
|
[type]="iconButtonTypes.primary"
|
||||||
|
icon="iqser:plus"
|
||||||
|
></iqser-icon-button>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template #tableItemTemplate let-entity="entity">
|
||||||
|
<div>
|
||||||
|
<div class="label cell">
|
||||||
|
<span>{{ entity.name }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="center cell">
|
||||||
|
<mat-slide-toggle (toggleChange)="toggleStatus(entity)" [checked]="entity.enabled" color="primary"></mat-slide-toggle>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell user-column">
|
||||||
|
<redaction-initials-avatar
|
||||||
|
[defaultValue]="'unknown' | translate"
|
||||||
|
[user]="entity.createdBy || 'system'"
|
||||||
|
></redaction-initials-avatar>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell">
|
||||||
|
<div class="small-label">
|
||||||
|
{{ entity.dateAdded | date: 'd MMM yyyy' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell">
|
||||||
|
<div class="small-label">
|
||||||
|
{{ entity.dateModified | date: 'd MMM yyyy' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cell">
|
||||||
|
<div class="action-buttons">
|
||||||
|
<iqser-circle-button
|
||||||
|
[routerLink]="getRouterLink(entity)"
|
||||||
|
[tooltip]="'watermarks-listing.action.edit' | translate"
|
||||||
|
[type]="circleButtonTypes.dark"
|
||||||
|
icon="iqser:edit"
|
||||||
|
></iqser-circle-button>
|
||||||
|
|
||||||
|
<iqser-circle-button
|
||||||
|
(action)="openConfirmDeleteWatermarkDialog($event, entity)"
|
||||||
|
[tooltip]="'watermarks-listing.action.delete' | translate"
|
||||||
|
[type]="circleButtonTypes.dark"
|
||||||
|
icon="iqser:trash"
|
||||||
|
></iqser-circle-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
CircleButtonTypes,
|
CircleButtonTypes,
|
||||||
ConfirmationDialogInput,
|
ConfirmationDialogInput,
|
||||||
@ -15,14 +15,15 @@ import { getCurrentUser } from '@services/user.service';
|
|||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { firstValueFrom } from 'rxjs';
|
import { firstValueFrom } from 'rxjs';
|
||||||
import { WatermarkService } from '@services/entity-services/watermark.service';
|
import { WatermarkService } from '@services/entity-services/watermark.service';
|
||||||
import { AdminDialogService } from '../../services/admin-dialog.service';
|
import { AdminDialogService } from '../../../services/admin-dialog.service';
|
||||||
|
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: './watermarks-listing-screen.component.html',
|
templateUrl: './watermarks-listing-screen.component.html',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
providers: listingProvidersFactory(WatermarksListingScreenComponent),
|
providers: listingProvidersFactory(WatermarksListingScreenComponent),
|
||||||
})
|
})
|
||||||
export class WatermarksListingScreenComponent extends ListingComponent<Watermark> implements OnInit {
|
export class WatermarksListingScreenComponent extends ListingComponent<Watermark> {
|
||||||
readonly iconButtonTypes = IconButtonTypes;
|
readonly iconButtonTypes = IconButtonTypes;
|
||||||
readonly circleButtonTypes = CircleButtonTypes;
|
readonly circleButtonTypes = CircleButtonTypes;
|
||||||
readonly currentUser = getCurrentUser();
|
readonly currentUser = getCurrentUser();
|
||||||
@ -39,36 +40,29 @@ export class WatermarksListingScreenComponent extends ListingComponent<Watermark
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly _loadingService: LoadingService,
|
private readonly _loadingService: LoadingService,
|
||||||
private readonly _watermarkService: WatermarkService,
|
private readonly _watermarkService: WatermarkService,
|
||||||
|
private readonly _watermarksMapService: WatermarksMapService,
|
||||||
private readonly _dialogService: AdminDialogService,
|
private readonly _dialogService: AdminDialogService,
|
||||||
private readonly _toaster: Toaster,
|
private readonly _toaster: Toaster,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
this.entitiesService.setEntities(this._watermarksMapService.get(this.#dossierTemplateId));
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
|
||||||
await this._loadData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async openConfirmDeleteWatermarkDialog($event: MouseEvent, watermark: Watermark): Promise<void> {
|
async openConfirmDeleteWatermarkDialog($event: MouseEvent, watermark: Watermark): Promise<void> {
|
||||||
const isUsed = await firstValueFrom(this._watermarkService.isWatermarkUsed(watermark.id));
|
const isUsed = await firstValueFrom(this._watermarkService.isWatermarkUsed(watermark.id));
|
||||||
|
|
||||||
if (!isUsed) {
|
|
||||||
await this._deleteWatermark(watermark);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = new ConfirmationDialogInput({
|
const data = new ConfirmationDialogInput({
|
||||||
question: _('watermarks-listing.watermark-is-used'),
|
question: isUsed ? _('watermarks-listing.watermark-is-used') : null,
|
||||||
});
|
});
|
||||||
this._dialogService.openDialog('confirm', $event, data, async () => {
|
this._dialogService.openDialog('confirm', $event, data, async () => {
|
||||||
await this._deleteWatermark(watermark);
|
await this._deleteWatermark(watermark);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async toggleStatus(watermark?: Watermark): Promise<void> {
|
async toggleStatus(watermark: Watermark): Promise<void> {
|
||||||
watermark.enabled = !watermark.enabled;
|
|
||||||
this._loadingService.start();
|
this._loadingService.start();
|
||||||
await firstValueFrom(this._watermarkService.saveWatermark(watermark));
|
const updatedWatermark = await firstValueFrom(this._watermarkService.saveWatermark({ ...watermark, enabled: !watermark.enabled }));
|
||||||
|
this.entitiesService.replace(updatedWatermark);
|
||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,25 +70,11 @@ export class WatermarksListingScreenComponent extends ListingComponent<Watermark
|
|||||||
return `/main/admin/dossier-templates/${this.#dossierTemplateId}/watermarks/${watermark ? watermark.id : 'create'}`;
|
return `/main/admin/dossier-templates/${this.#dossierTemplateId}/watermarks/${watermark ? watermark.id : 'create'}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _loadData(): Promise<void> {
|
|
||||||
this._loadingService.start();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await firstValueFrom(this._watermarkService.getWatermarks(this.#dossierTemplateId));
|
|
||||||
const watermarkConfig = response?.map(item => new Watermark(item)) || [];
|
|
||||||
this.entitiesService.setEntities(watermarkConfig);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._loadingService.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _deleteWatermark(watermark: Watermark): Promise<void> {
|
private async _deleteWatermark(watermark: Watermark): Promise<void> {
|
||||||
this._loadingService.start();
|
this._loadingService.start();
|
||||||
await firstValueFrom(this._watermarkService.deleteWatermark(watermark.id));
|
await firstValueFrom(this._watermarkService.deleteWatermark(this.#dossierTemplateId, watermark.id));
|
||||||
|
this.entitiesService.setEntities(this._watermarksMapService.get(this.#dossierTemplateId));
|
||||||
this._toaster.success(_('watermarks-listing.action.delete-success'));
|
this._toaster.success(_('watermarks-listing.action.delete-success'));
|
||||||
await this._loadData();
|
|
||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,105 +0,0 @@
|
|||||||
<section>
|
|
||||||
<div class="page-header">
|
|
||||||
<redaction-dossier-template-breadcrumbs class="flex-1"></redaction-dossier-template-breadcrumbs>
|
|
||||||
|
|
||||||
<div class="actions flex-1">
|
|
||||||
<redaction-dossier-template-actions></redaction-dossier-template-actions>
|
|
||||||
|
|
||||||
<iqser-circle-button
|
|
||||||
[routerLink]="['../..']"
|
|
||||||
[tooltip]="'common.close' | translate"
|
|
||||||
icon="iqser:close"
|
|
||||||
tooltipPosition="below"
|
|
||||||
></iqser-circle-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content-inner">
|
|
||||||
<div class="overlay-shadow"></div>
|
|
||||||
|
|
||||||
<redaction-admin-side-nav type="dossierTemplates"></redaction-admin-side-nav>
|
|
||||||
|
|
||||||
<div class="content-container">
|
|
||||||
<iqser-table
|
|
||||||
[bulkActions]="bulkActions"
|
|
||||||
[headerTemplate]="headerTemplate"
|
|
||||||
[itemSize]="80"
|
|
||||||
[noDataText]="'watermarks-listing.no-data.title' | translate"
|
|
||||||
[selectionEnabled]="true"
|
|
||||||
[tableColumnConfigs]="tableColumnConfigs"
|
|
||||||
emptyColumnWidth="1fr"
|
|
||||||
noDataIcon="red:attribute"
|
|
||||||
></iqser-table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<ng-template #headerTemplate>
|
|
||||||
<div class="table-header-actions">
|
|
||||||
<iqser-icon-button
|
|
||||||
[routerLink]="getRouterLink()"
|
|
||||||
*ngIf="currentUser.isAdmin"
|
|
||||||
[label]="'watermarks-listing.add-new' | translate"
|
|
||||||
[type]="iconButtonTypes.primary"
|
|
||||||
icon="iqser:plus"
|
|
||||||
></iqser-icon-button>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
<ng-template #bulkActions>
|
|
||||||
<iqser-circle-button
|
|
||||||
*ngIf="currentUser.isAdmin && (listingService.areSomeSelected$ | async)"
|
|
||||||
[tooltip]="'watermarks-listing.action.delete' | translate"
|
|
||||||
[type]="circleButtonTypes.dark"
|
|
||||||
icon="iqser:trash"
|
|
||||||
></iqser-circle-button>
|
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
<ng-template #tableItemTemplate let-entity="entity">
|
|
||||||
<div *ngIf="cast(entity) as watermark">
|
|
||||||
<div class="label cell">
|
|
||||||
<span>{{ watermark.name }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="center cell">
|
|
||||||
<mat-slide-toggle (toggleChange)="toggleStatus(watermark)" [checked]="watermark.enabled" color="primary"></mat-slide-toggle>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cell user-column">
|
|
||||||
<redaction-initials-avatar
|
|
||||||
[defaultValue]="'unknown' | translate"
|
|
||||||
[user]="watermark.createdBy || 'system'"
|
|
||||||
></redaction-initials-avatar>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cell">
|
|
||||||
<div class="small-label">
|
|
||||||
{{ watermark.dateAdded | date: 'd MMM yyyy' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cell">
|
|
||||||
<div class="small-label">
|
|
||||||
{{ watermark.dateModified | date: 'd MMM yyyy' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="cell">
|
|
||||||
<div class="action-buttons">
|
|
||||||
<iqser-circle-button
|
|
||||||
[routerLink]="getRouterLink(watermark)"
|
|
||||||
[tooltip]="'watermarks-listing.action.edit' | translate"
|
|
||||||
[type]="circleButtonTypes.dark"
|
|
||||||
icon="iqser:edit"
|
|
||||||
></iqser-circle-button>
|
|
||||||
|
|
||||||
<iqser-circle-button
|
|
||||||
(action)="openConfirmDeleteWatermarkDialog($event, watermark)"
|
|
||||||
[tooltip]="'watermarks-listing.action.delete' | translate"
|
|
||||||
[type]="circleButtonTypes.dark"
|
|
||||||
icon="iqser:trash"
|
|
||||||
></iqser-circle-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
@ -5,11 +5,10 @@ import { NGXLogger } from 'ngx-logger';
|
|||||||
import { ViewModeService } from './view-mode.service';
|
import { ViewModeService } from './view-mode.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { Core } from '@pdftron/webviewer';
|
import { Core } from '@pdftron/webviewer';
|
||||||
import { firstValueFrom } from 'rxjs';
|
|
||||||
import { WatermarkService } from '@services/entity-services/watermark.service';
|
|
||||||
import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service';
|
import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service';
|
||||||
import { REDDocumentViewer } from '../../pdf-viewer/services/document-viewer.service';
|
import { REDDocumentViewer } from '../../pdf-viewer/services/document-viewer.service';
|
||||||
import { LicenseService } from '../../../services/license.service';
|
import { LicenseService } from '@services/license.service';
|
||||||
|
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
|
||||||
import PDFNet = Core.PDFNet;
|
import PDFNet = Core.PDFNet;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -21,7 +20,7 @@ export class StampService {
|
|||||||
private readonly _logger: NGXLogger,
|
private readonly _logger: NGXLogger,
|
||||||
private readonly _viewModeService: ViewModeService,
|
private readonly _viewModeService: ViewModeService,
|
||||||
private readonly _translateService: TranslateService,
|
private readonly _translateService: TranslateService,
|
||||||
private readonly _watermarkService: WatermarkService,
|
private readonly _watermarksMapService: WatermarksMapService,
|
||||||
private readonly _licenseService: LicenseService,
|
private readonly _licenseService: LicenseService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -44,7 +43,7 @@ export class StampService {
|
|||||||
if (this._viewModeService.isRedacted) {
|
if (this._viewModeService.isRedacted) {
|
||||||
const dossier = this._state.dossier;
|
const dossier = this._state.dossier;
|
||||||
if (dossier.previewWatermarkId) {
|
if (dossier.previewWatermarkId) {
|
||||||
await this._stampPreview(pdfDoc, dossier.dossierTemplateId);
|
await this._stampPreview(pdfDoc, dossier.dossierTemplateId, dossier.previewWatermarkId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await this._stampExcludedPages(pdfDoc, file.excludedPages);
|
await this._stampExcludedPages(pdfDoc, file.excludedPages);
|
||||||
@ -70,8 +69,8 @@ export class StampService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _stampPreview(document: PDFNet.PDFDoc, dossierTemplateId: string): Promise<void> {
|
private async _stampPreview(document: PDFNet.PDFDoc, dossierTemplateId: string, watermarkId: string): Promise<void> {
|
||||||
const watermark = await firstValueFrom(this._watermarkService.getWatermark(dossierTemplateId));
|
const watermark = this._watermarksMapService.get(dossierTemplateId, watermarkId);
|
||||||
await stampPDFPage(
|
await stampPDFPage(
|
||||||
document,
|
document,
|
||||||
this._pdf.PDFNet,
|
this._pdf.PDFNet,
|
||||||
|
|||||||
@ -15,13 +15,19 @@
|
|||||||
></redaction-select>
|
></redaction-select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<redaction-dossier-watermark-selector
|
<redaction-watermark-selector
|
||||||
[dossierTemplateId]="dossier.dossierTemplateId"
|
[dossierTemplateId]="dossier.dossierTemplateId"
|
||||||
[watermarkId]="form.get('watermarkId').value"
|
[label]="'dossier-watermark-selector.watermark' | translate"
|
||||||
[previewWatermarkId]="form.get('previewWatermarkId').value"
|
formControlName="watermarkId"
|
||||||
(idsUpdate)="updateWatermarkIds($event)"
|
|
||||||
>
|
>
|
||||||
</redaction-dossier-watermark-selector>
|
</redaction-watermark-selector>
|
||||||
|
|
||||||
|
<redaction-watermark-selector
|
||||||
|
[dossierTemplateId]="dossier.dossierTemplateId"
|
||||||
|
[label]="'dossier-watermark-selector.preview' | translate"
|
||||||
|
formControlName="previewWatermarkId"
|
||||||
|
>
|
||||||
|
</redaction-watermark-selector>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ng-template #reportTemplateOptionTemplate let-option="option">
|
<ng-template #reportTemplateOptionTemplate let-option="option">
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import { ReportTemplateService } from '@services/report-template.service';
|
|||||||
import { PermissionsService } from '@services/permissions.service';
|
import { PermissionsService } from '@services/permissions.service';
|
||||||
import { firstValueFrom } from 'rxjs';
|
import { firstValueFrom } from 'rxjs';
|
||||||
import { DossiersService } from '@services/dossiers/dossiers.service';
|
import { DossiersService } from '@services/dossiers/dossiers.service';
|
||||||
import { UpdateWatermarkIdsEvent } from '@components/dossier-watermark-selector/dossier-watermark-selector.component';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redaction-edit-dossier-download-package',
|
selector: 'redaction-edit-dossier-download-package',
|
||||||
@ -47,7 +46,7 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const key of Object.keys(this.form.getRawValue())) {
|
for (const key of Object.keys(this.form.getRawValue())) {
|
||||||
if (key.startsWith('watermark') || key.startsWith('previewWatermark')) {
|
if (key.toLowerCase().includes('watermark')) {
|
||||||
if (this.dossier[key] !== this.form.get(key).value) {
|
if (this.dossier[key] !== this.form.get(key).value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -107,8 +106,8 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
|
|||||||
this.form.reset({
|
this.form.reset({
|
||||||
downloadFileTypes: this.dossier.downloadFileTypes,
|
downloadFileTypes: this.dossier.downloadFileTypes,
|
||||||
reportTemplateIds: this.dossier.reportTemplateIds,
|
reportTemplateIds: this.dossier.reportTemplateIds,
|
||||||
watermarkId: [this.dossier.watermarkId],
|
watermarkId: this.dossier.watermarkId,
|
||||||
previewWatermarkId: [this.dossier.previewWatermarkId],
|
previewWatermarkId: this.dossier.previewWatermarkId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,9 +127,4 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateWatermarkIds(event: UpdateWatermarkIdsEvent) {
|
|
||||||
this.form.get('watermarkId').setValue(event.watermarkId);
|
|
||||||
this.form.get('previewWatermarkId').setValue(event.previewWatermarkId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
<div *ngIf="watermarks$ | async as watermarks" class="container">
|
||||||
|
<div class="iqser-input-group watermark">
|
||||||
|
<mat-checkbox (change)="changeChecked($event)" [checked]="!!value" [disabled]="disabled" color="primary">
|
||||||
|
{{ label }}
|
||||||
|
</mat-checkbox>
|
||||||
|
|
||||||
|
<mat-select (selectionChange)="selectWatermark($event.value)" *ngIf="!!value" [value]="value">
|
||||||
|
<mat-select-trigger *ngIf="!!value">
|
||||||
|
<mat-icon *ngIf="!watermarksMap.get(value)?.enabled" svgIcon="red:warning"></mat-icon>
|
||||||
|
<span> {{ watermarksMap.get(value)?.name }} </span>
|
||||||
|
</mat-select-trigger>
|
||||||
|
|
||||||
|
<mat-option *ngFor="let watermark of watermarks" [disabled]="!watermark.enabled" [value]="watermark.id">
|
||||||
|
<mat-icon *ngIf="!watermark.enabled" svgIcon="red:warning"></mat-icon>
|
||||||
|
{{ watermark.name }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core';
|
||||||
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
|
import { FormFieldComponent, shareLast } from '@iqser/common-ui';
|
||||||
|
import { filter, map, tap } from 'rxjs/operators';
|
||||||
|
import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||||
|
import { Watermark } from '@red/domain';
|
||||||
|
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
|
||||||
|
import { MatCheckboxChange } from '@angular/material/checkbox';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'redaction-watermark-selector [dossierTemplateId] [label]',
|
||||||
|
templateUrl: './watermark-selector.component.html',
|
||||||
|
styleUrls: ['./watermark-selector.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: NG_VALUE_ACCESSOR,
|
||||||
|
multi: true,
|
||||||
|
useExisting: WatermarkSelectorComponent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: NG_VALIDATORS,
|
||||||
|
multi: true,
|
||||||
|
useExisting: WatermarkSelectorComponent,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class WatermarkSelectorComponent extends FormFieldComponent<string> implements OnChanges {
|
||||||
|
@Input() dossierTemplateId: string;
|
||||||
|
@Input() label: string;
|
||||||
|
readonly watermarks$: Observable<Watermark[]>;
|
||||||
|
watermarksMap = new Map<string, Watermark>();
|
||||||
|
#watermarks: Watermark[] = [];
|
||||||
|
readonly #dossierTemplateId$ = new BehaviorSubject<string>(null);
|
||||||
|
|
||||||
|
constructor(private readonly _watermarksMapService: WatermarksMapService) {
|
||||||
|
super();
|
||||||
|
this.watermarks$ = this.#dossierTemplateId$.pipe(
|
||||||
|
filter(dossierTemplateId => !!dossierTemplateId),
|
||||||
|
map(dossierTemplateId => this._watermarksMapService.get(dossierTemplateId)),
|
||||||
|
tap(watermarks => {
|
||||||
|
this.#watermarks = watermarks;
|
||||||
|
this.watermarksMap.clear();
|
||||||
|
watermarks.forEach(watermark => this.watermarksMap.set(watermark.id, watermark));
|
||||||
|
}),
|
||||||
|
tap(watermarks => {
|
||||||
|
if (!watermarks.length) {
|
||||||
|
this.selectWatermark(null);
|
||||||
|
this.setDisabledState(true);
|
||||||
|
} else {
|
||||||
|
this.setDisabledState(false);
|
||||||
|
if (this.value && this.touched) {
|
||||||
|
this.selectWatermark(watermarks[0].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
shareLast(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
changeChecked($event: MatCheckboxChange): void {
|
||||||
|
const { checked } = $event;
|
||||||
|
if (!checked || this.#watermarks.length === 0) {
|
||||||
|
this.selectWatermark(null);
|
||||||
|
} else {
|
||||||
|
this.selectWatermark(this.#watermarks[0].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectWatermark(watermarkId: string): void {
|
||||||
|
this.markAsTouched();
|
||||||
|
this._value = watermarkId;
|
||||||
|
this.onChange(this._value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
if (changes.dossierTemplateId) {
|
||||||
|
this.#dossierTemplateId$.next(this.dossierTemplateId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -47,8 +47,19 @@
|
|||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<redaction-dossier-watermark-selector [dossierTemplateId]="dossierTemplateId" (idsUpdate)="updateWatermarkIds($event)">
|
<redaction-watermark-selector
|
||||||
</redaction-dossier-watermark-selector>
|
[dossierTemplateId]="dossierTemplateId"
|
||||||
|
[label]="'dossier-watermark-selector.watermark' | translate"
|
||||||
|
formControlName="watermarkId"
|
||||||
|
>
|
||||||
|
</redaction-watermark-selector>
|
||||||
|
|
||||||
|
<redaction-watermark-selector
|
||||||
|
[dossierTemplateId]="dossierTemplateId"
|
||||||
|
[label]="'dossier-watermark-selector.preview' | translate"
|
||||||
|
formControlName="previewWatermarkId"
|
||||||
|
>
|
||||||
|
</redaction-watermark-selector>
|
||||||
|
|
||||||
<div class="due-date">
|
<div class="due-date">
|
||||||
<mat-checkbox (change)="hasDueDate = !hasDueDate" [checked]="hasDueDate" class="filter-menu-checkbox" color="primary">
|
<mat-checkbox (change)="hasDueDate = !hasDueDate" [checked]="hasDueDate" class="filter-menu-checkbox" color="primary">
|
||||||
@ -92,10 +103,10 @@
|
|||||||
<iqser-icon-button
|
<iqser-icon-button
|
||||||
(action)="save({ addMembers: true })"
|
(action)="save({ addMembers: true })"
|
||||||
[disabled]="disabled"
|
[disabled]="disabled"
|
||||||
|
[id]="'createDossierEditTeamButton'"
|
||||||
[label]="'add-dossier-dialog.actions.save-and-add-members' | translate"
|
[label]="'add-dossier-dialog.actions.save-and-add-members' | translate"
|
||||||
[type]="iconButtonTypes.dark"
|
[type]="iconButtonTypes.dark"
|
||||||
icon="red:assign"
|
icon="red:assign"
|
||||||
[id]="'createDossierEditTeamButton'"
|
|
||||||
></iqser-icon-button>
|
></iqser-icon-button>
|
||||||
|
|
||||||
<iqser-help-button helpButtonKey="new_dossier_button"></iqser-help-button>
|
<iqser-help-button helpButtonKey="new_dossier_button"></iqser-help-button>
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { firstValueFrom } from 'rxjs';
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { DossiersDialogService } from '../../../shared-dossiers/services/dossiers-dialog.service';
|
import { DossiersDialogService } from '../../../shared-dossiers/services/dossiers-dialog.service';
|
||||||
import { UpdateWatermarkIdsEvent } from '@components/dossier-watermark-selector/dossier-watermark-selector.component';
|
|
||||||
|
|
||||||
interface DialogData {
|
interface DialogData {
|
||||||
readonly dossierTemplateId?: string;
|
readonly dossierTemplateId?: string;
|
||||||
@ -67,17 +66,11 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On
|
|||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
this.dossierTemplateId = this.form.get('dossierTemplateId').value;
|
await this.dossierTemplateChanged(this.form.get('dossierTemplateId').value);
|
||||||
await this.dossierTemplateChanged(this.dossierTemplateId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reportTemplateValueMapper = (reportTemplate: IReportTemplate) => reportTemplate.templateId;
|
reportTemplateValueMapper = (reportTemplate: IReportTemplate) => reportTemplate.templateId;
|
||||||
|
|
||||||
updateWatermarkIds(event: UpdateWatermarkIdsEvent) {
|
|
||||||
this.form.get('watermarkId').setValue(event.watermarkId);
|
|
||||||
this.form.get('previewWatermarkId').setValue(event.previewWatermarkId);
|
|
||||||
}
|
|
||||||
|
|
||||||
async save(options?: SaveOptions) {
|
async save(options?: SaveOptions) {
|
||||||
this._loadingService.start();
|
this._loadingService.start();
|
||||||
const savedDossier = await firstValueFrom(this._activeDossiersService.createOrUpdate(this._formToObject()));
|
const savedDossier = await firstValueFrom(this._activeDossiersService.createOrUpdate(this._formToObject()));
|
||||||
@ -94,7 +87,9 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On
|
|||||||
this._loadingService.stop();
|
this._loadingService.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
async dossierTemplateChanged(dossierTemplateId) {
|
async dossierTemplateChanged(dossierTemplateId: string) {
|
||||||
|
this.dossierTemplateId = dossierTemplateId;
|
||||||
|
|
||||||
// get current selected dossierTemplate
|
// get current selected dossierTemplate
|
||||||
const dossierTemplate = this.dossierTemplates.find(r => r.dossierTemplateId === dossierTemplateId);
|
const dossierTemplate = this.dossierTemplates.find(r => r.dossierTemplateId === dossierTemplateId);
|
||||||
|
|
||||||
|
|||||||
@ -23,20 +23,20 @@ import { TypeFilterComponent } from './components/type-filter/type-filter.compon
|
|||||||
import { TeamMembersComponent } from './components/team-members/team-members.component';
|
import { TeamMembersComponent } from './components/team-members/team-members.component';
|
||||||
import { EditorComponent } from './components/editor/editor.component';
|
import { EditorComponent } from './components/editor/editor.component';
|
||||||
import { ExpandableFileActionsComponent } from './components/expandable-file-actions/expandable-file-actions.component';
|
import { ExpandableFileActionsComponent } from './components/expandable-file-actions/expandable-file-actions.component';
|
||||||
import { ProcessingIndicatorComponent } from '@shared/components/processing-indicator/processing-indicator.component';
|
import { ProcessingIndicatorComponent } from './components/processing-indicator/processing-indicator.component';
|
||||||
import { DossierStateComponent } from '@shared/components/dossier-state/dossier-state.component';
|
import { DossierStateComponent } from './components/dossier-state/dossier-state.component';
|
||||||
import { FileStatsComponent } from './components/file-stats/file-stats.component';
|
import { FileStatsComponent } from './components/file-stats/file-stats.component';
|
||||||
import { FileNameColumnComponent } from '@shared/components/file-name-column/file-name-column.component';
|
import { FileNameColumnComponent } from './components/file-name-column/file-name-column.component';
|
||||||
import { DossierNameColumnComponent } from '@shared/components/dossier-name-column/dossier-name-column.component';
|
import { DossierNameColumnComponent } from './components/dossier-name-column/dossier-name-column.component';
|
||||||
import { MAT_DATE_FORMATS } from '@angular/material/core';
|
import { MAT_DATE_FORMATS } from '@angular/material/core';
|
||||||
import { DossiersTypeSwitchComponent } from '@shared/components/dossiers-type-switch/dossiers-type-switch.component';
|
import { DossiersTypeSwitchComponent } from './components/dossiers-type-switch/dossiers-type-switch.component';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { AddDossierDialogComponent } from '@shared/dialogs/add-dossier-dialog/add-dossier-dialog.component';
|
import { AddDossierDialogComponent } from './dialogs/add-dossier-dialog/add-dossier-dialog.component';
|
||||||
import { SharedDialogService } from '@shared/services/dialog.service';
|
import { SharedDialogService } from './services/dialog.service';
|
||||||
import { DossierWatermarkSelectorComponent } from '@components/dossier-watermark-selector/dossier-watermark-selector.component';
|
import { AddEditEntityComponent } from './components/add-edit-entity/add-edit-entity.component';
|
||||||
import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component';
|
|
||||||
import { ColorPickerModule } from 'ngx-color-picker';
|
import { ColorPickerModule } from 'ngx-color-picker';
|
||||||
|
import { WatermarkSelectorComponent } from './components/dossier-watermark-selector/watermark-selector.component';
|
||||||
|
|
||||||
const buttons = [FileDownloadBtnComponent, UserButtonComponent];
|
const buttons = [FileDownloadBtnComponent, UserButtonComponent];
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ const components = [
|
|||||||
FileNameColumnComponent,
|
FileNameColumnComponent,
|
||||||
DossiersTypeSwitchComponent,
|
DossiersTypeSwitchComponent,
|
||||||
AddDossierDialogComponent,
|
AddDossierDialogComponent,
|
||||||
DossierWatermarkSelectorComponent,
|
WatermarkSelectorComponent,
|
||||||
AddEditEntityComponent,
|
AddEditEntityComponent,
|
||||||
|
|
||||||
...buttons,
|
...buttons,
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { HttpErrorResponse, HttpStatusCode } from '@angular/common/http';
|
|||||||
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
||||||
import { DictionaryService } from '../entity-services/dictionary.service';
|
import { DictionaryService } from '../entity-services/dictionary.service';
|
||||||
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
|
import { DefaultColorsService } from '@services/entity-services/default-colors.service';
|
||||||
|
import { WatermarkService } from '@services/entity-services/watermark.service';
|
||||||
|
|
||||||
const DOSSIER_TEMPLATE_CONFLICT_MSG = _('dossier-templates-listing.error.conflict');
|
const DOSSIER_TEMPLATE_CONFLICT_MSG = _('dossier-templates-listing.error.conflict');
|
||||||
const GENERIC_MSG = _('dossier-templates-listing.error.generic');
|
const GENERIC_MSG = _('dossier-templates-listing.error.generic');
|
||||||
@ -26,6 +27,7 @@ export class DossierTemplatesService extends EntitiesService<IDossierTemplate, D
|
|||||||
private readonly _dossierTemplateStatsService: DossierTemplateStatsService,
|
private readonly _dossierTemplateStatsService: DossierTemplateStatsService,
|
||||||
private readonly _dictionaryService: DictionaryService,
|
private readonly _dictionaryService: DictionaryService,
|
||||||
private readonly _defaultColorsService: DefaultColorsService,
|
private readonly _defaultColorsService: DefaultColorsService,
|
||||||
|
private readonly _watermarksService: WatermarkService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@ -45,6 +47,7 @@ export class DossierTemplatesService extends EntitiesService<IDossierTemplate, D
|
|||||||
...getAttributes(templates),
|
...getAttributes(templates),
|
||||||
this._dictionaryService.loadDictionaryData(dossierTemplateIds(templates)),
|
this._dictionaryService.loadDictionaryData(dossierTemplateIds(templates)),
|
||||||
this._defaultColorsService.loadAll(dossierTemplateIds(templates)),
|
this._defaultColorsService.loadAll(dossierTemplateIds(templates)),
|
||||||
|
this._watermarksService.loadAll(dossierTemplateIds(templates)),
|
||||||
]).pipe(map(() => templates));
|
]).pipe(map(() => templates));
|
||||||
}
|
}
|
||||||
return of(templates);
|
return of(templates);
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { GenericService, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
import { GenericService, mapEach, QueryParam, RequiredParam, Validate } from '@iqser/common-ui';
|
||||||
import { IWatermark } from '@red/domain';
|
import { IWatermark, Watermark } from '@red/domain';
|
||||||
import { Observable } from 'rxjs';
|
import { forkJoin, Observable } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
import { map, switchMap, tap } from 'rxjs/operators';
|
||||||
|
import { WatermarksMapService } from '@services/entity-services/watermarks-map.service';
|
||||||
|
|
||||||
interface IsUsedResponse {
|
interface IsUsedResponse {
|
||||||
value: boolean;
|
value: boolean;
|
||||||
@ -14,25 +15,40 @@ interface IsUsedResponse {
|
|||||||
export class WatermarkService extends GenericService<IWatermark> {
|
export class WatermarkService extends GenericService<IWatermark> {
|
||||||
protected readonly _defaultModelPath = 'watermark';
|
protected readonly _defaultModelPath = 'watermark';
|
||||||
|
|
||||||
@Validate()
|
constructor(private readonly _watermarksMapService: WatermarksMapService) {
|
||||||
saveWatermark(@RequiredParam() body: IWatermark) {
|
super();
|
||||||
return this._post(body, `${this._defaultModelPath}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
deleteWatermark(@RequiredParam() watermarkId: string) {
|
deleteWatermark(@RequiredParam() dossierTemplateId: string, @RequiredParam() watermarkId: string): Observable<Watermark[]> {
|
||||||
return super.delete({}, `${this._defaultModelPath}/${watermarkId}`);
|
return super
|
||||||
|
.delete(null, `${this._defaultModelPath}/${watermarkId}`)
|
||||||
|
.pipe(switchMap(() => this.loadForDossierTemplate(dossierTemplateId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
getWatermark(@RequiredParam() watermarkId: string) {
|
saveWatermark(@RequiredParam() body: IWatermark): Observable<Watermark> {
|
||||||
return this._getOne([watermarkId]);
|
return this._post(body, `${this._defaultModelPath}`).pipe(
|
||||||
|
switchMap(watermark =>
|
||||||
|
this.loadForDossierTemplate(watermark.dossierTemplateId).pipe(
|
||||||
|
map(() => this._watermarksMapService.get(watermark.dossierTemplateId, watermark.id.toString())),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
getWatermarks(@RequiredParam() dossierTemplateId: string): Observable<IWatermark[]> {
|
loadForDossierTemplate(@RequiredParam() dossierTemplateId: string): Observable<Watermark[]> {
|
||||||
const queryParams: QueryParam[] = [{ key: 'dossierTemplateId', value: dossierTemplateId }];
|
const queryParams: QueryParam[] = [{ key: 'dossierTemplateId', value: dossierTemplateId }];
|
||||||
return this.getAll<IWatermark[]>(this._defaultModelPath, queryParams);
|
return this.getAll(this._defaultModelPath, queryParams).pipe(
|
||||||
|
mapEach(entity => new Watermark(entity)),
|
||||||
|
tap(entities => this._watermarksMapService.set(dossierTemplateId, entities.sort(this.sortByStatusFn))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Validate()
|
||||||
|
loadAll(@RequiredParam() dossierTemplateIds: string[]): Observable<Watermark[]> {
|
||||||
|
return forkJoin(dossierTemplateIds.map(id => this.loadForDossierTemplate(id))).pipe(map(arrays => [].concat(...arrays)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Validate()
|
@Validate()
|
||||||
@ -40,4 +56,11 @@ export class WatermarkService extends GenericService<IWatermark> {
|
|||||||
const queryParams: QueryParam[] = [{ key: 'watermarkId', value: watermarkId }];
|
const queryParams: QueryParam[] = [{ key: 'watermarkId', value: watermarkId }];
|
||||||
return this.getAll<IsUsedResponse>(`${this._defaultModelPath}/used`, queryParams).pipe(map(result => result.value));
|
return this.getAll<IsUsedResponse>(`${this._defaultModelPath}/used`, queryParams).pipe(map(result => result.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sortByStatusFn = (a: Watermark, b: Watermark) => {
|
||||||
|
if (a.enabled === b.enabled) {
|
||||||
|
return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1;
|
||||||
|
}
|
||||||
|
return a.enabled ? -1 : 1;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { DOSSIER_TEMPLATE_ID, IWatermark, Watermark } from '@red/domain';
|
||||||
|
import { EntitiesMapService } from '@iqser/common-ui';
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class WatermarksMapService extends EntitiesMapService<Watermark, IWatermark> {
|
||||||
|
protected readonly _primaryKey = DOSSIER_TEMPLATE_ID;
|
||||||
|
}
|
||||||
@ -1 +1 @@
|
|||||||
Subproject commit 345454be9d260a3fbb27e9e5b57902dda2e350e0
|
Subproject commit 477e8ea5ae97244703dbfe04a4ee98daa8d5f185
|
||||||
@ -19,8 +19,8 @@ export class Dossier implements IDossier, IListable {
|
|||||||
readonly hardDeletedTime?: string;
|
readonly hardDeletedTime?: string;
|
||||||
readonly softDeletedTime?: string;
|
readonly softDeletedTime?: string;
|
||||||
readonly startDate?: string;
|
readonly startDate?: string;
|
||||||
readonly watermarkId: number;
|
readonly watermarkId: string;
|
||||||
readonly previewWatermarkId: number;
|
readonly previewWatermarkId: string;
|
||||||
readonly archivedTime: string;
|
readonly archivedTime: string;
|
||||||
readonly hasReviewers: boolean;
|
readonly hasReviewers: boolean;
|
||||||
readonly routerLink: string;
|
readonly routerLink: string;
|
||||||
|
|||||||
@ -56,9 +56,9 @@ export interface IDossierRequest {
|
|||||||
/**
|
/**
|
||||||
* Watermark id that will be applied to the redacted files.
|
* Watermark id that will be applied to the redacted files.
|
||||||
*/
|
*/
|
||||||
readonly watermarkId?: number;
|
readonly watermarkId?: string;
|
||||||
/**
|
/**
|
||||||
* Watermark id that will be applied to the preview files.
|
* Watermark id that will be applied to the preview files.
|
||||||
*/
|
*/
|
||||||
readonly previewWatermarkId?: number;
|
readonly previewWatermarkId?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export interface IDossier {
|
|||||||
readonly reportTemplateIds: List;
|
readonly reportTemplateIds: List;
|
||||||
readonly softDeletedTime?: string;
|
readonly softDeletedTime?: string;
|
||||||
readonly startDate?: string;
|
readonly startDate?: string;
|
||||||
readonly watermarkId: number;
|
readonly watermarkId: string;
|
||||||
readonly previewWatermarkId: number;
|
readonly previewWatermarkId: string;
|
||||||
readonly archivedTime: string;
|
readonly archivedTime: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { IWatermark, WatermarkOrientation } from './watermark';
|
import { IWatermark, WatermarkOrientation } from './watermark';
|
||||||
import { IListable } from '@iqser/common-ui';
|
import { Entity } from '@iqser/common-ui';
|
||||||
|
|
||||||
export class Watermark implements IListable, IWatermark {
|
export class Watermark extends Entity<IWatermark> {
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
readonly dossierTemplateId: string;
|
readonly dossierTemplateId: string;
|
||||||
enabled: boolean;
|
readonly enabled: boolean;
|
||||||
readonly fontSize: number;
|
readonly fontSize: number;
|
||||||
readonly fontType: string;
|
readonly fontType: string;
|
||||||
readonly hexColor: string;
|
readonly hexColor: string;
|
||||||
@ -16,12 +16,15 @@ export class Watermark implements IListable, IWatermark {
|
|||||||
readonly dateAdded?: string;
|
readonly dateAdded?: string;
|
||||||
readonly dateModified?: string;
|
readonly dateModified?: string;
|
||||||
|
|
||||||
|
readonly routerLink = undefined;
|
||||||
|
|
||||||
constructor(watermark: IWatermark) {
|
constructor(watermark: IWatermark) {
|
||||||
this.id = watermark.id;
|
super(watermark);
|
||||||
|
this.id = watermark.id.toString();
|
||||||
this.dossierTemplateId = watermark.dossierTemplateId;
|
this.dossierTemplateId = watermark.dossierTemplateId;
|
||||||
this.enabled = watermark.enabled;
|
this.enabled = watermark.enabled;
|
||||||
this.fontSize = watermark.fontSize;
|
this.fontSize = watermark.fontSize;
|
||||||
this.fontType = watermark.fontType;
|
this.fontType = watermark.fontType === 'arial' ? 'helvetica' : watermark.fontType;
|
||||||
this.hexColor = watermark.hexColor;
|
this.hexColor = watermark.hexColor;
|
||||||
this.opacity = watermark.opacity;
|
this.opacity = watermark.opacity;
|
||||||
this.orientation = watermark.orientation;
|
this.orientation = watermark.orientation;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user