RED-4247 - fixed found issues:

- disabled watermarks can not be selected anymore on dossier create/edit and now user know if the watermark is disabled;
- table is now sortable;
- save button disappear now at first save;
- fixed checkbox text;
This commit is contained in:
Valentin Mihai 2022-07-06 02:08:53 +03:00
parent 5e027501e8
commit 8e8c07a60e
15 changed files with 204 additions and 134 deletions

View File

@ -0,0 +1,37 @@
<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>

View File

@ -0,0 +1,24 @@
.container {
margin-top: 14px;
.watermark {
width: 300px;
max-width: 300px;
mat-select {
margin-left: 22px;
mat-select-trigger,
mat-option {
display: flex;
align-items: center;
gap: 18px;
}
span {
text-overflow: ellipsis;
overflow: hidden;
}
}
}
}

View File

@ -0,0 +1,85 @@
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>();
#oldWatermarkId: string | null;
#oldPreviewWatermarkId: string | null;
watermarks$: Observable<OptionWatermark[]>;
readonly documentTypes = DocumentTypes;
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);
}
}

View File

@ -0,0 +1,14 @@
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;
}
}

View File

@ -137,6 +137,7 @@ export class WatermarkScreenComponent implements OnInit {
this._watermark.dossierTemplateId = this.#dossierTemplateId;
this.form.setValue({ ...watermark });
this._loadViewer();
this._changeDetectorRef.markForCheck();
}),
);
}

View File

@ -31,11 +31,11 @@ export class WatermarksListingScreenComponent extends ListingComponent<Watermark
readonly currentUser: User;
readonly tableColumnConfigs: TableColumnConfig<Watermark>[] = [
{ label: _('watermarks-listing.table-col-names.name'), width: '2fr' },
{ label: _('watermarks-listing.table-col-names.status'), class: 'flex-center' },
{ label: _('watermarks-listing.table-col-names.name'), sortByKey: 'searchKey', width: '2fr' },
{ label: _('watermarks-listing.table-col-names.status'), sortByKey: 'enabled', class: 'flex-center' },
{ label: _('watermarks-listing.table-col-names.created-by'), class: 'user-column' },
{ label: _('watermarks-listing.table-col-names.created-on') },
{ label: _('watermarks-listing.table-col-names.modified-on') },
{ label: _('watermarks-listing.table-col-names.created-on'), sortByKey: 'dateAdded' },
{ label: _('watermarks-listing.table-col-names.modified-on'), sortByKey: 'dateModified' },
];
readonly tableHeaderLabel: string = _('watermarks-listing.table-header.title');

View File

