refactor plan blueprint editor, change belongsToTenant on copied items

This commit is contained in:
mchouliara 2024-08-28 12:43:45 +03:00
parent ff0cb00d49
commit 1bf3fae0b8
3 changed files with 76 additions and 69 deletions

View File

@ -5,17 +5,17 @@
<div class="col-md col-12"> <div class="col-md col-12">
<app-navigation-breadcrumb /> <app-navigation-breadcrumb />
</div> </div>
<div class="col-md-auto mb-md-0 col-12 mb-2" *ngIf="!isNew && !isClone && !isNewVersion && this.editorModel.belongsToCurrentTenant != false"> <div class="col-md-auto mb-md-0 col-12 mb-2" *ngIf="!hideEditActions && canDelete">
<button [disabled]="isLocked" mat-button class="action-btn" type="button" (click)="delete()"> <button [disabled]="isLocked" mat-button class="action-btn" type="button" (click)="delete()">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.DELETE' | translate}} {{'PLAN-BLUEPRINT-EDITOR.ACTIONS.DELETE' | translate}}
</button> </button>
</div> </div>
<div class="col-md-auto col-12" *ngIf="formGroup.get('status').value==1 && !isClone && !isNewVersion"> <div class="col-md-auto col-12" *ngIf="canDownloadXML">
<button mat-button class="finalize-btn" (click)="downloadXML()" type="button">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.DOWNLOAD-XML' | translate }}</button> <button mat-button class="finalize-btn" (click)="downloadXML()" type="button">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.DOWNLOAD-XML' | translate }}</button>
</div> </div>
<div *ngIf="formGroup.get('status').value!=1" class="col-auto"> <div *ngIf="!hideEditActions && canFinalize" class="col-auto">
<button mat-button class="finalize-btn" (click)="finalize()" [disabled]="!this.isFormValid() || !canFinalize || isLocked" type="button">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.FINALIZE' | translate }}</button> <button mat-button class="finalize-btn" (click)="finalize()" [disabled]="this.isLocked || !this.isFormValid()" type="button">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
</div> </div>
</div> </div>
<form *ngIf="formGroup"> <form *ngIf="formGroup">
@ -52,8 +52,8 @@
</div> </div>
<div class="col-auto d-flex"><mat-icon [ngClass]="{'drag-handle-disabled': formGroup.disabled}" cdkDragHandle class="drag-handle">drag_indicator</mat-icon></div> <div class="col-auto d-flex"><mat-icon [ngClass]="{'drag-handle-disabled': formGroup.disabled}" cdkDragHandle class="drag-handle">drag_indicator</mat-icon></div>
<div class="col-auto d-flex"> <div class="col-auto d-flex" *ngIf="!hideEditActions">
<button mat-icon-button class="action-list-icon" matTooltip="{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.REMOVE-SECTION' | translate}}" (click)="removeSection(sectionIndex)" [disabled]="formGroup.disabled"> <button mat-icon-button class="action-list-icon" matTooltip="{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.REMOVE-SECTION' | translate}}" (click)="removeSection(sectionIndex)">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
</button> </button>
</div> </div>
@ -77,8 +77,8 @@
<mat-error *ngIf="section.get('description').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="section.get('description').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>
<div class="col-auto mb-3"> <div class="col-auto mb-3" *ngIf="!hideEditActions">
<button mat-button class="action-btn" type="button" (click)="addField(sectionIndex)" [disabled]="formGroup.disabled">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.ADD-FIELD' | translate}}</button> <button mat-button class="action-btn" type="button" (click)="addField(sectionIndex)">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.ADD-FIELD' | translate}}</button>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
@ -90,8 +90,8 @@
<span *ngIf="!isSectionSelected(fieldIndex)" style="font-size: 18px; box-sizing: border-box; display: inline-block; padding: 0.85rem 0.42rem 0 0.45rem;">{{fieldIndex + 1}}</span> <span *ngIf="!isSectionSelected(fieldIndex)" style="font-size: 18px; box-sizing: border-box; display: inline-block; padding: 0.85rem 0.42rem 0 0.45rem;">{{fieldIndex + 1}}</span>
<mat-icon *ngIf="isSectionSelected(fieldIndex)" [ngClass]="{'drag-handle-disabled': formGroup.disabled}" cdkDragHandle class="drag-handle" style="margin-top: 0.9rem;">drag_indicator</mat-icon> <mat-icon *ngIf="isSectionSelected(fieldIndex)" [ngClass]="{'drag-handle-disabled': formGroup.disabled}" cdkDragHandle class="drag-handle" style="margin-top: 0.9rem;">drag_indicator</mat-icon>
</div> </div>
<div class="col-auto"> <div class="col-auto" *ngIf="!hideEditActions">
<button mat-icon-button matTooltip="{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.REMOVE-FIELD' | translate}}" (click)="removeField(sectionIndex, fieldIndex)" [disabled]="formGroup.disabled"> <button mat-icon-button matTooltip="{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.REMOVE-FIELD' | translate}}" (click)="removeField(sectionIndex, fieldIndex)">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
</button> </button>
</div> </div>
@ -190,8 +190,8 @@
</div> </div>
</div> </div>
</div> </div>
<div [hidden]="viewOnly" class="col-12 col-xl-auto section-options-horizontal"> <div [hidden]="viewOnly" class="col-12 col-xl-auto section-options-horizontal" *ngIf="!hideEditActions">
<button mat-icon-button matTooltip="{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.REMOVE-FIELD' | translate}}" (click)="removeField(sectionIndex, fieldIndex)" [disabled]="formGroup.disabled"> <button mat-icon-button matTooltip="{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.REMOVE-FIELD' | translate}}" (click)="removeField(sectionIndex, fieldIndex)">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
</button> </button>
</div> </div>
@ -216,8 +216,8 @@
<mat-error *ngIf="section.get('hasTemplates').hasError('backendError')">{{section.get('hasTemplates').getError('backendError').message}}</mat-error> <mat-error *ngIf="section.get('hasTemplates').hasError('backendError')">{{section.get('hasTemplates').getError('backendError').message}}</mat-error>
<mat-error *ngIf="section.get('hasTemplates').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="section.get('hasTemplates').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</div> </div>
<div class="col-auto" *ngIf="section.get('hasTemplates').value == true"> <div class="col-auto" *ngIf="!hideEditActions && section.get('hasTemplates').value">
<button mat-button class="action-btn" type="button" (click)="addDescriptionTemplate(sectionIndex)" [disabled]="formGroup.disabled">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.ADD-DESCRIPTION-TEMPLATE' | translate}}</button> <button mat-button class="action-btn" type="button" (click)="addDescriptionTemplate(sectionIndex)">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.ADD-DESCRIPTION-TEMPLATE' | translate}}</button>
</div> </div>
</div> </div>
</div> </div>
@ -233,8 +233,8 @@
<span *ngIf="!isDescriptionTemplateSelected(descriptionTemplateIndex)" style="font-size: 18px; box-sizing: border-box; display: inline-block; padding: 0.85rem 0.42rem 0 0.45rem;">{{descriptionTemplateIndex + 1}}</span> <span *ngIf="!isDescriptionTemplateSelected(descriptionTemplateIndex)" style="font-size: 18px; box-sizing: border-box; display: inline-block; padding: 0.85rem 0.42rem 0 0.45rem;">{{descriptionTemplateIndex + 1}}</span>
<mat-icon *ngIf="isDescriptionTemplateSelected(descriptionTemplateIndex)" [ngClass]="{'drag-handle-disabled': formGroup.disabled}" cdkDragHandle class="drag-handle" style="margin-top: 0.9rem;">drag_indicator</mat-icon> <mat-icon *ngIf="isDescriptionTemplateSelected(descriptionTemplateIndex)" [ngClass]="{'drag-handle-disabled': formGroup.disabled}" cdkDragHandle class="drag-handle" style="margin-top: 0.9rem;">drag_indicator</mat-icon>
</div> </div>
<div class="col-auto"> <div class="col-auto" *ngIf="!hideEditActions">
<button mat-icon-button class="action-list-icon" matTooltip="{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.REMOVE-DESCRIPTION-TEMPLATE' | translate}}" (click)="removeDescriptionTemplate(sectionIndex, descriptionTemplateIndex)" [disabled]="formGroup.disabled"> <button mat-icon-button class="action-list-icon" matTooltip="{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.REMOVE-DESCRIPTION-TEMPLATE' | translate}}" (click)="removeDescriptionTemplate(sectionIndex, descriptionTemplateIndex)">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
</button> </button>
</div> </div>
@ -283,8 +283,8 @@
</div> </div>
<div class="col-12 col-xl-auto section-options-horizontal"> <div class="col-12 col-xl-auto section-options-horizontal">
<div class="row"> <div class="row">
<div class="col-auto"> <div class="col-auto" *ngIf="!hideEditActions">
<button mat-icon-button class="action-list-icon" matTooltip="{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.REMOVE-DESCRIPTION-TEMPLATE' | translate}}" (click)="removeDescriptionTemplate(sectionIndex, descriptionTemplateIndex)" [disabled]="formGroup.disabled"> <button mat-icon-button class="action-list-icon" matTooltip="{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.REMOVE-DESCRIPTION-TEMPLATE' | translate}}" (click)="removeDescriptionTemplate(sectionIndex, descriptionTemplateIndex)">
<mat-icon>delete</mat-icon> <mat-icon>delete</mat-icon>
</button> </button>
</div> </div>
@ -318,8 +318,8 @@
<div class="col-12"> <div class="col-12">
<div class="row"> <div class="row">
<div class="col-auto"> <div class="col-auto" *ngIf="!hideEditActions">
<button mat-button class="action-btn" type="button" (click)="addSection()" [disabled]="formGroup.disabled">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.ADD-SECTION' | translate}}</button> <button mat-button class="action-btn" type="button" (click)="addSection()">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.ADD-SECTION' | translate}}</button>
<mat-error *ngIf="formGroup.get('definition').get('sections').dirty && formGroup.get('definition').get('sections').hasError('required')">{{'PLAN-BLUEPRINT-EDITOR.SECTIONS-REQUIRED' | translate}}</mat-error> <mat-error *ngIf="formGroup.get('definition').get('sections').dirty && formGroup.get('definition').get('sections').hasError('required')">{{'PLAN-BLUEPRINT-EDITOR.SECTIONS-REQUIRED' | translate}}</mat-error>
<mat-error *ngIf="formGroup.get('definition').get('sections').hasError('backendError')">{{formGroup.get('definition').get('sections').getError('backendError').message}}</mat-error> <mat-error *ngIf="formGroup.get('definition').get('sections').hasError('backendError')">{{formGroup.get('definition').get('sections').getError('backendError').message}}</mat-error>
</div> </div>
@ -331,8 +331,8 @@
<button mat-button class="action-btn" (click)="cancel()" type="button">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.CANCEL' | translate}}</button> <button mat-button class="action-btn" (click)="cancel()" type="button">{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.CANCEL' | translate}}</button>
</div> </div>
<div class="col"></div> <div class="col"></div>
<div class="col-auto"> <div class="col-auto" *ngIf="!hideEditActions">
<button mat-button class="action-btn" [disabled]="!canSave || isLocked" type="submit" (click)="save(); formSubmit()"> <button mat-button class="action-btn" [disabled]="isLocked" type="submit" (click)="save(); formSubmit()">
{{'PLAN-BLUEPRINT-EDITOR.ACTIONS.SAVE' | translate}} {{'PLAN-BLUEPRINT-EDITOR.ACTIONS.SAVE' | translate}}
</button> </button>
</div> </div>

