RED-4416: Customize dossier dictionary colors

This commit is contained in:
Adina Țeudan 2022-07-06 15:34:38 +03:00
parent 703466dd81
commit 80cef8bad6
24 changed files with 207 additions and 163 deletions

View File

@ -9,7 +9,6 @@ import { DigitalSignatureScreenComponent } from './screens/digital-signature/dig
import { FileAttributesListingScreenComponent } from './screens/file-attributes-listing/file-attributes-listing-screen.component'; import { FileAttributesListingScreenComponent } from './screens/file-attributes-listing/file-attributes-listing-screen.component';
import { UserListingScreenComponent } from './screens/user-listing/user-listing-screen.component'; import { UserListingScreenComponent } from './screens/user-listing/user-listing-screen.component';
import { DossierTemplateBreadcrumbsComponent } from './components/dossier-template-breadcrumbs/dossier-template-breadcrumbs.component'; import { DossierTemplateBreadcrumbsComponent } from './components/dossier-template-breadcrumbs/dossier-template-breadcrumbs.component';
import { ColorPickerModule } from 'ngx-color-picker';
import { AddEditFileAttributeDialogComponent } from './dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component'; import { AddEditFileAttributeDialogComponent } from './dialogs/add-edit-file-attribute-dialog/add-edit-file-attribute-dialog.component';
import { AddEditCloneDossierTemplateDialogComponent } from './dialogs/add-edit-dossier-template-dialog/add-edit-clone-dossier-template-dialog.component'; import { AddEditCloneDossierTemplateDialogComponent } from './dialogs/add-edit-dossier-template-dialog/add-edit-clone-dossier-template-dialog.component';
import { AddEntityDialogComponent } from './dialogs/add-entity-dialog/add-entity-dialog.component'; import { AddEntityDialogComponent } from './dialogs/add-entity-dialog/add-entity-dialog.component';
@ -102,6 +101,6 @@ const components = [
@NgModule({ @NgModule({
declarations: [...components], declarations: [...components],
providers: [AdminDialogService, AuditService, DigitalSignatureService, RulesService, SmtpConfigService], providers: [AdminDialogService, AuditService, DigitalSignatureService, RulesService, SmtpConfigService],
imports: [CommonModule, SharedModule, AdminRoutingModule, SharedAdminModule, ColorPickerModule, A11yModule], imports: [CommonModule, SharedModule, AdminRoutingModule, SharedAdminModule, A11yModule],
}) })
export class AdminModule {} export class AdminModule {}

View File

@ -8,6 +8,7 @@
#redactionAddEditEntity #redactionAddEditEntity
[dossierTemplateId]="dossierTemplateId" [dossierTemplateId]="dossierTemplateId"
[entity]="null" [entity]="null"
[readOnly]="false"
></redaction-add-edit-entity> ></redaction-add-edit-entity>
</div> </div>

View File

@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, Inject, Injector, ViewChild } from
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { AddEditEntityComponent } from '../../shared/components/add-edit-entity/add-edit-entity.component'; import { AddEditEntityComponent } from '../../../shared/components/add-edit-entity/add-edit-entity.component';
import { BaseDialogComponent } from '@iqser/common-ui'; import { BaseDialogComponent } from '@iqser/common-ui';
interface DialogData { interface DialogData {

View File

@ -10,7 +10,11 @@
</div> </div>
<div class="dialog-content"> <div class="dialog-content">
<redaction-add-edit-entity [dossierTemplateId]="dossierTemplateId" [entity]="entity$ | async"></redaction-add-edit-entity> <redaction-add-edit-entity
[dossierTemplateId]="dossierTemplateId"
[entity]="entity$ | async"
[readOnly]="!permissionsService.canEditEntities()"
></redaction-add-edit-entity>
</div> </div>
<div *ngIf="permissionsService.canEditEntities()" class="dialog-actions"> <div *ngIf="permissionsService.canEditEntities()" class="dialog-actions">

View File

@ -4,7 +4,7 @@ import { DictionariesMapService } from '@services/entity-services/dictionaries-m
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { UserService } from '@services/user.service'; import { UserService } from '@services/user.service';
import { PermissionsService } from '@services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { AddEditEntityComponent } from '../../../../shared/components/add-edit-entity/add-edit-entity.component'; import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component';
import { IqserEventTarget } from '@iqser/common-ui'; import { IqserEventTarget } from '@iqser/common-ui';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';

View File

@ -3,12 +3,11 @@ 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 { ColorPickerModule } from 'ngx-color-picker';
const routes = [{ path: '', component: WatermarkScreenComponent }]; const routes = [{ path: '', component: WatermarkScreenComponent }];
@NgModule({ @NgModule({
declarations: [WatermarkScreenComponent], declarations: [WatermarkScreenComponent],
imports: [RouterModule.forChild(routes), CommonModule, SharedModule, ColorPickerModule], imports: [RouterModule.forChild(routes), CommonModule, SharedModule],
}) })
export class WatermarkModule {} export class WatermarkModule {}

View File

@ -2,17 +2,15 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { SharedModule } from '@shared/shared.module'; import { SharedModule } from '@shared/shared.module';
import { DossierTemplateActionsComponent } from './components/dossier-template-actions/dossier-template-actions.component'; import { DossierTemplateActionsComponent } from './components/dossier-template-actions/dossier-template-actions.component';
import { AddEditEntityComponent } from './components/add-edit-entity/add-edit-entity.component';
import { ColorPickerModule } from 'ngx-color-picker';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
const components = [DossierTemplateActionsComponent, AddEditEntityComponent]; const components = [DossierTemplateActionsComponent];
const modules = [CommonModule, SharedModule]; const modules = [CommonModule, SharedModule];
@NgModule({ @NgModule({
declarations: [...components], declarations: [...components],
exports: [...components, ...modules], exports: [...components, ...modules],
imports: [...modules, RouterModule, ColorPickerModule], imports: [...modules, RouterModule],
}) })
export class SharedAdminModule {} export class SharedAdminModule {}

View File

@ -32,7 +32,6 @@ import { ChangeLegalBasisDialogComponent } from './dialogs/change-legal-basis-di
import { RecategorizeImageDialogComponent } from './dialogs/recategorize-image-dialog/recategorize-image-dialog.component'; import { RecategorizeImageDialogComponent } from './dialogs/recategorize-image-dialog/recategorize-image-dialog.component';
import { HighlightActionDialogComponent } from './dialogs/highlight-action-dialog/highlight-action-dialog.component'; import { HighlightActionDialogComponent } from './dialogs/highlight-action-dialog/highlight-action-dialog.component';
import { FilePreviewDialogService } from './services/file-preview-dialog.service'; import { FilePreviewDialogService } from './services/file-preview-dialog.service';
import { ColorPickerModule } from 'ngx-color-picker';
import { DocumentInfoDialogComponent } from './dialogs/document-info-dialog/document-info-dialog.component'; import { DocumentInfoDialogComponent } from './dialogs/document-info-dialog/document-info-dialog.component';
import { ManualRedactionService } from './services/manual-redaction.service'; import { ManualRedactionService } from './services/manual-redaction.service';
import { AnnotationWrapperComponent } from './components/annotation-wrapper/annotation-wrapper.component'; import { AnnotationWrapperComponent } from './components/annotation-wrapper/annotation-wrapper.component';
@ -94,7 +93,6 @@ const components = [
IqserIconsModule, IqserIconsModule,
TranslateModule, TranslateModule,
OverlayModule, OverlayModule,
ColorPickerModule,
], ],
providers: [FilePreviewDialogService, ManualRedactionService, DocumentUnloadedGuard], providers: [FilePreviewDialogService, ManualRedactionService, DocumentUnloadedGuard],
}) })