@ -74,6 +74,7 @@ export class IconsModule {
'user',
'visibility',
'visibility-off',
'warning',
];
for (const icon of icons) {

View File

@ -15,41 +15,13 @@
></redaction-select>
</div>
<ng-container *ngIf="watermarks.length">
<div class="iqser-input-group watermark">
<mat-checkbox
color="primary"
[checked]="isWatermarkEnabled('watermarkId')"
(change)="enableDisableWatermark($event.checked, 'watermarkId')"
>
{{ 'add-dossier-dialog.form.watermark' | translate }}
</mat-checkbox>
<mat-form-field *ngIf="isWatermarkEnabled('watermarkId')">
<mat-select formControlName="watermarkId">
<mat-option *ngFor="let watermark of watermarks" [value]="watermark.id">
{{ watermark.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="iqser-input-group watermark">
<mat-checkbox
color="primary"
[checked]="isWatermarkEnabled('previewWatermarkId')"
(change)="enableDisableWatermark($event.checked, 'previewWatermarkId')"
>
{{ 'add-dossier-dialog.form.preview' | translate }}
</mat-checkbox>
<mat-form-field *ngIf="isWatermarkEnabled('previewWatermarkId')">
<mat-select formControlName="previewWatermarkId">
<mat-option *ngFor="let watermark of watermarks" [value]="watermark.id">
{{ watermark.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</ng-container>
<redaction-dossier-watermark-selector
[dossierTemplateId]="dossier.dossierTemplateId"
[watermarkId]="form.get('watermarkId').value"
[previewWatermarkId]="form.get('previewWatermarkId').value"
(idsUpdate)="updateWatermarkIds($event)"
>
</redaction-dossier-watermark-selector>
</form>
<ng-template #reportTemplateOptionTemplate let-option="option">

View File

@ -8,6 +8,7 @@ import { PermissionsService } from '@services/permissions.service';
import { firstValueFrom } from 'rxjs';
import { DossiersService } from '@services/dossiers/dossiers.service';
import { WatermarkService } from '@services/entity-services/watermark.service';
import { UpdateWatermarkIdsEvent } from '@components/dossier-watermark-selector/dossier-watermark-selector.component';
@Component({
selector: 'redaction-edit-dossier-download-package',
@ -23,9 +24,6 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
}),
);
availableReportTypes: IReportTemplate[] = [];
watermarks: IWatermark[] = [];
oldWatermarkId: string;
oldPreviewWatermarkID: string;
@Input() dossier: Dossier;
@ -34,7 +32,6 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
private readonly _reportTemplateController: ReportTemplateService,
private readonly _formBuilder: UntypedFormBuilder,
private readonly _permissionsService: PermissionsService,
private readonly _watermarkService: WatermarkService,
) {}
get reportTypesLength() {
@ -92,10 +89,6 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
if (!this._permissionsService.canEditDossier(this.dossier)) {
this.form.disable();
}
this.watermarks = await firstValueFrom(this._watermarkService.getWatermarks(dossierTemplateId));
this.oldWatermarkId = this.form.get('watermarkId').value || this.watermarks[0]?.id;
this.oldPreviewWatermarkID = this.form.get('previewWatermarkId').value || this.watermarks[0]?.id;
}
async save(): EditDossierSaveResult {
@ -137,19 +130,8 @@ export class EditDossierDownloadPackageComponent implements OnInit, EditDossierS
);
}
isWatermarkEnabled(key: string): boolean {
return this.form.get(key).value;
}
enableDisableWatermark(checked: boolean, key: string): void {
let oldValue: string;
if (key === 'watermarkId') {
this.oldWatermarkId = !checked ? this.form.get(key).value : this.oldWatermarkId;
oldValue = this.oldWatermarkId;
} else {
this.oldPreviewWatermarkID = !checked ? this.form.get(key).value : this.oldPreviewWatermarkID;
oldValue = this.oldPreviewWatermarkID;
}
this.form.get(key).setValue(checked ? oldValue : null);
updateWatermarkIds(event: UpdateWatermarkIdsEvent) {
this.form.get('watermarkId').setValue(event.watermarkId);
this.form.get('previewWatermarkId').setValue(event.previewWatermarkId);
}
}

View File

@ -47,41 +47,8 @@
></textarea>
</div>
<ng-container *ngIf="watermarks.length">
<div class="iqser-input-group watermark">
<mat-checkbox
color="primary"
[checked]="isWatermarkEnabled('watermarkId')"
(change)="enableDisableWatermark($event.checked, 'watermarkId')"
>
{{ 'add-dossier-dialog.form.watermark' | translate }}
</mat-checkbox>
<mat-form-field *ngIf="isWatermarkEnabled('watermarkId')">
<mat-select formControlName="watermarkId">
<mat-option *ngFor="let watermark of watermarks" [value]="watermark.id">
{{ watermark.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="iqser-input-group watermark">
<mat-checkbox
color="primary"
[checked]="isWatermarkEnabled('previewWatermarkId')"
(change)="enableDisableWatermark($event.checked, 'previewWatermarkId')"
>
{{ 'add-dossier-dialog.form.preview' | translate }}
</mat-checkbox>
<mat-form-field *ngIf="isWatermarkEnabled('previewWatermarkId')">
<mat-select formControlName="previewWatermarkId">
<mat-option *ngFor="let watermark of watermarks" [value]="watermark.id">
{{ watermark.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</ng-container>
<redaction-dossier-watermark-selector [dossierTemplateId]="dossierTemplateId" (idsUpdate)="updateWatermarkIds($event)">
</redaction-dossier-watermark-selector>
<div class="due-date">
<mat-checkbox (change)="hasDueDate = !hasDueDate" [checked]="hasDueDate" class="filter-menu-checkbox" color="primary">

View File

@ -1,6 +1,6 @@
import { Component, Inject, Injector, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { DOSSIER_TEMPLATE_ID, DownloadFileType, IDossierRequest, IDossierTemplate, IReportTemplate, IWatermark } from '@red/domain';
import { DOSSIER_TEMPLATE_ID, DownloadFileType, IDossierRequest, IDossierTemplate, IReportTemplate } from '@red/domain';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { downloadTypesTranslations } from '@translations/download-types-translations';
import { BaseDialogComponent, IconButtonTypes, LoadingService, SaveOptions } from '@iqser/common-ui';
@ -11,7 +11,7 @@ import { firstValueFrom } from 'rxjs';
import dayjs from 'dayjs';
import { Router } from '@angular/router';
import { DossiersDialogService } from '../../../shared-dossiers/services/dossiers-dialog.service';
import { WatermarkService } from '@services/entity-services/watermark.service';
import { UpdateWatermarkIdsEvent } from '@components/dossier-watermark-selector/dossier-watermark-selector.component';
interface DialogData {
readonly dossierTemplateId?: string;
@ -33,9 +33,7 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On
);
dossierTemplates: IDossierTemplate[];
availableReportTypes = [];
watermarks: IWatermark[] = [];
oldWatermarkId: string;
oldPreviewWatermarkID: string;
dossierTemplateId: string;
constructor(
private readonly _activeDossiersService: ActiveDossiersService,
@ -45,7 +43,6 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On
private readonly _router: Router,
private readonly _dialogService: DossiersDialogService,
private readonly _loadingService: LoadingService,
private readonly _watermarkService: WatermarkService,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<AddDossierDialogComponent>,
@Inject(MAT_DIALOG_DATA) readonly data: DialogData,
@ -73,15 +70,17 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On
}
async ngOnInit(): Promise<void> {
const dossierTemplateId = this.form.get('dossierTemplateId').value;
await this.dossierTemplateChanged(dossierTemplateId);
this.watermarks = await firstValueFrom(this._watermarkService.getWatermarks(dossierTemplateId));
this.oldWatermarkId = this.watermarks[0]?.id;
this.oldPreviewWatermarkID = this.watermarks[0]?.id;
this.dossierTemplateId = this.form.get('dossierTemplateId').value;
await this.dossierTemplateChanged(this.dossierTemplateId);
}
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) {
this._loadingService.start();
const savedDossier = await firstValueFrom(this._activeDossiersService.createOrUpdate(this._formToObject()));
@ -168,20 +167,4 @@ export class AddDossierDialogComponent extends BaseDialogComponent implements On
previewWatermarkId: this.form.get('previewWatermarkId').value,
};
}
isWatermarkEnabled(key: string): boolean {
return !!this.form.get(key).value;
}
enableDisableWatermark(checked: boolean, key: string): void {
let oldValue: string;
if (key === 'watermarkId') {
this.oldWatermarkId = !checked ? this.form.get(key).value : this.oldWatermarkId;
oldValue = this.oldWatermarkId;
} else {
this.oldPreviewWatermarkID = !checked ? this.form.get(key).value : this.oldPreviewWatermarkID;
oldValue = this.oldPreviewWatermarkID;
}
this.form.get(key).setValue(checked ? oldValue : null);
}
}

View File

@ -35,6 +35,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { RouterModule } from '@angular/router';
import { AddDossierDialogComponent } from '@shared/dialogs/add-dossier-dialog/add-dossier-dialog.component';
import { SharedDialogService } from '@shared/services/dialog.service';
import { DossierWatermarkSelectorComponent } from '@components/dossier-watermark-selector/dossier-watermark-selector.component';
const buttons = [FileDownloadBtnComponent, UserButtonComponent];
@ -57,7 +58,7 @@ const components = [
FileNameColumnComponent,
DossiersTypeSwitchComponent,
AddDossierDialogComponent,
DossierWatermarkSelectorComponent,
...buttons,
];

View File

@ -27,12 +27,10 @@
"label": "Dossier-Name",
"placeholder": "Geben Sie einen Namen ein."
},
"preview": "",
"template": {
"label": "Dossier-Vorlage",
"placeholder": ""
},
"watermark": "Geschwärzte Dokumente mit Wasserzeichen versehen"
}
},
"header-new": "Dossier erstellen"
},
@ -98,11 +96,7 @@
"name-placeholder": "",
"rank": "",
"rank-placeholder": "",
"recommendation-color": "",
"recommendation-color-placeholder": "",
"redaction": "",
"skipped-color": "",
"skipped-color-placeholder": "",
"technical-name": "",
"technical-name-hint": ""
},
@ -705,6 +699,7 @@
"title": "Es ist kein Zertifikat für die digitale Signatur konfiguriert. Laden Sie ein PCKS#12-Zertifikat hoch, um Ihre geschwärzten Dokumente zu signieren."
}
},
"disabled": "",
"document-info": {
"save": "Dokumenteninformation speichern",
"title": "Datei-Attribute anlegen"
@ -995,6 +990,10 @@
"incomplete": ""
}
},
"dossier-watermark-selector": {
"preview": "",
"watermark": ""
},
"dossiers-type-switch": {
"active": "",
"archive": ""

View File

@ -27,12 +27,10 @@
"label": "Dossier Name",
"placeholder": "Enter Name"
},
"preview": "Watermark application on preview documents",
"template": {
"label": "Dossier Template",
"placeholder": "Choose Dossier Template"
},
"watermark": "Watermark application on redacted documents"
}
},
"header-new": "Create Dossier"
},
@ -701,6 +699,7 @@
"title": "No Digital Signature Certificate.<br/>For signing redacted documents please configure a certificate."
}
},
"disabled": "disabled",
"document-info": {
"save": "Save Document Info",
"title": "Enter File Attributes"
@ -991,6 +990,10 @@
"incomplete": "Incomplete"
}
},
"dossier-watermark-selector": {
"preview": "Watermark application on preview documents",
"watermark": "Watermark application on watermark documents"
},
"dossiers-type-switch": {
"active": "Active",
"archive": "Archived"

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><defs><linearGradient gradientTransform="matrix(1.31117 0 0 1.30239 737.39 159.91)" gradientUnits="userSpaceOnUse" id="0" y2="-.599" x2="0" y1="45.47"><stop stop-color="#ffc515"/><stop offset="1" stop-color="#ffd55b"/></linearGradient></defs><g transform="matrix(.85714 0 0 .85714-627.02-130.8)"><path d="m797.94 212.01l-25.607-48c-.736-1.333-2.068-2.074-3.551-2.074-1.483 0-2.822.889-3.569 2.222l-25.417 48c-.598 1.185-.605 2.815.132 4 .737 1.185 1.921 1.778 3.404 1.778h51.02c1.483 0 2.821-.741 3.42-1.926.747-1.185.753-2.667.165-4" fill="url(#0)"/><path d="m-26.309 18.07c-1.18 0-2.135.968-2.135 2.129v12.82c0 1.176.948 2.129 2.135 2.129 1.183 0 2.135-.968 2.135-2.129v-12.82c0-1.176-.946-2.129-2.135-2.129zm0 21.348c-1.18 0-2.135.954-2.135 2.135 0 1.18.954 2.135 2.135 2.135 1.181 0 2.135-.954 2.135-2.135 0-1.18-.952-2.135-2.135-2.135z" transform="matrix(1.05196 0 0 1.05196 796.53 161.87)" fill="#000" stroke="#40330d" fill-opacity=".75"/></g></svg>

After

Width:  |  Height:  |  Size: 1016 B