Pull request #325: VM/RED-2614

Merge in RED/ui from VM/RED-2614 to master

* commit '920be9e4bf537276b1f6ceb25883ec75b82c5395':
  added warn box for all needed dialogs
  extended base dialog for 'recategorize image dialog' component and 'resize annotation dialog' compoenent
  extended base dialog for 'document info dialog' component and 'force annotation dialog' compoenent
  extended base dialog for 'change legal basis dialog' component
  extended base dialog for 'manual annotation dialog' component
  extended base dialog for 'add dossier' component
  moved 'base-dialog component' and 'confirmation-dialog service' in common
  stored initial form as a simple object instead of a form
  changed 'click' to 'action'
  removed commented code, updated 'close' and 'changeTab' methods
  updated general logic for 'valid' and 'changed' methods to be used by more classes that inherit BaseDialog
  updated base dialog component to display the confirmation dialog whenever the user wants to leave the modal or change its tab with unsaved changes
  WIP on warning the user before leaving the page with unsaved changes
This commit is contained in:
Valentin-Gabriel Mihai 2022-01-19 08:09:20 +01:00 committed by Timo Bejan
commit ee2638e0be
32 changed files with 237 additions and 260 deletions

View File

@ -95,11 +95,11 @@
</div>
<div class="dialog-actions">
<button (click)="save()" [disabled]="!valid || !changed" color="primary" mat-flat-button>
<button (click)="save()" [disabled]="disabled" color="primary" mat-flat-button>
{{ 'add-edit-dictionary.save' | translate }}
</button>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { ChangeDetectionStrategy, Component, Inject, Injector } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Observable } from 'rxjs';
@ -21,7 +21,6 @@ import { HttpStatusCode } from '@angular/common/http';
})
export class AddEditDictionaryDialogComponent extends BaseDialogComponent {
readonly dictionary = this._data.dictionary;
readonly form: FormGroup = this._getForm(this.dictionary);
readonly canEditLabel$ = this._canEditLabel$;
readonly technicalName$: Observable<string>;
readonly dialogHeader = this._translateService.instant('add-edit-dictionary.title', {
@ -29,7 +28,6 @@ export class AddEditDictionaryDialogComponent extends BaseDialogComponent {
name: this._data.dictionary?.label,
});
readonly hasColor$: Observable<boolean>;
readonly disabled = false;
private readonly _dossierTemplateId = this._data.dossierTemplateId;
constructor(
@ -39,37 +37,18 @@ export class AddEditDictionaryDialogComponent extends BaseDialogComponent {
private readonly _appStateService: AppStateService,
private readonly _translateService: TranslateService,
private readonly _dictionaryService: DictionaryService,
private readonly _dialogRef: MatDialogRef<AddEditDictionaryDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<AddEditDictionaryDialogComponent>,
@Inject(MAT_DIALOG_DATA)
private readonly _data: { readonly dictionary: Dictionary; readonly dossierTemplateId: string },
) {
super();
super(_injector, _dialogRef);
this.form = this._getForm(this.dictionary);
this.initialFormValue = this.form.getRawValue();
this.hasColor$ = this._colorEmpty$;
this.technicalName$ = this.form.get('label').valueChanges.pipe(map(value => this._toTechnicalName(value)));
}
get valid(): boolean {
return this.form.valid;
}
get changed(): boolean {
if (!this.dictionary) {
return true;
}
for (const key of Object.keys(this.form.getRawValue())) {
if (key === 'caseSensitive') {
if (this.getDictCaseSensitive(this.dictionary) !== this.form.get(key).value) {
return true;
}
} else if (this.dictionary[key] !== this.form.get(key).value) {
return true;
}
}
return false;
}
private get _canEditLabel$() {
return this.userService.currentUser$.pipe(
map(user => user.isAdmin || !this._data.dictionary),

View File

@ -35,11 +35,11 @@
</div>
</div>
<div class="dialog-actions">
<button (click)="save()" [disabled]="form.invalid || !changed" color="primary" mat-flat-button>
<button (click)="save()" [disabled]="disabled" color="primary" mat-flat-button>
{{ 'add-edit-dossier-attribute.save' | translate }}
</button>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,8 +1,8 @@
import { Component, HostListener, Inject, OnDestroy } from '@angular/core';
import { Component, HostListener, Inject, Injector, OnDestroy } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { DossierAttributeConfigTypes, FileAttributeConfigTypes, IDossierAttributeConfig } from '@red/domain';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AutoUnsubscribe, IqserEventTarget, LoadingService, Toaster } from '@iqser/common-ui';
import { BaseDialogComponent, IqserEventTarget, LoadingService, Toaster } from '@iqser/common-ui';
import { HttpErrorResponse } from '@angular/common/http';
import { DossierAttributesService } from '@shared/services/controller-wrappers/dossier-attributes.service';
import { dossierAttributeTypesTranslations } from '../../translations/dossier-attribute-types-translations';
@ -12,9 +12,8 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
templateUrl: './add-edit-dossier-attribute-dialog.component.html',
styleUrls: ['./add-edit-dossier-attribute-dialog.component.scss'],
})
export class AddEditDossierAttributeDialogComponent extends AutoUnsubscribe implements OnDestroy {
export class AddEditDossierAttributeDialogComponent extends BaseDialogComponent implements OnDestroy {
dossierAttribute: IDossierAttributeConfig = this.data.dossierAttribute;
readonly form: FormGroup = this._getForm(this.dossierAttribute);
readonly translations = dossierAttributeTypesTranslations;
readonly typeOptions = Object.keys(DossierAttributeConfigTypes);
@ -23,11 +22,14 @@ export class AddEditDossierAttributeDialogComponent extends AutoUnsubscribe impl
private readonly _loadingService: LoadingService,
private readonly _dossierAttributesService: DossierAttributesService,
private readonly _toaster: Toaster,
readonly dialogRef: MatDialogRef<AddEditDossierAttributeDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<AddEditDossierAttributeDialogComponent>,
@Inject(MAT_DIALOG_DATA)
readonly data: { readonly dossierAttribute: IDossierAttributeConfig },
) {
super();
super(_injector, _dialogRef);
this.form = this._getForm(this.dossierAttribute);
this.initialFormValue = this.form.getRawValue();
}
get changed(): boolean {
@ -55,7 +57,7 @@ export class AddEditDossierAttributeDialogComponent extends AutoUnsubscribe impl
this._dossierAttributesService.createOrUpdate(attribute).subscribe(
() => {
this.dialogRef.close(true);
this._dialogRef.close(true);
},
(error: HttpErrorResponse) => {
this._loadingService.stop();

View File

@ -33,16 +33,11 @@
<div class="validity">
<div>
<mat-checkbox
(change)="hasValidFrom = !hasValidFrom"
[checked]="hasValidFrom"
class="filter-menu-checkbox"
color="primary"
>
<mat-checkbox (change)="toggleHasValid('from')" [checked]="hasValidFrom" class="filter-menu-checkbox" color="primary">
{{ 'add-edit-dossier-template.form.valid-from' | translate }}
</mat-checkbox>
<mat-checkbox (change)="hasValidTo = !hasValidTo" [checked]="hasValidTo" class="filter-menu-checkbox" color="primary">
<mat-checkbox (change)="toggleHasValid('to')" [checked]="hasValidTo" class="filter-menu-checkbox" color="primary">
{{ 'add-edit-dossier-template.form.valid-to' | translate }}
</mat-checkbox>
</div>
@ -87,11 +82,11 @@
</div>
<div class="dialog-actions">
<button (click)="save()" [disabled]="!valid || !changed" color="primary" mat-flat-button>
<button (click)="save()" [disabled]="disabled" color="primary" mat-flat-button>
{{ 'add-edit-dossier-template.save' | translate }}
</button>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,4 +1,4 @@
import { Component, Inject } from '@angular/core';
import { Component, Inject, Injector } from '@angular/core';
import { AppStateService } from '@state/app-state.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
@ -17,7 +17,6 @@ import { HttpStatusCode } from '@angular/common/http';
styleUrls: ['./add-edit-dossier-template-dialog.component.scss'],
})
export class AddEditDossierTemplateDialogComponent extends BaseDialogComponent {
readonly form: FormGroup = this._getForm();
hasValidFrom: boolean;
hasValidTo: boolean;
downloadTypesEnum: DownloadFileType[] = ['ORIGINAL', 'PREVIEW', 'REDACTED'];
@ -25,65 +24,49 @@ export class AddEditDossierTemplateDialogComponent extends BaseDialogComponent {
key: type,
label: downloadTypesTranslations[type],
}));
readonly disabled = false;
private _previousValidFrom: Moment;
private _previousValidTo: Moment;
private _lastValidFrom: Moment;
private _lastValidTo: Moment;
constructor(
private readonly _appStateService: AppStateService,
private readonly _toaster: Toaster,
private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _formBuilder: FormBuilder,
public dialogRef: MatDialogRef<AddEditDossierTemplateDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<AddEditDossierTemplateDialogComponent>,
@Inject(MAT_DIALOG_DATA) readonly dossierTemplate: IDossierTemplate,
) {
super();
super(_injector, _dialogRef);
this.form = this._getForm();
this.initialFormValue = this.form.getRawValue();
this.hasValidFrom = !!this.dossierTemplate?.validFrom;
this.hasValidTo = !!this.dossierTemplate?.validTo;
this._previousValidFrom = this.form.get('validFrom').value;
this._previousValidTo = this.form.get('validTo').value;
this._previousValidFrom = this._lastValidFrom = this.form.get('validFrom').value;
this._previousValidTo = this._lastValidTo = this.form.get('validTo').value;
this.form.valueChanges.subscribe(value => {
this.addSubscription = this.form.valueChanges.subscribe(value => {
this._applyValidityIntervalConstraints(value);
});
this.addSubscription = this.form.controls['validFrom'].valueChanges.subscribe(value => {
this._lastValidFrom = value ? value : this._lastValidFrom;
});
this.addSubscription = this.form.controls['validTo'].valueChanges.subscribe(value => {
this._lastValidFrom = value ? value : this._lastValidFrom;
});
}
get valid(): boolean {
return this.form.valid;
}
get changed(): boolean {
if (!this.dossierTemplate) {
return true;
toggleHasValid(extremity: string) {
if (extremity === 'from') {
this.hasValidFrom = !this.hasValidFrom;
this.form.controls['validFrom'].setValue(this.hasValidFrom ? this._lastValidFrom : null);
} else {
this.hasValidTo = !this.hasValidTo;
this.form.controls['validTo'].setValue(this.hasValidTo ? this._lastValidTo : null);
}
for (const key of Object.keys(this.form.getRawValue())) {
const formValue = this.form.get(key).value;
const objectValue = this.dossierTemplate[key];
if (key === 'validFrom') {
if (this.hasValidFrom !== !!objectValue || (this.hasValidFrom && !moment(objectValue).isSame(moment(formValue)))) {
return true;
}
} else if (key === 'validTo') {
if (this.hasValidTo !== !!objectValue || (this.hasValidTo && !moment(objectValue).isSame(moment(formValue)))) {
return true;
}
} else if (formValue instanceof Array) {
if (objectValue.length !== formValue.length) {
return true;
}
for (const item of objectValue) {
if (!formValue.includes(item)) {
return true;
}
}
} else if (objectValue !== formValue) {
return true;
}
}
return false;
}
async save() {
@ -97,7 +80,7 @@ export class AddEditDossierTemplateDialogComponent extends BaseDialogComponent {
await this._dossierTemplatesService.createOrUpdate(dossierTemplate).toPromise();
await this._dossierTemplatesService.loadAll().toPromise();
await this._appStateService.loadDictionaryData();
this.dialogRef.close(true);
this._dialogRef.close(true);
} catch (error: any) {
const message =
error.status === HttpStatusCode.Conflict

View File

@ -84,11 +84,11 @@
</div>
</div>
<div class="dialog-actions">
<button (click)="save()" [disabled]="!valid || !changed" color="primary" mat-flat-button>
<button (click)="save()" [disabled]="disabled" color="primary" mat-flat-button>
{{ 'add-edit-file-attribute.save' | translate }}
</button>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,10 +1,10 @@
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { ChangeDetectionStrategy, Component, Inject, Injector } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { FileAttributeConfigTypes, IFileAttributeConfig } from '@red/domain';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { fileAttributeTypesTranslations } from '../../translations/file-attribute-types-translations';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { BaseDialogComponent } from '@iqser/common-ui';
import { BaseDialogComponent } from '../../../../../../../../libs/common-ui/src';
@Component({
selector: 'redaction-add-edit-file-attribute-dialog',
@ -13,12 +13,10 @@ import { BaseDialogComponent } from '@iqser/common-ui';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AddEditFileAttributeDialogComponent extends BaseDialogComponent {
readonly disabled = false;
DISPLAYED_FILTERABLE_LIMIT = 3;
translations = fileAttributeTypesTranslations;
fileAttribute: IFileAttributeConfig = this.data.fileAttribute;
dossierTemplateId: string = this.data.dossierTemplateId;
readonly form!: FormGroup;
readonly typeOptions = Object.keys(FileAttributeConfigTypes);
readonly canSetDisplayed!: boolean;
readonly canSetFilterable!: boolean;
@ -26,7 +24,8 @@ export class AddEditFileAttributeDialogComponent extends BaseDialogComponent {
constructor(
private readonly _formBuilder: FormBuilder,
private readonly _fileAttributesService: FileAttributesService,
public dialogRef: MatDialogRef<AddEditFileAttributeDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<AddEditFileAttributeDialogComponent>,
@Inject(MAT_DIALOG_DATA)
public data: {
fileAttribute: IFileAttributeConfig;
@ -35,32 +34,11 @@ export class AddEditFileAttributeDialogComponent extends BaseDialogComponent {
numberOfFilterableAttrs: number;
},
) {
super();
super(_injector, _dialogRef);
this.canSetDisplayed = data.numberOfDisplayedAttrs < this.DISPLAYED_FILTERABLE_LIMIT || data.fileAttribute?.displayedInFileList;
this.canSetFilterable = data.numberOfFilterableAttrs < this.DISPLAYED_FILTERABLE_LIMIT || data.fileAttribute?.filterable;
this.form = this._getForm(this.fileAttribute);
}
get valid(): boolean {
return this.form.valid;
}
get changed(): boolean {
if (!this.fileAttribute) {
return true;
}
for (const key of Object.keys(this.form.getRawValue())) {
if (key === 'readonly') {
if (this.fileAttribute.editable === this.form.get(key).value) {
return true;
}
} else if (this.fileAttribute[key] !== this.form.get(key).value) {
return true;
}
}
return false;
this.initialFormValue = this.form.getRawValue();
}
save() {
@ -69,7 +47,7 @@ export class AddEditFileAttributeDialogComponent extends BaseDialogComponent {
editable: !this.form.get('readonly').value,
...this.form.getRawValue(),
};
this.dialogRef.close(fileAttribute);
this._dialogRef.close(fileAttribute);
}
private _getForm(fileAttribute: IFileAttributeConfig): FormGroup {

View File

@ -28,11 +28,11 @@
</div>
<div class="dialog-actions">
<button (click)="save()" [disabled]="!valid || !changed" color="primary" mat-flat-button>
<button (click)="save()" [disabled]="disabled" color="primary" mat-flat-button>
{{ 'edit-color-dialog.save' | translate }}
</button>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,4 +1,4 @@
import { Component, Inject } from '@angular/core';
import { Component, Inject, Injector } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { DefaultColorType, IColors } from '@red/domain';
import { BaseDialogComponent, Toaster } from '@iqser/common-ui';
@ -19,10 +19,7 @@ interface IEditColorData {
styleUrls: ['./edit-color-dialog.component.scss'],
})
export class EditColorDialogComponent extends BaseDialogComponent {
readonly form: FormGroup;
translations = defaultColorsTranslations;
readonly disabled = false;
private readonly _initialColor: string;
private readonly _dossierTemplateId: string;
constructor(
@ -30,23 +27,16 @@ export class EditColorDialogComponent extends BaseDialogComponent {
private readonly _dictionaryService: DictionaryService,
private readonly _toaster: Toaster,
private readonly _translateService: TranslateService,
private readonly _dialogRef: MatDialogRef<EditColorDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<EditColorDialogComponent>,
@Inject(MAT_DIALOG_DATA)
readonly data: IEditColorData,
) {
super();
super(_injector, _dialogRef);
this._dossierTemplateId = data.dossierTemplateId;
this._initialColor = data.colors[data.colorKey];
this.form = this._getForm();
}
get changed(): boolean {
return this.form.get('color').value !== this._initialColor;
}
get valid(): boolean {
return this.form.valid;
this.initialFormValue = this.form.getRawValue();
}
async save() {

View File

@ -34,6 +34,7 @@ export class AdminDialogService extends DialogService<DialogType> {
protected readonly _config: DialogConfig<DialogType> = {
confirm: {
component: ConfirmationDialogComponent,
dialogConfig: { disableClose: false },
},
addEditDictionary: {
component: AddEditDictionaryDialogComponent,
@ -49,18 +50,19 @@ export class AdminDialogService extends DialogService<DialogType> {
},
deleteFileAttribute: {
component: ConfirmDeleteFileAttributeDialogComponent,
dialogConfig: { disableClose: false },
},
importFileAttributes: {
component: FileAttributesCsvImportDialogComponent,
dialogConfig: largeDialogConfig,
dialogConfig: { ...largeDialogConfig, ...{ disableClose: false } },
},
deleteUsers: {
component: ConfirmDeleteUsersDialogComponent,
dialogConfig: { autoFocus: true },
dialogConfig: { autoFocus: true, disableClose: false },
},
addEditUser: {
component: AddEditUserDialogComponent,
dialogConfig: { autoFocus: true },
dialogConfig: { autoFocus: true, disableClose: false },
},
smtpAuthConfig: {
component: SmtpAuthDialogComponent,

View File

@ -1,5 +1,5 @@
<section class="dialog">
<form (submit)="saveDossier()" [formGroup]="form">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-header heading-l" translate="add-dossier-dialog.header-new"></div>
<div class="dialog-content">
@ -91,7 +91,7 @@
</button>
<iqser-icon-button
(action)="saveDossier(true)"
(action)="save({ addMembers: true })"
[disabled]="disabled"
[label]="'add-dossier-dialog.actions.save-and-add-members' | translate"
[type]="iconButtonTypes.dark"

View File

@ -1,10 +1,10 @@
import { Component } from '@angular/core';
import { Component, Injector } from '@angular/core';
import { MatDialogRef } from '@angular/material/dialog';
import { DownloadFileType, IDossierRequest, IDossierTemplate, IReportTemplate } from '@red/domain';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import * as moment from 'moment';
import { downloadTypesTranslations } from '../../../../translations/download-types-translations';
import { IconButtonTypes } from '@iqser/common-ui';
import { BaseDialogComponent, IconButtonTypes, SaveOptions } from '@iqser/common-ui';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { DossierTemplatesService } from '@services/entity-services/dossier-templates.service';
import { ReportTemplateService } from '@services/report-template.service';
@ -13,10 +13,9 @@ import { ReportTemplateService } from '@services/report-template.service';
templateUrl: './add-dossier-dialog.component.html',
styleUrls: ['./add-dossier-dialog.component.scss'],
})
export class AddDossierDialogComponent {
export class AddDossierDialogComponent extends BaseDialogComponent {
readonly iconButtonTypes = IconButtonTypes;
readonly form: FormGroup;
hasDueDate = false;
downloadTypes: { key: DownloadFileType; label: string }[] = ['ORIGINAL', 'PREVIEW', 'REDACTED'].map((type: DownloadFileType) => ({
key: type,
@ -30,10 +29,13 @@ export class AddDossierDialogComponent {
private readonly _dossierTemplatesService: DossierTemplatesService,
private readonly _formBuilder: FormBuilder,
private readonly _reportTemplateController: ReportTemplateService,
readonly dialogRef: MatDialogRef<AddDossierDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<AddDossierDialogComponent>,
) {
super(_injector, _dialogRef);
this._getDossierTemplates();
this.form = this._getForm();
this.initialFormValue = this.form.getRawValue();
}
private _getForm(): FormGroup {
@ -75,10 +77,10 @@ export class AddDossierDialogComponent {
reportTemplateValueMapper = (reportTemplate: IReportTemplate) => reportTemplate.templateId;
async saveDossier(addMembers = false) {
async save(options?: SaveOptions) {
const savedDossier = await this._dossiersService.createOrUpdate(this._formToObject()).toPromise();
if (savedDossier) {
this.dialogRef.close({ dossier: savedDossier, addMembers });
this._dialogRef.close({ dossier: savedDossier, addMembers: options?.addMembers });
}
}

View File

@ -38,12 +38,12 @@
</div>
<div class="dialog-actions">
<button [disabled]="!form.valid || !changed" color="primary" mat-flat-button type="submit">
<button [disabled]="disabled" color="primary" mat-flat-button type="submit">
{{ 'change-legal-basis-dialog.actions.save' | translate }}
</button>
<div class="all-caps-label cancel" mat-dialog-close translate="change-legal-basis-dialog.actions.cancel"></div>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,4 +1,4 @@
import { Component, Inject, OnInit } from '@angular/core';
import { Component, Inject, Injector, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@ -6,6 +6,7 @@ import { PermissionsService } from '@services/permissions.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { Dossier } from '@red/domain';
import { BaseDialogComponent } from '@iqser/common-ui';
export interface LegalBasisOption {
label?: string;
@ -16,8 +17,7 @@ export interface LegalBasisOption {
@Component({
templateUrl: './change-legal-basis-dialog.component.html',
})
export class ChangeLegalBasisDialogComponent implements OnInit {
form: FormGroup = this._getForm();
export class ChangeLegalBasisDialogComponent extends BaseDialogComponent implements OnInit {
isDocumentAdmin: boolean;
legalOptions: LegalBasisOption[] = [];
@ -26,16 +26,12 @@ export class ChangeLegalBasisDialogComponent implements OnInit {
private readonly _dossiersService: DossiersService,
private readonly _permissionsService: PermissionsService,
private readonly _formBuilder: FormBuilder,
readonly dialogRef: MatDialogRef<ChangeLegalBasisDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<ChangeLegalBasisDialogComponent>,
@Inject(MAT_DIALOG_DATA) private readonly _data: { annotations: AnnotationWrapper[]; dossier: Dossier },
) {}
get changed(): boolean {
return (
this.form.get('reason').value.legalBasis !== this._data.annotations[0].legalBasis ||
this.form.get('section').value !== this._data.annotations[0].section ||
this.form.get('classification').value !== this._data.annotations[0].value
);
) {
super(_injector, _dialogRef);
this.form = this._getForm();
}
get allRectangles(): boolean {
@ -43,6 +39,7 @@ export class ChangeLegalBasisDialogComponent implements OnInit {
}
async ngOnInit() {
super.ngOnInit();
const data = await this._justificationsService.getForDossierTemplate(this._data.dossier.dossierTemplateId).toPromise();
this.legalOptions = data
@ -56,6 +53,7 @@ export class ChangeLegalBasisDialogComponent implements OnInit {
this.form.patchValue({
reason: this.legalOptions.find(option => option.legalBasis === this._data.annotations[0].legalBasis),
});
this.initialFormValue = this.form.getRawValue();
}
private _getForm(): FormGroup {
@ -69,7 +67,7 @@ export class ChangeLegalBasisDialogComponent implements OnInit {
}
save() {
this.dialogRef.close({
this._dialogRef.close({
legalBasis: this.form.get('reason').value.legalBasis,
section: this.form.get('section').value,
comment: this.form.get('comment').value,

View File

@ -1,7 +1,7 @@
<section *ngIf="!!form" class="dialog">
<div class="dialog-header heading-l" translate="document-info.title"></div>
<form (submit)="saveDocumentInfo()" [formGroup]="form">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">
<div *ngFor="let attr of attributes" class="iqser-input-group w-300">
<label>{{ attr.label }}</label>
@ -9,11 +9,11 @@
</div>
</div>
<div class="dialog-actions">
<button [disabled]="form.invalid" color="primary" mat-flat-button type="submit">
<button [disabled]="disabled" color="primary" mat-flat-button type="submit">
{{ 'document-info.save' | translate }}
</button>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,16 +1,17 @@
import { Component, Inject, OnInit } from '@angular/core';
import { Component, Inject, Injector, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { Dossier, File, IFileAttributeConfig } from '@red/domain';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { FileAttributesService } from '@services/entity-services/file-attributes.service';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { FilesService } from '@services/entity-services/files.service';
import { BaseDialogComponent } from '@iqser/common-ui';
@Component({
templateUrl: './document-info-dialog.component.html',
styleUrls: ['./document-info-dialog.component.scss'],
})
export class DocumentInfoDialogComponent implements OnInit {
export class DocumentInfoDialogComponent extends BaseDialogComponent implements OnInit {
form: FormGroup;
attributes: IFileAttributeConfig[];
@ -21,27 +22,31 @@ export class DocumentInfoDialogComponent implements OnInit {
private readonly _formBuilder: FormBuilder,
private readonly _fileAttributesService: FileAttributesService,
private readonly _filesService: FilesService,
public dialogRef: MatDialogRef<DocumentInfoDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<DocumentInfoDialogComponent>,
@Inject(MAT_DIALOG_DATA) readonly data: File,
) {
super(_injector, _dialogRef);
this._dossier = this._dossiersService.find(this.data.dossierId);
}
async ngOnInit() {
super.ngOnInit();
this.attributes = (
await this._fileAttributesService.getFileAttributesConfig(this._dossier.dossierTemplateId).toPromise()
).fileAttributeConfigs.filter(attr => attr.editable);
this.form = this._getForm();
this.initialFormValue = this.form.getRawValue();
}
async saveDocumentInfo() {
async save() {
const attributeIdToValue = {
...this.data.fileAttributes?.attributeIdToValue,
...this.form.getRawValue(),
};
await this._fileAttributesService.setFileAttributes({ attributeIdToValue }, this.data.dossierId, this.data.fileId).toPromise();
this._filesService.reload(this.data.dossierId, this.data.fileId);
this.dialogRef.close(true);
this._dialogRef.close(true);
}
private _getForm(): FormGroup {

View File

@ -53,7 +53,7 @@
{{ 'edit-dossier-dialog.actions.save' | translate }}
</button>
<iqser-icon-button
(action)="save(true)"
(action)="save({ closeAfterSave: true })"
[disabled]="disabled || !valid || !changed"
[label]="'edit-dossier-dialog.actions.save-and-close' | translate"
[type]="iconButtonTypes.dark"
@ -65,5 +65,5 @@
</div>
</div>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,10 +1,10 @@
import { ChangeDetectorRef, Component, Inject, ViewChild } from '@angular/core';
import { ChangeDetectorRef, Component, Inject, Injector, ViewChild } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Dossier } from '@red/domain';
import { EditDossierGeneralInfoComponent } from './general-info/edit-dossier-general-info.component';
import { EditDossierDownloadPackageComponent } from './download-package/edit-dossier-download-package.component';
import { EditDossierSectionInterface } from './edit-dossier-section.interface';
import { BaseDialogComponent, IconButtonTypes, LoadingService, Toaster } from '@iqser/common-ui';
import { BaseDialogComponent, ConfirmOptions, IconButtonTypes, LoadingService, SaveOptions, Toaster } from '@iqser/common-ui';
import { EditDossierDictionaryComponent } from './dictionary/edit-dossier-dictionary.component';
import { EditDossierAttributesComponent } from './attributes/edit-dossier-attributes.component';
@ -15,6 +15,7 @@ import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { EditDossierTeamComponent } from './edit-dossier-team/edit-dossier-team.component';
import { PermissionsService } from '@services/permissions.service';
import { BaseDialogComponent } from '@shared/dialog/base-dialog.component';
type Section = 'dossierInfo' | 'downloadPackage' | 'dossierDictionary' | 'members' | 'dossierAttributes' | 'deletedDocuments';
@ -40,16 +41,17 @@ export class EditDossierDialogComponent extends BaseDialogComponent {
private readonly _toaster: Toaster,
private readonly _dossiersService: DossiersService,
private readonly _changeRef: ChangeDetectorRef,
private readonly _dialogRef: MatDialogRef<EditDossierDialogComponent>,
private readonly _loadingService: LoadingService,
private readonly _permissionsService: PermissionsService,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<EditDossierDialogComponent>,
@Inject(MAT_DIALOG_DATA)
private readonly _data: {
dossierId: string;
section?: Section;
},
) {
super();
super(_injector, _dialogRef);
this.navItems = [
{
key: 'dossierInfo',
@ -126,7 +128,7 @@ export class EditDossierDialogComponent extends BaseDialogComponent {
return this.activeComponent?.disabled;
}
async save(closeAfterSave: boolean = false) {
async save(options?: SaveOptions) {
this._loadingService.start();
const result = await this.activeComponent.save();
this._loadingService.stop();
@ -135,7 +137,7 @@ export class EditDossierDialogComponent extends BaseDialogComponent {
this._toaster.success(_('edit-dossier-dialog.change-successful'), { params: { dossierName: this._dossierName } });
}
if (result.success && closeAfterSave) {
if (result.success && options?.closeAfterSave) {
this._dialogRef.close();
}
}
@ -146,9 +148,19 @@ export class EditDossierDialogComponent extends BaseDialogComponent {
changeTab(key: Section) {
if (this.changed) {
this._toaster.error(_('edit-dossier-dialog.unsaved-changes'));
return;
this._openConfirmDialog().then(async result => {
if (result in ConfirmOptions) {
if (result === ConfirmOptions.CONFIRM) {
await this.save();
} else {
this.revert();
}
this.activeNav = key;
}
this._waitingForConfirmation = false;
});
} else {
this.activeNav = key;
}
this.activeNav = key;
}
}

View File

@ -1,5 +1,5 @@
<section class="dialog">
<form (submit)="handleForceAnnotation()" [formGroup]="redactionForm">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-header heading-l" translate="manual-annotation.dialog.header.force-redaction" *ngIf="!isHintDialog"></div>
<div class="dialog-header heading-l" translate="manual-annotation.dialog.header.force-hint" *ngIf="isHintDialog"></div>
@ -19,7 +19,7 @@
<div class="iqser-input-group w-400" *ngIf="!isHintDialog">
<label translate="manual-annotation.dialog.content.legalBasis"></label>
<input [value]="redactionForm.get('reason').value?.legalBasis" disabled type="text" />
<input [value]="form.get('reason').value?.legalBasis" disabled type="text" />
</div>
<div [class.required]="!isDocumentAdmin" class="iqser-input-group w-300">
@ -29,11 +29,11 @@
</div>
<div class="dialog-actions">
<button [disabled]="!redactionForm.valid" color="primary" mat-flat-button type="submit">
<button [disabled]="disabled" color="primary" mat-flat-button type="submit">
{{ 'manual-annotation.dialog.actions.save' | translate }}
</button>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,7 +1,7 @@
import { Component, Inject, OnInit } from '@angular/core';
import { Component, Inject, Injector, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Toaster } from '@iqser/common-ui';
import { BaseDialogComponent, Toaster } from '@iqser/common-ui';
import { TranslateService } from '@ngx-translate/core';
import { UserService } from '@services/user.service';
import { ManualAnnotationService } from '../../services/manual-annotation.service';
@ -21,8 +21,7 @@ export interface LegalBasisOption {
templateUrl: './force-annotation-dialog.component.html',
styleUrls: ['./force-annotation-dialog.component.scss'],
})
export class ForceAnnotationDialogComponent implements OnInit {
redactionForm: FormGroup;
export class ForceAnnotationDialogComponent extends BaseDialogComponent implements OnInit {
isDocumentAdmin: boolean;
legalOptions: LegalBasisOption[] = [];
@ -35,10 +34,13 @@ export class ForceAnnotationDialogComponent implements OnInit {
private readonly _justificationsService: JustificationsService,
private readonly _manualAnnotationService: ManualAnnotationService,
private readonly _permissionsService: PermissionsService,
public dialogRef: MatDialogRef<ForceAnnotationDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<ForceAnnotationDialogComponent>,
@Inject(MAT_DIALOG_DATA) private readonly _data: { readonly dossier: Dossier; readonly hint: boolean },
) {
this.redactionForm = this._getForm();
super(_injector, _dialogRef);
this.form = this._getForm();
this.initialFormValue = this.form.getRawValue();
}
get isHintDialog() {
@ -55,6 +57,7 @@ export class ForceAnnotationDialogComponent implements OnInit {
}
async ngOnInit() {
super.ngOnInit();
const data = await this._justificationsService.getForDossierTemplate(this._data.dossier.dossierTemplateId).toPromise();
this.legalOptions = data.map(lbm => ({
@ -66,17 +69,17 @@ export class ForceAnnotationDialogComponent implements OnInit {
this.legalOptions.sort((a, b) => a.label.localeCompare(b.label));
}
handleForceAnnotation() {
this.dialogRef.close(this._createForceRedactionRequest());
save() {
this._dialogRef.close(this._createForceRedactionRequest());
}
private _createForceRedactionRequest(): ILegalBasisChangeRequest {
const request: ILegalBasisChangeRequest = {};
const legalOption: LegalBasisOption = this.redactionForm.get('reason').value;
const legalOption: LegalBasisOption = this.form.get('reason').value;
request.legalBasis = legalOption.legalBasis;
request.comment = this.redactionForm.get('comment').value;
request.comment = this.form.get('comment').value;
return request;
}

View File

@ -1,5 +1,5 @@
<section class="dialog">
<form (submit)="handleAddRedaction()" [formGroup]="redactionForm">
<form (submit)="save()" [formGroup]="form">
<div [translate]="title" class="dialog-header heading-l"></div>
<div class="dialog-content">
@ -54,7 +54,7 @@
<div *ngIf="!isDictionaryRequest" class="iqser-input-group w-400">
<label translate="manual-annotation.dialog.content.legalBasis"></label>
<input [value]="redactionForm.get('reason').value?.legalBasis" disabled type="text" />
<input [value]="form.get('reason').value?.legalBasis" disabled type="text" />
</div>
<div *ngIf="data.manualRedactionEntryWrapper.manualRedactionEntry.rectangle" class="iqser-input-group w-400">
@ -74,11 +74,11 @@
</div>
<div class="dialog-actions">
<button [disabled]="!redactionForm.valid" color="primary" mat-flat-button type="submit">
<button [disabled]="disabled" color="primary" mat-flat-button type="submit">
{{ 'manual-annotation.dialog.actions.save' | translate }}
</button>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,4 +1,4 @@
import { Component, Inject, OnInit } from '@angular/core';
import { Component, Inject, Injector, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppStateService } from '@state/app-state.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
@ -9,6 +9,7 @@ import { PermissionsService } from '@services/permissions.service';
import { JustificationsService } from '@services/entity-services/justifications.service';
import { Dictionary, Dossier, File, IAddRedactionRequest } from '@red/domain';
import { DossiersService } from '@services/entity-services/dossiers.service';
import { BaseDialogComponent } from '@iqser/common-ui';
import { DictionaryService } from '@shared/services/dictionary.service';
export interface LegalBasisOption {
@ -22,9 +23,7 @@ export interface LegalBasisOption {
templateUrl: './manual-annotation-dialog.component.html',
styleUrls: ['./manual-annotation-dialog.component.scss'],
})
export class ManualAnnotationDialogComponent implements OnInit {
redactionForm: FormGroup;
export class ManualAnnotationDialogComponent extends BaseDialogComponent implements OnInit {
isDocumentAdmin: boolean;
isDictionaryRequest: boolean;
isFalsePositiveRequest: boolean;
@ -43,15 +42,21 @@ export class ManualAnnotationDialogComponent implements OnInit {
private readonly _dossiersService: DossiersService,
private readonly _dictionaryService: DictionaryService,
public dialogRef: MatDialogRef<ManualAnnotationDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<ManualAnnotationDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: { manualRedactionEntryWrapper: ManualRedactionEntryWrapper; file: File },
) {
super(_injector, _dialogRef);
this._dossier = this._dossiersService.find(this.data.file.dossierId);
this.isDocumentAdmin = this._permissionsService.isApprover(this._dossier);
this.isFalsePositiveRequest = this.data.manualRedactionEntryWrapper.type === 'FALSE_POSITIVE';
this.isDictionaryRequest = this.data.manualRedactionEntryWrapper.type === 'DICTIONARY' || this.isFalsePositiveRequest;
this.redactionForm = this._getForm();
this.form = this._getForm();
this.initialFormValue = this.form.getRawValue();
this.possibleDictionaries = this._possibleDictionaries;
}
get title() {
@ -59,7 +64,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
}
get displayedDictionaryLabel() {
const dictType = this.redactionForm.get('dictionary').value;
const dictType = this.form.get('dictionary').value;
if (dictType) {
return this.possibleDictionaries.find(d => d.type === dictType).label;
}
@ -92,6 +97,7 @@ export class ManualAnnotationDialogComponent implements OnInit {
}
async ngOnInit() {
super.ngOnInit();
this.possibleDictionaries = await this._getPossibleDictionaries();
const data = await this._justificationsService.getForDossierTemplate(this._dossier.dossierTemplateId).toPromise();
@ -104,11 +110,11 @@ export class ManualAnnotationDialogComponent implements OnInit {
this.legalOptions.sort((a, b) => a.label.localeCompare(b.label));
}
handleAddRedaction() {
save() {
this._enhanceManualRedaction(this.data.manualRedactionEntryWrapper.manualRedactionEntry);
this._manualAnnotationService.addAnnotation(this.data.manualRedactionEntryWrapper.manualRedactionEntry, this.data.file).subscribe(
response => this.dialogRef.close(new ManualAnnotationResponse(this.data.manualRedactionEntryWrapper, response)),
() => this.dialogRef.close(),
response => this._dialogRef.close(new ManualAnnotationResponse(this.data.manualRedactionEntryWrapper, response)),
() => this._dialogRef.close(),
);
}
@ -133,8 +139,8 @@ export class ManualAnnotationDialogComponent implements OnInit {
}
private _enhanceManualRedaction(addRedactionRequest: IAddRedactionRequest) {
const legalOption: LegalBasisOption = this.redactionForm.get('reason').value;
addRedactionRequest.type = this.redactionForm.get('dictionary').value;
const legalOption: LegalBasisOption = this.form.get('reason').value;
addRedactionRequest.type = this.form.get('dictionary').value;
if (legalOption) {
addRedactionRequest.reason = legalOption.description;
addRedactionRequest.legalBasis = legalOption.legalBasis;
@ -146,11 +152,13 @@ export class ManualAnnotationDialogComponent implements OnInit {
if (!addRedactionRequest.reason) {
addRedactionRequest.reason = 'Dictionary Request';
}
const commentValue = this.redactionForm.get('comment').value;
const commentValue = this.form.get('comment').value;
addRedactionRequest.comment = commentValue ? { text: commentValue } : null;
addRedactionRequest.section = this.redactionForm.get('section').value;
addRedactionRequest.value = addRedactionRequest.rectangle
? this.redactionForm.get('classification').value
: addRedactionRequest.value;
addRedactionRequest.section = this.form.get('section').value;
addRedactionRequest.value = addRedactionRequest.rectangle ? this.form.get('classification').value : addRedactionRequest.value;
}
get disabled() {
return this.form.invalid;
}
}

View File

@ -1,5 +1,5 @@
<section class="dialog">
<form (submit)="save()" [formGroup]="recategorizeImageForm">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-header heading-l" translate="recategorize-image-dialog.header"></div>
<div class="dialog-content">
@ -23,12 +23,12 @@
</div>
<div class="dialog-actions">
<button [disabled]="!recategorizeImageForm.valid || !changed" color="primary" mat-flat-button type="submit">
<button [disabled]="disabled" color="primary" mat-flat-button type="submit">
{{ 'recategorize-image-dialog.actions.save' | translate }}
</button>
<div class="all-caps-label cancel" mat-dialog-close translate="recategorize-image-dialog.actions.cancel"></div>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,17 +1,17 @@
import { Component, Inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Component, Inject, Injector, OnInit } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { PermissionsService } from '@services/permissions.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { imageCategoriesTranslations } from '../../translations/image-categories-translations';
import { ImageCategory } from '../../models/image-category.model';
import { Dossier } from '@red/domain';
import { BaseDialogComponent } from '@iqser/common-ui';
@Component({
templateUrl: './recategorize-image-dialog.component.html',
})
export class RecategorizeImageDialogComponent implements OnInit {
recategorizeImageForm: FormGroup;
export class RecategorizeImageDialogComponent extends BaseDialogComponent implements OnInit {
isDocumentAdmin: boolean;
typeOptions: ImageCategory[] = ['signature', 'logo', 'formula', 'image'];
translations = imageCategoriesTranslations;
@ -19,27 +19,32 @@ export class RecategorizeImageDialogComponent implements OnInit {
constructor(
private readonly _permissionsService: PermissionsService,
private readonly _formBuilder: FormBuilder,
public dialogRef: MatDialogRef<RecategorizeImageDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<RecategorizeImageDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: { annotations: AnnotationWrapper[]; dossier: Dossier },
) {}
) {
super(_injector, _dialogRef);
}
get changed(): boolean {
return this.recategorizeImageForm.get('type').value !== this.data.annotations[0].type;
return this.form.get('type').value !== this.data.annotations[0].type;
}
ngOnInit() {
super.ngOnInit();
this.isDocumentAdmin = this._permissionsService.isApprover(this.data.dossier);
this.recategorizeImageForm = this._formBuilder.group({
this.form = this._formBuilder.group({
type: [this.data.annotations[0].type, Validators.required],
comment: this.isDocumentAdmin ? [null] : [null, Validators.required],
});
this.initialFormValue = this.form.getRawValue();
}
save() {
this.dialogRef.close({
type: this.recategorizeImageForm.get('type').value,
comment: this.recategorizeImageForm.get('comment').value,
this._dialogRef.close({
type: this.form.get('type').value,
comment: this.form.get('comment').value,
});
}
}

View File

@ -7,7 +7,7 @@
) | translate: { hint: data.hint }
}}
</div>
<form (submit)="confirm()" [formGroup]="redactionForm">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-content">
{{
(data.removeFromDictionary
@ -46,12 +46,12 @@
</div>
<div class="dialog-actions">
<button [disabled]="!redactionForm.valid" color="primary" mat-flat-button type="submit">
<button [disabled]="disabled" color="primary" mat-flat-button type="submit">
{{ 'remove-annotations-dialog.confirm' | translate }}
</button>
<div class="all-caps-label cancel" mat-dialog-close translate="remove-annotations-dialog.cancel"></div>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,10 +1,10 @@
import { Component, Inject } from '@angular/core';
import { Component, Inject, Injector } from '@angular/core';
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
import { TranslateService } from '@ngx-translate/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { PermissionsService } from '@services/permissions.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { humanize } from '@iqser/common-ui';
import { FormBuilder, Validators } from '@angular/forms';
import { BaseDialogComponent, humanize } from '@iqser/common-ui';
import { Dossier } from '@red/domain';
export interface RemoveAnnotationsDialogInput {
@ -18,23 +18,24 @@ export interface RemoveAnnotationsDialogInput {
templateUrl: './remove-annotations-dialog.component.html',
styleUrls: ['./remove-annotations-dialog.component.scss'],
})
export class RemoveAnnotationsDialogComponent {
redactionForm: FormGroup;
export class RemoveAnnotationsDialogComponent extends BaseDialogComponent {
constructor(
private readonly _translateService: TranslateService,
private readonly _formBuilder: FormBuilder,
readonly permissionsService: PermissionsService,
public dialogRef: MatDialogRef<RemoveAnnotationsDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<RemoveAnnotationsDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: RemoveAnnotationsDialogInput,
) {
this.redactionForm = this._formBuilder.group({
super(_injector, _dialogRef);
this.form = this._formBuilder.group({
comment: this.permissionsService.isApprover(this.data.dossier) ? [null] : [null, Validators.required],
});
this.initialFormValue = this.form.getRawValue();
}
confirm() {
this.dialogRef.close({ comment: this.redactionForm.getRawValue().comment });
save() {
this._dialogRef.close({ comment: this.form.getRawValue().comment });
}
printable(annotation: AnnotationWrapper) {

View File

@ -1,5 +1,5 @@
<section class="dialog">
<form (submit)="save()" [formGroup]="resizeForm">
<form (submit)="save()" [formGroup]="form">
<div class="dialog-header heading-l" translate="resize-annotation-dialog.header"></div>
<div class="dialog-content">
@ -10,12 +10,12 @@
</div>
<div class="dialog-actions">
<button [disabled]="!resizeForm.valid" color="primary" mat-flat-button type="submit">
<button [disabled]="disabled" color="primary" mat-flat-button type="submit">
{{ 'resize-annotation-dialog.actions.save' | translate }}
</button>
<div class="all-caps-label cancel" mat-dialog-close translate="resize-annotation-dialog.actions.cancel"></div>
</div>
</form>
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
<iqser-circle-button class="dialog-close" icon="iqser:close" (action)="close()"></iqser-circle-button>
</section>

View File

@ -1,34 +1,40 @@
import { Component, Inject, OnInit } from '@angular/core';
import { Component, Inject, Injector, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { FormBuilder, Validators } from '@angular/forms';
import { PermissionsService } from '@services/permissions.service';
import { Dossier } from '@red/domain';
import { BaseDialogComponent } from '@iqser/common-ui';
@Component({
templateUrl: './resize-annotation-dialog.component.html',
})
export class ResizeAnnotationDialogComponent implements OnInit {
resizeForm: FormGroup;
export class ResizeAnnotationDialogComponent extends BaseDialogComponent implements OnInit {
isDocumentAdmin: boolean;
constructor(
private readonly _permissionsService: PermissionsService,
private readonly _formBuilder: FormBuilder,
public dialogRef: MatDialogRef<ResizeAnnotationDialogComponent>,
protected readonly _injector: Injector,
protected readonly _dialogRef: MatDialogRef<ResizeAnnotationDialogComponent>,
@Inject(MAT_DIALOG_DATA) private readonly _data: { dossier: Dossier },
) {}
) {
super(_injector, _dialogRef);
}
ngOnInit() {
super.ngOnInit();
this.isDocumentAdmin = this._permissionsService.isApprover(this._data.dossier);
this.resizeForm = this._formBuilder.group({
this.form = this._formBuilder.group({
comment: this.isDocumentAdmin ? [null] : [null, Validators.required],
});
this.initialFormValue = this.form.getRawValue();
}
save() {
this.dialogRef.close({
comment: this.resizeForm.get('comment').value,
this._dialogRef.close({
comment: this.form.get('comment').value,
});
}
}

View File

@ -30,6 +30,7 @@ export class DossiersDialogService extends DialogService<DialogType> {
protected readonly _config: DialogConfig<DialogType> = {
confirm: {
component: ConfirmationDialogComponent,
dialogConfig: { disableClose: false },
},
documentInfo: {
component: DocumentInfoDialogComponent,
@ -45,6 +46,7 @@ export class DossiersDialogService extends DialogService<DialogType> {
},
assignFile: {
component: AssignReviewerApproverDialogComponent,
dialogConfig: { disableClose: false },
},
recategorizeImage: {
component: RecategorizeImageDialogComponent,

View File

@ -448,6 +448,13 @@
"question": "Are you sure you want to delete {filesCount, plural, one{this document} other{these documents}}?",
"title": "Delete {filesCount, plural, one{{fileName}} other{Selected Documents}}"
},
"unsaved-changes": {
"confirmation-text": "Save and Leave",
"details": "If you leave the tab without saving, all the unsaved changes will be lost.",
"discard-changes-text": "DISCARD CHANGES",
"question": "Are you sure you want to leave the tab? You have unsaved changes.",
"title": "You have unsaved changes"
},
"upload-report-template": {
"alternate-confirmation-text": "Upload as multi-file report",
"confirmation-text": "Upload as single-file report",
@ -940,8 +947,7 @@
"members": "Members",
"team-members": "Team Members"
},
"side-nav-title": "Configurations",
"unsaved-changes": "You have unsaved changes. Save or revert before changing the tab."
"side-nav-title": "Configurations"
},
"error": {
"deleted-entity": {

@ -1 +1 @@
Subproject commit 1b8ce8ef1d295efc5b02b39b631b5e654938de29
Subproject commit 95644f59e4e32517d76e0bd9267805a88ebdd8d1