View File

@ -0,0 +1,22 @@
<section class="dialog">
<div class="dialog-header heading-l">{{ 'dictionary-details.title' | translate }}</div>
<div class="dialog-content">
<redaction-add-edit-entity
[dossierId]="data.dossierId"
[dossierTemplateId]="data.dictionary.dossierTemplateId"
[entity]="data.dictionary"
[readOnly]="data.readOnly"
></redaction-add-edit-entity>
</div>
<div class="dialog-actions">
<button (click)="save()" [disabled]="disabled" color="primary" mat-flat-button>
{{ 'dictionary-details.actions.save' | translate }}
</button>
<div (click)="close()" class="all-caps-label cancel" translate="dictionary-details.actions.cancel"></div>
</div>
<iqser-circle-button (action)="close()" class="dialog-close" icon="iqser:close"></iqser-circle-button>
</section>

View File

@ -0,0 +1,41 @@
import { Component, Inject, Injector, ViewChild } from '@angular/core';
import { BaseDialogComponent } from '@iqser/common-ui';
import { dossiersServiceProvider } from '@services/entity-services/dossiers.service.provider';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Dictionary } from '@red/domain';
import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component';
@Component({
templateUrl: './dictionary-details-dialog.component.html',
styleUrls: ['./dictionary-details-dialog.component.scss'],
providers: [dossiersServiceProvider],
})
export class DictionaryDetailsDialogComponent extends BaseDialogComponent {
@ViewChild(AddEditEntityComponent, { static: true }) private readonly _addEditEntityComponent: AddEditEntityComponent;
constructor(
@Inject(MAT_DIALOG_DATA)
readonly data: { dictionary: Dictionary; dossierId: string; readOnly: boolean },
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<DictionaryDetailsDialogComponent>,
) {
super(_injector, _dialogRef, true);
}
get valid(): boolean {
return this._addEditEntityComponent.valid;
}
get changed(): boolean {
return this._addEditEntityComponent.changed;
}
get disabled(): boolean {
return this._addEditEntityComponent.disabled;
}
async save(): Promise<void> {
await this._addEditEntityComponent.save();
this._dialogRef.close(true);
}
}