View File

@ -55,10 +55,6 @@ import { RouterUtilsService } from '@app/core/services/router/router-utils.servi
}) })
export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditorModel, PlanBlueprint> implements OnInit { export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditorModel, PlanBlueprint> implements OnInit {
isNew = true;
isClone = false;
isNewVersion = false;
isDeleted = false;
formGroup: UntypedFormGroup = null; formGroup: UntypedFormGroup = null;
showInactiveDetails = false; showInactiveDetails = false;
@ -74,22 +70,31 @@ export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditor
public usedDescriptionTemplateGroupIdsBySection: Map<Guid, Guid[]> = new Map<Guid, Guid[]>; public usedDescriptionTemplateGroupIdsBySection: Map<Guid, Guid[]> = new Map<Guid, Guid[]>;
public descriptionTemplateGroupIdsConfigBySection: Map<Guid, SingleAutoCompleteConfiguration> = new Map<Guid, SingleAutoCompleteConfiguration>; public descriptionTemplateGroupIdsConfigBySection: Map<Guid, SingleAutoCompleteConfiguration> = new Map<Guid, SingleAutoCompleteConfiguration>;
protected get canDelete(): boolean { PlanBlueprintStatus = PlanBlueprintStatus;
return !this.isDeleted && !this.isNew && this.hasPermission(this.authService.permissionEnum.DeletePlanBlueprint); isNew = true;
isClone = false;
isNewVersion = false;
isDeleted = false;
belongsToCurrentTenant = true;
protected get isTransient(): boolean {
return this.isNew || this.isClone || this.isNewVersion;
} }
protected get canSave(): boolean { protected get hideEditActions(): boolean {
if (this.isDeleted || !this.hasPermission(this.authService.permissionEnum.EditPlanBlueprint)) return false; return this.isDeleted || this.isFinalized || !this.authService.hasPermission(AppPermission.EditPlanBlueprint) || !this.belongsToCurrentTenant;
if (this.isNewVersion) return this.canCreateNewVersion; }
return !this.formGroup.disabled;
protected get canDownloadXML(): boolean {
return (this.formGroup.get('status').value === PlanBlueprintStatus.Finalized) && !this.isTransient;
}
protected get canDelete(): boolean {
return !this.isTransient && this.hasPermission(this.authService.permissionEnum.DeletePlanBlueprint);
} }
protected get canFinalize(): boolean { protected get canFinalize(): boolean {
return !this.isNewVersion && !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditPlanBlueprint); return !this.isTransient && !this.isFinalized;
}
protected get canCreateNewVersion(): boolean {
return this.isFinalized;
} }
protected get isFinalized(): boolean { protected get isFinalized(): boolean {
@ -167,16 +172,22 @@ export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditor
getItem(itemId: Guid, successFunction: (item: PlanBlueprint) => void) { getItem(itemId: Guid, successFunction: (item: PlanBlueprint) => void) {
this.planBlueprintService.getSingle(itemId, PlanBlueprintEditorResolver.lookupFields()) this.planBlueprintService.getSingle(itemId, PlanBlueprintEditorResolver.lookupFields())
.pipe(map(data => data as PlanBlueprint), takeUntil(this._destroyed)) .pipe(map(data => data as PlanBlueprint), takeUntil(this._destroyed))
.subscribe( .subscribe({
data => successFunction(data), next: (data) => successFunction(data),
error => this.onCallbackError(error) error: (error) => this.onCallbackError(error)
); });
} }
prepareForm(data: PlanBlueprint) { prepareForm(data: PlanBlueprint) {
try { try {
this.editorModel = data ? new PlanBlueprintEditorModel().fromModel(data) : new PlanBlueprintEditorModel(); const dataCopy = data ? JSON.parse(JSON.stringify(data)) : null;
this.isDeleted = data ? data.isActive === IsActive.Inactive : false; if(dataCopy && this.isClone) {
dataCopy.belongsToCurrentTenant = true;
}
this.editorModel = dataCopy ? new PlanBlueprintEditorModel().fromModel(dataCopy) : new PlanBlueprintEditorModel();
this.isDeleted = dataCopy ? dataCopy.isActive === IsActive.Inactive : false;
this.belongsToCurrentTenant = this.isNew || dataCopy.belongsToCurrentTenant;
this.buildForm(); this.buildForm();
if (data && data.id) this.checkLock(data.id, LockTargetType.PlanBlueprint, 'PLAN-BLUEPRINT-EDITOR.LOCKED-DIALOG.TITLE', 'PLAN-BLUEPRINT-EDITOR.LOCKED-DIALOG.MESSAGE'); if (data && data.id) this.checkLock(data.id, LockTargetType.PlanBlueprint, 'PLAN-BLUEPRINT-EDITOR.LOCKED-DIALOG.TITLE', 'PLAN-BLUEPRINT-EDITOR.LOCKED-DIALOG.MESSAGE');
@ -194,13 +205,9 @@ export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditor
} }
buildForm() { buildForm() {
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.authService.hasPermission(AppPermission.EditPlanBlueprint), (this.isNew || this.isClone)); this.formGroup = this.editorModel.buildForm(null, this.hideEditActions, (this.isNew || this.isClone));
this.planBlueprintEditorService.setValidationErrorModel(this.editorModel.validationErrorModel); this.planBlueprintEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
if (this.isFinalized || this.isDeleted) {
this.formGroup.disable();
}
if (this.isNewVersion) { if (this.isNewVersion) {
this.formGroup.enable();
this.formGroup.get('code').disable(); this.formGroup.get('code').disable();
} }
} }
@ -221,26 +228,26 @@ export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditor
} }
persistEntity(onSuccess?: (response) => void): void { persistEntity(onSuccess?: (response) => void): void {
if (this.isNewVersion == false) { if (!this.isNewVersion) {
const formData = this.formService.getValue(this.formGroup.value) as PlanBlueprintPersist; const formData = this.formService.getValue(this.formGroup.value) as PlanBlueprintPersist;
formData.code = this.formGroup.get('code').getRawValue(); formData.code = this.formGroup.get('code').getRawValue();
this.planBlueprintService.persist(formData) this.planBlueprintService.persist(formData)
.pipe(takeUntil(this._destroyed)).subscribe( .pipe(takeUntil(this._destroyed)).subscribe({
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete), next: (complete) => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
error => { error: (error) => {
this.formGroup.get('status').setValue(PlanBlueprintStatus.Draft); this.formGroup.get('status').setValue(PlanBlueprintStatus.Draft);
this.onCallbackError(error); this.onCallbackError(error);
} }
); });
} else if (this.isNewVersion == true && this.isNew == false && this.isClone == false) { } else if (!this.isNew && !this.isClone) {
const formData = this.formService.getValue(this.formGroup.value) as NewVersionPlanBlueprintPersist; const formData = this.formService.getValue(this.formGroup.value) as NewVersionPlanBlueprintPersist;
this.planBlueprintService.newVersion(formData) this.planBlueprintService.newVersion(formData)
.pipe(takeUntil(this._destroyed)).subscribe( .pipe(takeUntil(this._destroyed)).subscribe({
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete), next: (complete) => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
error => this.onCallbackError(error) error: (error) => this.onCallbackError(error)
); });
} }
} }
@ -269,10 +276,10 @@ export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditor
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) { if (result) {
this.planBlueprintService.delete(value.id).pipe(takeUntil(this._destroyed)) this.planBlueprintService.delete(value.id).pipe(takeUntil(this._destroyed))
.subscribe( .subscribe({
complete => this.onCallbackDeleteSuccess(), complete: () => this.onCallbackDeleteSuccess(),
error => this.onCallbackError(error) error: (error) => this.onCallbackError(error)
); });
} }
}); });
} }
@ -637,7 +644,7 @@ export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditor
finalize() { finalize() {
if (this.checkValidity() || !this.hasDescriptionTemplates()) { if (this.checkValidity() || !this.hasDescriptionTemplates()) {
this.formGroup.get('status').setValue(PlanBlueprintStatus.Finalized); this.formGroup.get('status').setValue(PlanBlueprintStatus.Finalized);
if (this.isNewVersion) this.isNewVersion = false; if (this.isNewVersion){ this.isNewVersion = false; }
this.formSubmit(); this.formSubmit();
} }
} }

View File

@ -41,15 +41,15 @@ export class PlanBlueprintEditorModel extends BaseEditorModel implements PlanBlu
if (context == null) { context = this.createValidationContext(); } if (context == null) { context = this.createValidationContext(); }
return this.formBuilder.group({ return this.formBuilder.group({
id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators], id: [{ value: this.id, disabled }, context.getValidation('id').validators],
label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators], label: [{ value: this.label, disabled }, context.getValidation('label').validators],
code: [{ value: this.code, disabled: !isNewOrClone }, context.getValidation('code').validators], code: [{ value: this.code, disabled: !isNewOrClone }, context.getValidation('code').validators],
status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators], status: [{ value: this.status, disabled }, context.getValidation('status').validators],
definition: this.definition.buildForm({ definition: this.definition.buildForm({
rootPath: `definition.`, rootPath: `definition.`,
disabled: disabled disabled
}), }),
hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators] hash: [{ value: this.hash, disabled }, context.getValidation('hash').validators]
}); });
} }