View File

@ -9,28 +9,18 @@
</div> </div>
</div> </div>
</div> </div>
<form *ngIf="form" [formGroup]="form">
<div class="iqser-input-group">
<mat-checkbox color="primary" formControlName="addToDictionaryAction" name="addToDictionaryAction">
{{ 'edit-dossier-dialog.dictionary.add-to-dictionary-action' | translate }}
</mat-checkbox>
</div>
</form>
</div> </div>
<div *ngIf="canEditDisplayName" class="display-name"> <div>
<div translate="edit-dossier-dialog.dictionary.display-name.edit"></div> <iqser-circle-button
<iqser-editable-input (action)="openEditDetailsDialog()"
(save)="updateDisplayName($event)" [icon]="canEditProperties ? 'iqser:edit' : 'red:info'"
[buttonsType]="circleButtonTypes.default" [tooltip]="
[cancelTooltip]="'edit-dossier-dialog.dictionary.display-name.cancel' | translate" canEditProperties
[class]="'w-250 ml-16'" ? ('edit-dossier-dialog.dictionary.edit' | translate)
[placeholder]="'edit-dossier-dialog.dictionary.display-name.placeholder' | translate" : ('edit-dossier-dialog.dictionary.info' | translate)
[saveTooltip]="'edit-dossier-dialog.dictionary.display-name.save' | translate" "
[showPreview]="false" ></iqser-circle-button>
[value]="dossierDictionary?.label"
></iqser-editable-input>
</div> </div>
</div> </div>

View File

@ -1,14 +1,12 @@
import { Component, Input, OnInit, ViewChild } from '@angular/core'; import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { Dictionary, Dossier, IDictionary } from '@red/domain'; import { Dictionary, Dossier } from '@red/domain';
import { EditDossierSaveResult, EditDossierSectionInterface } from '../edit-dossier-section.interface'; import { EditDossierSaveResult, EditDossierSectionInterface } from '../edit-dossier-section.interface';
import { PermissionsService } from '@services/permissions.service'; import { PermissionsService } from '@services/permissions.service';
import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component'; import { DictionaryManagerComponent } from '@shared/components/dictionary-manager/dictionary-manager.component';
import { DictionaryService } from '@services/entity-services/dictionary.service'; import { DictionaryService } from '@services/entity-services/dictionary.service';
import { CircleButtonTypes, LoadingService, Toaster } from '@iqser/common-ui'; import { CircleButtonTypes, LoadingService } from '@iqser/common-ui';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
import { DossiersService } from '@services/dossiers/dossiers.service'; import { DossiersDialogService } from '../../../services/dossiers-dialog.service';
@Component({ @Component({
selector: 'redaction-edit-dossier-dictionary', selector: 'redaction-edit-dossier-dictionary',
@ -18,33 +16,22 @@ import { DossiersService } from '@services/dossiers/dossiers.service';
export class EditDossierDictionaryComponent implements EditDossierSectionInterface, OnInit { export class EditDossierDictionaryComponent implements EditDossierSectionInterface, OnInit {
@Input() dossier: Dossier; @Input() dossier: Dossier;
form: UntypedFormGroup;
canEdit = false; canEdit = false;
canEditDisplayName = false; canEditProperties = false;
dossierDictionary: Dictionary; dossierDictionary: Dictionary;
readonly circleButtonTypes = CircleButtonTypes; readonly circleButtonTypes = CircleButtonTypes;
@ViewChild(DictionaryManagerComponent, { static: false }) private readonly _dictionaryManager: DictionaryManagerComponent; @ViewChild(DictionaryManagerComponent, { static: false }) private readonly _dictionaryManager: DictionaryManagerComponent;
constructor( constructor(
private readonly _dossiersService: DossiersService,
private readonly _dictionaryService: DictionaryService, private readonly _dictionaryService: DictionaryService,
private readonly _permissionsService: PermissionsService, private readonly _permissionsService: PermissionsService,
private readonly _loadingService: LoadingService, private readonly _loadingService: LoadingService,
private readonly _formBuilder: UntypedFormBuilder, private readonly _dialogService: DossiersDialogService,
private readonly _toaster: Toaster,
) {} ) {}
get formChanged() {
if (this.form) {
return this.form.get('addToDictionaryAction').value !== this.dossierDictionary.addToDictionaryAction;
}
return false;
}
get changed(): boolean { get changed(): boolean {
return this._dictionaryManager.editor.hasChanges || this.formChanged; return this._dictionaryManager.editor.hasChanges;
} }
get disabled(): boolean { get disabled(): boolean {
@ -52,52 +39,25 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
} }
get valid(): boolean { get valid(): boolean {
return this._dictionaryManager.editor.hasChanges || this.formChanged; return this._dictionaryManager.editor.hasChanges;
} }
async ngOnInit() { async ngOnInit() {
this._loadingService.start(); this._loadingService.start();
this.canEdit = this._permissionsService.canEditDossierDictionary(this.dossier); this.canEdit = this._permissionsService.canEditDossierDictionary(this.dossier);
this.canEditDisplayName = this._permissionsService.canEditDossierDictionaryDisplayName(this.dossier); this.canEditProperties = this._permissionsService.canEditDossierDictionaryProperties(this.dossier);
await this._updateDossierDictionary(); await this._updateDossierDictionary();
this.form = this._getForm();
this._loadingService.stop();
}
async updateDisplayName(label: string) {
try {
this._loadingService.start();
// TODO: Setting the type manually shouldn't be necessary, but for now it fails with status code 500...
const dictionary: IDictionary = { ...this.dossierDictionary, type: 'dossier_redaction', label };
await firstValueFrom(
this._dictionaryService.updateDictionary(dictionary, this.dossier.dossierTemplateId, 'dossier_redaction', this.dossier.id),
);
await this._updateDossierDictionary();
this._toaster.success(_('edit-dossier-dialog.dictionary.display-name.success'));
} catch (error) {
this._toaster.error(_('edit-dossier-dialog.dictionary.display-name.error'));
}
this._loadingService.stop(); this._loadingService.stop();
} }
async save(): EditDossierSaveResult { async save(): EditDossierSaveResult {
try { try {
const dictionary: IDictionary = {
...this.dossierDictionary,
type: 'dossier_redaction',
hasDictionary: true,
addToDictionaryAction: this.form.get('addToDictionaryAction').value,
};
await firstValueFrom(
this._dictionaryService.updateDictionary(dictionary, this.dossier.dossierTemplateId, 'dossier_redaction', this.dossier.id),
);
await firstValueFrom( await firstValueFrom(
this._dictionaryService.saveEntries( this._dictionaryService.saveEntries(
this._dictionaryManager.editor.currentEntries, this._dictionaryManager.editor.currentEntries,
this._dictionaryManager.initialEntries, this._dictionaryManager.initialEntries,
this.dossier.dossierTemplateId, this.dossier.dossierTemplateId,
'dossier_redaction', this.dossierDictionary.type,
this.dossier.id, this.dossier.id,
false, false,
), ),
@ -112,19 +72,12 @@ export class EditDossierDictionaryComponent implements EditDossierSectionInterfa
revert() { revert() {
this._dictionaryManager.revert(); this._dictionaryManager.revert();
this.form.reset({
addToDictionaryAction: this.dossierDictionary.addToDictionaryAction,
});
} }
private _getForm(): UntypedFormGroup { openEditDetailsDialog(): void {
return this._formBuilder.group({ const data = { dictionary: this.dossierDictionary, dossierId: this.dossier.id, readOnly: !this.canEditProperties };
addToDictionaryAction: [ this._dialogService.openDialog('editDictionaryDetails', null, data, async () => {
{ await this._updateDossierDictionary();
value: this.dossierDictionary.addToDictionaryAction,
disabled: !this._permissionsService.canEditDossierDictionaryAddAction(this.dossier),
},
],
}); });
} }

View File

@ -4,8 +4,9 @@ import { EditDossierDialogComponent } from '../dialogs/edit-dossier-dialog/edit-
import { AssignReviewerApproverDialogComponent } from '../dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component'; import { AssignReviewerApproverDialogComponent } from '../dialogs/assign-reviewer-approver-dialog/assign-reviewer-approver-dialog.component';
import { ConfirmationDialogComponent, DialogConfig, DialogService, largeDialogConfig } from '@iqser/common-ui'; import { ConfirmationDialogComponent, DialogConfig, DialogService, largeDialogConfig } from '@iqser/common-ui';
import { ImportRedactionsDialogComponent } from '../../file-preview/dialogs/import-redactions-dialog/import-redactions-dialog'; import { ImportRedactionsDialogComponent } from '../../file-preview/dialogs/import-redactions-dialog/import-redactions-dialog';
import { DictionaryDetailsDialogComponent } from '../dialogs/edit-dossier-dialog/dictionary/dictionary-details-dialog/dictionary-details-dialog.component';
type DialogType = 'confirm' | 'editDossier' | 'assignFile' | 'importRedactions'; type DialogType = 'confirm' | 'editDossier' | 'assignFile' | 'importRedactions' | 'editDictionaryDetails';
@Injectable() @Injectable()
export class DossiersDialogService extends DialogService<DialogType> { export class DossiersDialogService extends DialogService<DialogType> {
@ -26,6 +27,10 @@ export class DossiersDialogService extends DialogService<DialogType> {
component: ImportRedactionsDialogComponent, component: ImportRedactionsDialogComponent,
dialogConfig: { disableClose: false }, dialogConfig: { disableClose: false },
}, },
editDictionaryDetails: {
component: DictionaryDetailsDialogComponent,
dialogConfig: { disableClose: false },
},
}; };
constructor(protected readonly _dialog: MatDialog) { constructor(protected readonly _dialog: MatDialog) {

View File

@ -12,6 +12,7 @@ import { EditDossierAttributesComponent } from './dialogs/edit-dossier-dialog/at
import { EditDossierTeamComponent } from './dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component'; import { EditDossierTeamComponent } from './dialogs/edit-dossier-dialog/edit-dossier-team/edit-dossier-team.component';
import { DateColumnComponent } from './components/date-column/date-column.component'; import { DateColumnComponent } from './components/date-column/date-column.component';
import { FileAssignService } from './services/file-assign.service'; import { FileAssignService } from './services/file-assign.service';
import { DictionaryDetailsDialogComponent } from './dialogs/edit-dossier-dialog/dictionary/dictionary-details-dialog/dictionary-details-dialog.component';
const components = [ const components = [
FileActionsComponent, FileActionsComponent,
@ -23,7 +24,7 @@ const components = [
FileActionsComponent, FileActionsComponent,
DateColumnComponent, DateColumnComponent,
]; ];
const dialogs = [EditDossierDialogComponent, AssignReviewerApproverDialogComponent]; const dialogs = [EditDossierDialogComponent, AssignReviewerApproverDialogComponent, DictionaryDetailsDialogComponent];
const services = [DossiersDialogService, FileAssignService]; const services = [DossiersDialogService, FileAssignService];
@NgModule({ @NgModule({

View File

@ -5,7 +5,7 @@
<input [placeholder]="'add-edit-entity.form.name-placeholder' | translate" formControlName="label" name="label" type="text" /> <input [placeholder]="'add-edit-entity.form.name-placeholder' | translate" formControlName="label" name="label" type="text" />
</div> </div>
<div class="iqser-input-group required w-75"> <div *ngIf="form.get('rank')" class="iqser-input-group required w-75">
<label translate="add-edit-entity.form.rank"></label> <label translate="add-edit-entity.form.rank"></label>
<input [placeholder]="'add-edit-entity.form.rank-placeholder' | translate" formControlName="rank" name="rank" type="number" /> <input [placeholder]="'add-edit-entity.form.rank-placeholder' | translate" formControlName="rank" name="rank" type="number" />
</div> </div>
@ -34,7 +34,7 @@
</div> </div>
</div> </div>
<div class="iqser-input-group mb-14"> <div *ngIf="form.get('type')" class="iqser-input-group mb-14">
<label translate="add-edit-entity.form.technical-name"></label> <label translate="add-edit-entity.form.technical-name"></label>
<div class="technical-name">{{ this.form.get('type').value || '-' }}</div> <div class="technical-name">{{ this.form.get('type').value || '-' }}</div>
<span <span
@ -44,7 +44,7 @@
></span> ></span>
</div> </div>
<div class="iqser-input-group slider-row"> <div *ngIf="form.get('hint')" class="iqser-input-group slider-row">
<mat-button-toggle-group appearance="legacy" formControlName="hint" name="hint"> <mat-button-toggle-group appearance="legacy" formControlName="hint" name="hint">
<mat-button-toggle [value]="false"> <mat-button-toggle [value]="false">
{{ 'add-edit-entity.form.redaction' | translate }} {{ 'add-edit-entity.form.redaction' | translate }}
@ -63,7 +63,7 @@
></mat-select> ></mat-select>
</div> </div>
<div class="iqser-input-group w-400"> <div *ngIf="form.get('description')" class="iqser-input-group w-400">
<label translate="add-edit-entity.form.description"></label> <label translate="add-edit-entity.form.description"></label>
<textarea <textarea
[placeholder]="'add-edit-entity.form.description-placeholder' | translate" [placeholder]="'add-edit-entity.form.description-placeholder' | translate"
@ -75,7 +75,7 @@
></textarea> ></textarea>
</div> </div>
<div class="iqser-input-group"> <div *ngIf="form.get('hasDictionary')" class="iqser-input-group">
<mat-slide-toggle color="primary" formControlName="hasDictionary"> <mat-slide-toggle color="primary" formControlName="hasDictionary">
{{ 'add-edit-entity.form.has-dictionary' | translate }} {{ 'add-edit-entity.form.has-dictionary' | translate }}
</mat-slide-toggle> </mat-slide-toggle>

View File

@ -13,7 +13,7 @@ import { BaseFormComponent, LoadingService, Toaster } from '@iqser/common-ui';
const REDACTION_FIELDS = ['defaultReason']; const REDACTION_FIELDS = ['defaultReason'];
@Component({ @Component({
selector: 'redaction-add-edit-entity [entity] [dossierTemplateId]', selector: 'redaction-add-edit-entity [entity] [dossierTemplateId] [readOnly]',
templateUrl: './add-edit-entity.component.html', templateUrl: './add-edit-entity.component.html',
styleUrls: ['./add-edit-entity.component.scss'], styleUrls: ['./add-edit-entity.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
@ -21,6 +21,8 @@ const REDACTION_FIELDS = ['defaultReason'];
export class AddEditEntityComponent extends BaseFormComponent implements OnInit { export class AddEditEntityComponent extends BaseFormComponent implements OnInit {
@Input() dossierTemplateId: string; @Input() dossierTemplateId: string;
@Input() entity: Dictionary; @Input() entity: Dictionary;
@Input() readOnly: boolean;
@Input() dossierId?: string;
technicalName$: Observable<string>; technicalName$: Observable<string>;
@ -44,16 +46,20 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
super(); super();
} }
get #isDossierRedaction(): boolean {
return this.entity?.type === 'dossier_redaction';
}
get #isSystemManaged(): boolean { get #isSystemManaged(): boolean {
return !!this.entity?.systemManaged; return !!this.entity?.systemManaged;
} }
get #addToDictionaryActionControl() { get #addToDictionaryActionControl() {
return { value: !!this.entity?.addToDictionaryAction, disabled: this.#isSystemManaged }; return { value: !!this.entity?.addToDictionaryAction, disabled: this.#isSystemManaged && !this.#isDossierRedaction };
} }
get #isHint(): boolean { get #isHint(): boolean {
return this.form.get('hint').value; return !!this.form.get('hint')?.value;
} }
revert(): void { revert(): void {
@ -71,7 +77,10 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
try { try {
if (this.entity) { if (this.entity) {
// edit mode // edit mode
await firstValueFrom(this._dictionaryService.updateDictionary(dictionary, this.dossierTemplateId, dictionary.type)); console.log({ dossierId: this.dossierId });
await firstValueFrom(
this._dictionaryService.updateDictionary(dictionary, this.dossierTemplateId, dictionary.type, this.dossierId),
);
this._toaster.success(_('add-edit-entity.success.edit')); this._toaster.success(_('add-edit-entity.success.edit'));
} else { } else {
// create mode // create mode
@ -114,20 +123,26 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
} }
private _initializeForm(): void { private _initializeForm(): void {
const controlsConfig = { let controlsConfig: Record<string, any> = {
type: [this.entity?.type],
label: [this.entity?.label, [Validators.required, Validators.minLength(3)]], label: [this.entity?.label, [Validators.required, Validators.minLength(3)]],
description: [this.entity?.description],
rank: [{ value: this.entity?.rank, disabled: this.#isSystemManaged }, Validators.required],
hexColor: [this.entity?.hexColor, [Validators.required, Validators.minLength(7)]], hexColor: [this.entity?.hexColor, [Validators.required, Validators.minLength(7)]],
recommendationHexColor: [this.entity?.recommendationHexColor, [Validators.required, Validators.minLength(7)]], recommendationHexColor: [this.entity?.recommendationHexColor, [Validators.required, Validators.minLength(7)]],
skippedHexColor: [this.entity?.skippedHexColor, [Validators.required, Validators.minLength(7)]], skippedHexColor: [this.entity?.skippedHexColor, [Validators.required, Validators.minLength(7)]],
hint: [{ value: !!this.entity?.hint, disabled: this.#isSystemManaged }],
hasDictionary: [{ value: !!this.entity?.hasDictionary, disabled: this.#isSystemManaged }],
caseSensitive: [{ value: this.entity ? !this.entity.caseInsensitive : false, disabled: this.#isSystemManaged }],
}; };
if (!this.entity?.hint) { if (!this.#isDossierRedaction) {
controlsConfig = {
...controlsConfig,
type: [this.entity?.type],
description: [this.entity?.description],
rank: [{ value: this.entity?.rank, disabled: this.#isSystemManaged }, Validators.required],
hint: [{ value: !!this.entity?.hint, disabled: this.#isSystemManaged }],
hasDictionary: [{ value: !!this.entity?.hasDictionary, disabled: this.#isSystemManaged }],
caseSensitive: [{ value: this.entity ? !this.entity.caseInsensitive : false, disabled: this.#isSystemManaged }],
};
}
if (!this.entity?.hint && !this.#isDossierRedaction) {
Object.assign(controlsConfig, { Object.assign(controlsConfig, {
defaultReason: [{ value: null, disabled: true }], defaultReason: [{ value: null, disabled: true }],
}); });
@ -144,29 +159,31 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
this.#initializeColors(form); this.#initializeColors(form);
this.technicalName$ = form.get('label').valueChanges.pipe(map((value: string) => this._toTechnicalName(value))); this.technicalName$ = form.get('label').valueChanges.pipe(map((value: string) => this._toTechnicalName(value)));
form.get('hint').valueChanges.subscribe(isHint => { if (!this.#isDossierRedaction) {
if (isHint) { form.get('hint').valueChanges.subscribe(isHint => {
REDACTION_FIELDS.forEach(field => form.removeControl(field)); if (isHint) {
} else { REDACTION_FIELDS.forEach(field => form.removeControl(field));
form.addControl('defaultReason', new UntypedFormControl({ value: null, disabled: true })); } else {
} form.addControl('defaultReason', new UntypedFormControl({ value: null, disabled: true }));
}); }
form.get('hasDictionary').valueChanges.subscribe(hasDictionary => {
if (hasDictionary) {
form.addControl('addToDictionaryAction', new UntypedFormControl(this.#addToDictionaryActionControl));
} else {
form.removeControl('addToDictionaryAction');
}
});
if (!this.entity) {
form.get('label').valueChanges.subscribe((label: string) => {
form.get('type').setValue(this._toTechnicalName(label));
}); });
form.get('hasDictionary').valueChanges.subscribe(hasDictionary => {
if (hasDictionary) {
form.addControl('addToDictionaryAction', new UntypedFormControl(this.#addToDictionaryActionControl));
} else {
form.removeControl('addToDictionaryAction');
}
});
if (!this.entity) {
form.get('label').valueChanges.subscribe((label: string) => {
form.get('type').setValue(this._toTechnicalName(label));
});
}
} }
if (!this._permissionsService.canEditEntities()) { if (this.readOnly) {
form.disable(); form.disable();
} }
@ -198,19 +215,28 @@ export class AddEditEntityComponent extends BaseFormComponent implements OnInit
const addToDictionaryAction = !!this.form.get('addToDictionaryAction')?.value; const addToDictionaryAction = !!this.form.get('addToDictionaryAction')?.value;
const hasDictionary = !!this.form.get('hasDictionary')?.value; const hasDictionary = !!this.form.get('hasDictionary')?.value;
return { let entity = {
type: this.form.get('type').value, ...this.entity,
label: this.form.get('label').value, label: this.form.get('label').value,
description: this.form.get('description').value,
hexColor: this.form.get('hexColor').value, hexColor: this.form.get('hexColor').value,
recommendationHexColor: this.form.get('recommendationHexColor').value, recommendationHexColor: this.form.get('recommendationHexColor').value,
skippedHexColor: this.form.get('skippedHexColor').value, skippedHexColor: this.form.get('skippedHexColor').value,
hint: this.#isHint,
rank: this.form.get('rank').value,
dossierTemplateId: this.dossierTemplateId, dossierTemplateId: this.dossierTemplateId,
caseInsensitive: !this.form.get('caseSensitive').value,
addToDictionaryAction, addToDictionaryAction,
hasDictionary,
}; };
if (this.entity.type !== 'dossier_redaction') {
entity = {
...entity,
type: this.form.get('type').value,
description: this.form.get('description').value,
hint: this.#isHint,
rank: this.form.get('rank').value,
caseInsensitive: !this.form.get('caseSensitive').value,
hasDictionary,
};
}
return entity;
} }
} }

View File

@ -36,6 +36,8 @@ import { RouterModule } from '@angular/router';
import { AddDossierDialogComponent } from '@shared/dialogs/add-dossier-dialog/add-dossier-dialog.component'; import { AddDossierDialogComponent } from '@shared/dialogs/add-dossier-dialog/add-dossier-dialog.component';
import { SharedDialogService } from '@shared/services/dialog.service'; import { SharedDialogService } from '@shared/services/dialog.service';
import { DossierWatermarkSelectorComponent } from '@components/dossier-watermark-selector/dossier-watermark-selector.component'; import { DossierWatermarkSelectorComponent } from '@components/dossier-watermark-selector/dossier-watermark-selector.component';
import { AddEditEntityComponent } from '@shared/components/add-edit-entity/add-edit-entity.component';
import { ColorPickerModule } from 'ngx-color-picker';
const buttons = [FileDownloadBtnComponent, UserButtonComponent]; const buttons = [FileDownloadBtnComponent, UserButtonComponent];
@ -59,6 +61,8 @@ const components = [
DossiersTypeSwitchComponent, DossiersTypeSwitchComponent,
AddDossierDialogComponent, AddDossierDialogComponent,
DossierWatermarkSelectorComponent, DossierWatermarkSelectorComponent,
AddEditEntityComponent,
...buttons, ...buttons,
]; ];
@ -66,7 +70,7 @@ const utils = [DatePipe, NamePipe, NavigateLastDossiersScreenDirective, LongPres
const services = [SharedDialogService]; const services = [SharedDialogService];
const modules = [MatConfigModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule, CommonUiModule]; const modules = [MatConfigModule, ScrollingModule, IconsModule, FormsModule, ReactiveFormsModule, CommonUiModule, ColorPickerModule];
@NgModule({ @NgModule({
declarations: [...components, ...utils, EditorComponent], declarations: [...components, ...utils, EditorComponent],

View File

@ -1,6 +1,6 @@
import { Injectable, Injector } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
import { firstValueFrom, forkJoin, Observable, of, throwError } from 'rxjs'; import { firstValueFrom, forkJoin, Observable, of, throwError } from 'rxjs';
import { EntitiesService, List, log, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui'; import { EntitiesService, List, QueryParam, RequiredParam, Toaster, Validate } from '@iqser/common-ui';
import { Dictionary, DictionaryEntryType, DictionaryEntryTypes, IColors, IDictionary, IUpdateDictionary } from '@red/domain'; import { Dictionary, DictionaryEntryType, DictionaryEntryTypes, IColors, IDictionary, IUpdateDictionary } from '@red/domain';
import { catchError, map, switchMap, tap } from 'rxjs/operators'; import { catchError, map, switchMap, tap } from 'rxjs/operators';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
@ -170,11 +170,10 @@ export class DictionaryService extends EntitiesService<Dictionary, IDictionary>
}, },
), ),
); );
} else {
this._toaster.error(_('dictionary-overview.error.entries-too-short'));
return throwError('Entries too short');
} }
this._toaster.error(_('dictionary-overview.error.entries-too-short'));
return throwError('Entries too short');
} }
async getDictionariesOptions(dossierTemplateId: string, dossierId: string): Promise<Dictionary[]> { async getDictionariesOptions(dossierTemplateId: string, dossierId: string): Promise<Dictionary[]> {

View File

@ -221,11 +221,7 @@ export class PermissionsService {
return dossier.isActive && this.isDossierMember(dossier); return dossier.isActive && this.isDossierMember(dossier);
} }
canEditDossierDictionaryDisplayName(dossier: Dossier): boolean { canEditDossierDictionaryProperties(dossier: Dossier): boolean {
return dossier.isActive && this.isOwner(dossier);
}
canEditDossierDictionaryAddAction(dossier: Dossier): boolean {
return dossier.isActive && this.isOwner(dossier); return dossier.isActive && this.isOwner(dossier);
} }

View File

@ -618,6 +618,13 @@
}, },
"dev-mode": "DEV", "dev-mode": "DEV",
"dictionary": "Wörterbuch", "dictionary": "Wörterbuch",
"dictionary-details": {
"actions": {
"cancel": "",
"save": ""
},
"title": ""
},
"dictionary-overview": { "dictionary-overview": {
"compare": { "compare": {
"compare": "Vergleichen", "compare": "Vergleichen",
@ -1061,16 +1068,13 @@
"change-successful": "Dossier wurde aktualisiert.", "change-successful": "Dossier wurde aktualisiert.",
"delete-successful": "Dossier wurde gelöscht.", "delete-successful": "Dossier wurde gelöscht.",
"dictionary": { "dictionary": {
"add-to-dictionary-action": "",
"display-name": { "display-name": {
"cancel": "Abbrechen",
"edit": "Anzeigenamen bearbeiten",
"error": "Anzeigename des Wörterbuchs konnte nicht aktualisiert werden.", "error": "Anzeigename des Wörterbuchs konnte nicht aktualisiert werden.",
"placeholder": "Anzeigenamen eingeben",
"save": "Anzeigenamen speichern",
"success": "Anzeigename des Wörterbuchs erfolgreich aktualisiert." "success": "Anzeigename des Wörterbuchs erfolgreich aktualisiert."
}, },
"entries": "{length} {length, plural, one{entry} other{entries}}" "edit": "",
"entries": "{length} {length, plural, one{entry} other{entries}}",
"info": ""
}, },
"general-info": { "general-info": {
"form": { "form": {

View File

@ -618,6 +618,13 @@
}, },
"dev-mode": "DEV", "dev-mode": "DEV",
"dictionary": "Dictionary", "dictionary": "Dictionary",
"dictionary-details": {
"actions": {
"cancel": "Cancel",
"save": "Save"
},
"title": "Edit Dossier Dictionary"
},
"dictionary-overview": { "dictionary-overview": {
"compare": { "compare": {
"compare": "Compare", "compare": "Compare",
@ -1061,16 +1068,13 @@
"change-successful": "Dossier {dossierName} was updated.", "change-successful": "Dossier {dossierName} was updated.",
"delete-successful": "Dossier {dossierName} was deleted.", "delete-successful": "Dossier {dossierName} was deleted.",
"dictionary": { "dictionary": {
"add-to-dictionary-action": "Enable 'Add to dictionary'",
"display-name": { "display-name": {
"cancel": "Cancel",
"edit": "Edit Display Name",
"error": "Failed to update dictionary display name.", "error": "Failed to update dictionary display name.",
"placeholder": "Enter Display Name",
"save": "Save Display Name",
"success": "Successfully updated dictionary display name." "success": "Successfully updated dictionary display name."
}, },
"entries": "{length} {length, plural, one{entry} other{entries}}" "edit": "Edit",
"entries": "{length} {length, plural, one{entry} other{entries}}",
"info": "Info"
}, },
"general-info": { "general-info": {
"form": { "form": {

@ -1 +1 @@
Subproject commit 17fc935e0815f0d151a2674e7b4c77886319da71 Subproject commit 738c38cf5f13de9542facd84d8c70f9929b980e6