2019-09-23 10:17:03 +02:00
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
import { Component, OnInit } from '@angular/core';
|
2023-10-25 16:47:48 +02:00
|
|
|
import { FormArray, UntypedFormGroup } from '@angular/forms';
|
2023-10-20 17:01:09 +02:00
|
|
|
import { MatDialog } from '@angular/material/dialog';
|
2023-10-24 09:40:26 +02:00
|
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
2023-10-20 17:01:09 +02:00
|
|
|
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
|
2019-12-11 15:51:03 +01:00
|
|
|
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
|
|
|
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
2023-10-20 17:01:09 +02:00
|
|
|
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
2023-10-25 16:47:48 +02:00
|
|
|
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
|
2023-10-24 09:40:26 +02:00
|
|
|
import { DatePipe } from '@angular/common';
|
2024-02-09 21:46:05 +01:00
|
|
|
import { MatCheckboxChange } from '@angular/material/checkbox';
|
|
|
|
import { MatSelectChange } from '@angular/material/select';
|
|
|
|
import { DmpBlueprintFieldCategory } from '@app/core/common/enum/dmp-blueprint-field-category';
|
2023-10-25 16:47:48 +02:00
|
|
|
import { DmpBlueprintExtraFieldDataType } from '@app/core/common/enum/dmp-blueprint-field-type';
|
|
|
|
import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status';
|
|
|
|
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
|
|
|
|
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
2023-10-24 09:40:26 +02:00
|
|
|
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
2024-02-09 21:46:05 +01:00
|
|
|
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
|
|
|
|
import { DmpBlueprint, DmpBlueprintPersist, NewVersionDmpBlueprintPersist, SystemFieldInSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
2023-10-24 09:40:26 +02:00
|
|
|
import { AuthService } from '@app/core/services/auth/auth.service';
|
2024-02-09 21:46:05 +01:00
|
|
|
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
|
2023-10-24 09:40:26 +02:00
|
|
|
import { LoggingService } from '@app/core/services/logging/logging-service';
|
2023-10-25 16:47:48 +02:00
|
|
|
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
|
|
|
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
|
2023-10-24 09:40:26 +02:00
|
|
|
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
2024-02-09 21:46:05 +01:00
|
|
|
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
2023-10-24 09:40:26 +02:00
|
|
|
import { BaseEditor } from '@common/base/base-editor';
|
2019-12-13 10:53:43 +01:00
|
|
|
import { FormService } from '@common/forms/form-service';
|
2023-10-25 16:47:48 +02:00
|
|
|
import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component';
|
2023-10-20 17:01:09 +02:00
|
|
|
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
2023-10-24 09:40:26 +02:00
|
|
|
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
|
|
|
import { FilterService } from '@common/modules/text-filter/filter-service';
|
2023-10-20 17:01:09 +02:00
|
|
|
import { Guid } from '@common/types/guid';
|
2018-10-05 17:00:54 +02:00
|
|
|
import { TranslateService } from '@ngx-translate/core';
|
2023-10-25 16:47:48 +02:00
|
|
|
import * as FileSaver from 'file-saver';
|
2019-12-11 15:51:03 +01:00
|
|
|
import { map, takeUntil } from 'rxjs/operators';
|
2024-02-09 21:46:05 +01:00
|
|
|
import { DescriptionTemplatePreviewDialogComponent } from '../../description-template/description-template-preview/description-template-preview-dialog.component';
|
|
|
|
import { DmpBlueprintEditorModel } from './dmp-blueprint-editor.model';
|
2023-10-24 09:40:26 +02:00
|
|
|
import { DmpBlueprintEditorResolver } from './dmp-blueprint-editor.resolver';
|
|
|
|
import { DmpBlueprintEditorService } from './dmp-blueprint-editor.service';
|
2024-02-09 21:46:05 +01:00
|
|
|
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
|
2024-02-20 13:58:16 +01:00
|
|
|
import { SemanticsService } from '@app/core/services/semantic/semantics.service';
|
2024-02-27 15:27:26 +01:00
|
|
|
import { PrefillingSourceService } from '@app/core/services/prefilling-source/prefilling-source.service';
|
2019-12-11 15:51:03 +01:00
|
|
|
|
2018-03-28 15:24:47 +02:00
|
|
|
|
|
|
|
@Component({
|
2023-10-20 17:01:09 +02:00
|
|
|
selector: 'app-dmp-blueprint-editor-component',
|
|
|
|
templateUrl: 'dmp-blueprint-editor.component.html',
|
2023-10-24 09:40:26 +02:00
|
|
|
styleUrls: ['./dmp-blueprint-editor.component.scss'],
|
|
|
|
providers: [DmpBlueprintEditorService]
|
2018-03-28 15:24:47 +02:00
|
|
|
})
|
2023-10-24 09:40:26 +02:00
|
|
|
export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorModel, DmpBlueprint> implements OnInit {
|
2018-03-28 15:24:47 +02:00
|
|
|
|
2018-10-05 17:00:54 +02:00
|
|
|
isNew = true;
|
2024-02-06 19:41:57 +01:00
|
|
|
isClone = false;
|
|
|
|
isNewVersion = false;
|
2023-10-24 09:40:26 +02:00
|
|
|
isDeleted = false;
|
2023-10-05 15:39:17 +02:00
|
|
|
formGroup: UntypedFormGroup = null;
|
2023-10-24 09:40:26 +02:00
|
|
|
showInactiveDetails = false;
|
2024-02-09 21:46:05 +01:00
|
|
|
|
|
|
|
dmpBlueprintSectionFieldCategory = DmpBlueprintFieldCategory;
|
2023-10-25 16:47:48 +02:00
|
|
|
dmpBlueprintSystemFieldType = DmpBlueprintSystemFieldType;
|
2023-11-28 14:15:16 +01:00
|
|
|
public dmpBlueprintSystemFieldTypeEnum = this.enumUtils.getEnumValues<DmpBlueprintSystemFieldType>(DmpBlueprintSystemFieldType);
|
2023-10-25 16:47:48 +02:00
|
|
|
dmpBlueprintExtraFieldDataType = DmpBlueprintExtraFieldDataType;
|
2023-11-28 14:15:16 +01:00
|
|
|
public dmpBlueprintExtraFieldDataTypeEnum = this.enumUtils.getEnumValues<DmpBlueprintExtraFieldDataType>(DmpBlueprintExtraFieldDataType);
|
2024-02-09 21:46:05 +01:00
|
|
|
public dmpBlueprintFieldCategoryEnum = this.enumUtils.getEnumValues<DmpBlueprintFieldCategory>(DmpBlueprintFieldCategory);
|
2024-01-29 12:13:30 +01:00
|
|
|
descriptionTempalteGroupSingleAutocompleteConfiguration: SingleAutoCompleteConfiguration = {
|
|
|
|
initialItems: (data?: any) => this.descriptionTemplateService.query(this.descriptionTemplateService.buildDescriptionTempalteGroupAutocompleteLookup(null, null, null, this.getUsedDescriptionTemplateGroupIds())).pipe(map(x => x.items)),
|
2024-02-09 21:46:05 +01:00
|
|
|
filterFn: (searchQuery: string, data?: any) => this.descriptionTemplateService.query(this.descriptionTemplateService.buildDescriptionTempalteGroupAutocompleteLookup(searchQuery, null, null, this.getUsedDescriptionTemplateGroupIds() ? this.getUsedDescriptionTemplateGroupIds() : null)).pipe(map(x => x.items)),
|
2024-01-29 12:13:30 +01:00
|
|
|
getSelectedItem: (selectedItem: any) => this.descriptionTemplateService.query(this.descriptionTemplateService.buildDescriptionTempalteGroupAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
|
|
|
|
displayFn: (item: DescriptionTemplate) => item.label,
|
|
|
|
titleFn: (item: DescriptionTemplate) => item.label,
|
|
|
|
subtitleFn: (item: DescriptionTemplate) => item.description,
|
|
|
|
valueAssign: (item: DescriptionTemplate) => item.groupId,
|
|
|
|
popupItemActionIcon: 'visibility'
|
|
|
|
}
|
2023-10-20 17:01:09 +02:00
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
protected get canDelete(): boolean {
|
|
|
|
return !this.isDeleted && !this.isNew && this.hasPermission(this.authService.permissionEnum.DeleteDmpBlueprint);
|
2023-08-03 12:10:36 +02:00
|
|
|
}
|
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
protected get canSave(): boolean {
|
2024-02-07 12:03:47 +01:00
|
|
|
if (this.isDeleted || !this.hasPermission(this.authService.permissionEnum.EditDmpBlueprint)) return false;
|
|
|
|
if (this.isNewVersion) return this.canCreateNewVersion;
|
|
|
|
return !this.formGroup.disabled;
|
2023-07-25 14:51:29 +02:00
|
|
|
}
|
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
protected get canFinalize(): boolean {
|
2024-02-07 16:13:13 +01:00
|
|
|
return !this.isNewVersion && !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditDmpBlueprint);
|
2023-07-25 14:51:29 +02:00
|
|
|
}
|
2023-10-20 17:01:09 +02:00
|
|
|
|
2024-02-07 12:03:47 +01:00
|
|
|
protected get canCreateNewVersion(): boolean {
|
|
|
|
return this.isFinalized;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected get isFinalized(): boolean {
|
|
|
|
return this.editorModel.status == DmpBlueprintStatus.Finalized;
|
|
|
|
}
|
2023-07-25 14:51:29 +02:00
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
private hasPermission(permission: AppPermission): boolean {
|
|
|
|
return this.authService.hasPermission(permission) || this.editorModel?.permissions?.includes(permission);
|
2023-07-25 14:51:29 +02:00
|
|
|
}
|
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
constructor(
|
|
|
|
// BaseFormEditor injected dependencies
|
|
|
|
protected dialog: MatDialog,
|
|
|
|
protected language: TranslateService,
|
|
|
|
protected formService: FormService,
|
|
|
|
protected router: Router,
|
|
|
|
protected uiNotificationService: UiNotificationService,
|
|
|
|
protected httpErrorHandlingService: HttpErrorHandlingService,
|
|
|
|
protected filterService: FilterService,
|
|
|
|
protected datePipe: DatePipe,
|
|
|
|
protected route: ActivatedRoute,
|
|
|
|
protected queryParamsService: QueryParamsService,
|
|
|
|
// Rest dependencies. Inject any other needed deps here:
|
|
|
|
public authService: AuthService,
|
|
|
|
public enumUtils: EnumUtils,
|
|
|
|
private dmpBlueprintService: DmpBlueprintService,
|
|
|
|
private logger: LoggingService,
|
2023-10-25 16:47:48 +02:00
|
|
|
private dmpBlueprintEditorService: DmpBlueprintEditorService,
|
|
|
|
private fileUtils: FileUtils,
|
|
|
|
private matomoService: MatomoService,
|
2024-02-09 21:46:05 +01:00
|
|
|
public descriptionTemplateService: DescriptionTemplateService,
|
2024-02-20 13:58:16 +01:00
|
|
|
public referenceTypeService: ReferenceTypeService,
|
2024-02-27 15:27:26 +01:00
|
|
|
public semanticsService: SemanticsService,
|
|
|
|
public prefillingSourceService: PrefillingSourceService
|
2023-10-24 09:40:26 +02:00
|
|
|
) {
|
|
|
|
super(dialog, language, formService, router, uiNotificationService, httpErrorHandlingService, filterService, datePipe, route, queryParamsService);
|
2023-07-25 14:51:29 +02:00
|
|
|
}
|
2023-10-20 17:01:09 +02:00
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
ngOnInit(): void {
|
2023-10-25 16:47:48 +02:00
|
|
|
this.matomoService.trackPageView('Admin: DMP Blueprints');
|
2023-10-24 09:40:26 +02:00
|
|
|
super.ngOnInit();
|
2024-02-06 19:41:57 +01:00
|
|
|
this.initModelFlags(this.route.snapshot.data['action']);
|
2024-02-07 16:59:11 +01:00
|
|
|
this.route.data.subscribe(d => {
|
|
|
|
this.initModelFlags(d['action']);
|
|
|
|
});
|
2024-03-07 16:14:39 +01:00
|
|
|
if ((this.formGroup.get('definition').get('sections') as FormArray).length == 0) {
|
|
|
|
this.addSection();
|
|
|
|
}
|
2024-02-06 19:41:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private initModelFlags(action: string): void {
|
|
|
|
if (action == 'clone') {
|
|
|
|
this.isNew = false;
|
|
|
|
this.isClone = true;
|
|
|
|
this.isNewVersion = false;
|
|
|
|
} else if (action == 'new-version') {
|
|
|
|
this.isNew = false;
|
|
|
|
this.isClone = false;
|
|
|
|
this.isNewVersion = true;
|
|
|
|
} else {
|
|
|
|
this.isNew = true;
|
|
|
|
this.isClone = false;
|
|
|
|
this.isNewVersion = false;
|
|
|
|
}
|
2023-07-25 14:51:29 +02:00
|
|
|
}
|
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
getItem(itemId: Guid, successFunction: (item: DmpBlueprint) => void) {
|
|
|
|
this.dmpBlueprintService.getSingle(itemId, DmpBlueprintEditorResolver.lookupFields())
|
|
|
|
.pipe(map(data => data as DmpBlueprint), takeUntil(this._destroyed))
|
|
|
|
.subscribe(
|
|
|
|
data => successFunction(data),
|
|
|
|
error => this.onCallbackError(error)
|
|
|
|
);
|
2023-07-25 14:51:29 +02:00
|
|
|
}
|
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
prepareForm(data: DmpBlueprint) {
|
|
|
|
try {
|
|
|
|
this.editorModel = data ? new DmpBlueprintEditorModel().fromModel(data) : new DmpBlueprintEditorModel();
|
|
|
|
this.isDeleted = data ? data.isActive === IsActive.Inactive : false;
|
|
|
|
this.buildForm();
|
|
|
|
} catch (error) {
|
|
|
|
this.logger.error('Could not parse dmpBlueprint item: ' + data + error);
|
|
|
|
this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error);
|
2023-07-25 14:51:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
buildForm() {
|
|
|
|
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.authService.hasPermission(AppPermission.EditDmpBlueprint));
|
|
|
|
this.dmpBlueprintEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
|
2024-02-07 16:13:13 +01:00
|
|
|
if (this.isFinalized || this.isDeleted) {
|
2023-10-27 17:56:19 +02:00
|
|
|
this.formGroup.disable();
|
|
|
|
}
|
2024-02-07 16:13:13 +01:00
|
|
|
const action = this.route.snapshot.data['action'];
|
|
|
|
if (action && action == 'new-version') {
|
|
|
|
this.formGroup.enable();
|
|
|
|
}
|
2023-07-25 14:51:29 +02:00
|
|
|
}
|
2023-10-20 17:01:09 +02:00
|
|
|
|
2024-01-25 19:55:42 +01:00
|
|
|
refreshData(id?: Guid): void {
|
|
|
|
this.getItem(id ?? this.editorModel.id, (data: DmpBlueprint) => this.prepareForm(data));
|
2023-09-11 07:59:47 +02:00
|
|
|
}
|
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
refreshOnNavigateToData(id?: Guid): void {
|
|
|
|
this.formGroup.markAsPristine();
|
2024-01-25 19:55:42 +01:00
|
|
|
if (this.isNew) {
|
|
|
|
let route = [];
|
|
|
|
route.push('/dmp-blueprints/' + id);
|
|
|
|
this.router.navigate(route, { queryParams: { 'lookup': this.queryParamsService.serializeLookup(this.lookupParams), 'lv': ++this.lv }, replaceUrl: true, relativeTo: this.route });
|
2023-10-24 09:40:26 +02:00
|
|
|
} else {
|
2024-01-25 19:55:42 +01:00
|
|
|
this.refreshData(id);
|
2023-09-11 07:59:47 +02:00
|
|
|
}
|
2023-09-27 11:54:18 +02:00
|
|
|
}
|
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
persistEntity(onSuccess?: (response) => void): void {
|
2024-02-09 21:46:05 +01:00
|
|
|
if (this.isNew && !this.isClone && !this.isNewVersion) {
|
2024-02-06 19:41:57 +01:00
|
|
|
const formData = this.formService.getValue(this.formGroup.value) as DmpBlueprintPersist;
|
|
|
|
|
|
|
|
this.dmpBlueprintService.persist(formData)
|
|
|
|
.pipe(takeUntil(this._destroyed)).subscribe(
|
|
|
|
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
|
|
|
|
error => this.onCallbackError(error)
|
|
|
|
);
|
|
|
|
} else if (this.isNewVersion && !this.isNew && !this.isClone) {
|
|
|
|
const formData = this.formService.getValue(this.formGroup.value) as NewVersionDmpBlueprintPersist;
|
|
|
|
|
|
|
|
this.dmpBlueprintService.newVersion(formData)
|
|
|
|
.pipe(takeUntil(this._destroyed)).subscribe(
|
|
|
|
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
|
|
|
|
error => this.onCallbackError(error)
|
|
|
|
);
|
|
|
|
}
|
2018-10-05 17:00:54 +02:00
|
|
|
}
|
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
formSubmit(): void {
|
|
|
|
this.formService.touchAllFormFields(this.formGroup);
|
2024-03-07 16:14:39 +01:00
|
|
|
console.log(this.formGroup)
|
2024-02-07 15:03:45 +01:00
|
|
|
if (!this.isFormValid()) {
|
|
|
|
return;
|
|
|
|
}
|
2018-10-05 17:00:54 +02:00
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
this.persistEntity();
|
2018-10-05 17:00:54 +02:00
|
|
|
}
|
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
public delete() {
|
|
|
|
const value = this.formGroup.value;
|
|
|
|
if (value.id) {
|
|
|
|
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
|
|
|
maxWidth: '300px',
|
|
|
|
data: {
|
|
|
|
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
|
|
|
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
|
|
|
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL')
|
|
|
|
}
|
2018-11-27 18:33:17 +01:00
|
|
|
});
|
2023-10-24 09:40:26 +02:00
|
|
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
|
|
|
if (result) {
|
|
|
|
this.dmpBlueprintService.delete(value.id).pipe(takeUntil(this._destroyed))
|
|
|
|
.subscribe(
|
2024-01-25 19:55:42 +01:00
|
|
|
complete => this.cancel(),
|
2023-10-24 09:40:26 +02:00
|
|
|
error => this.onCallbackError(error)
|
|
|
|
);
|
2021-06-22 15:48:46 +02:00
|
|
|
}
|
2019-02-25 17:53:36 +01:00
|
|
|
});
|
|
|
|
}
|
2019-01-18 18:03:45 +01:00
|
|
|
}
|
2019-07-23 17:01:51 +02:00
|
|
|
|
2023-10-24 09:40:26 +02:00
|
|
|
clearErrorModel() {
|
|
|
|
this.editorModel.validationErrorModel.clear();
|
|
|
|
this.formService.validateAllFormFields(this.formGroup);
|
2019-07-23 17:01:51 +02:00
|
|
|
}
|
|
|
|
|
2023-10-25 16:47:48 +02:00
|
|
|
//
|
|
|
|
//
|
|
|
|
// Sections
|
|
|
|
//
|
|
|
|
//
|
|
|
|
addSection(): void {
|
2024-03-07 16:14:39 +01:00
|
|
|
const formArray = this.formGroup.get('definition').get('sections') as FormArray;
|
|
|
|
formArray.push(this.editorModel.createChildSection(formArray.length));
|
|
|
|
this.addField(formArray.length - 1);
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
removeSection(sectionIndex: number): void {
|
|
|
|
(this.formGroup.get('definition').get('sections') as FormArray).removeAt(sectionIndex);
|
|
|
|
(this.formGroup.get('definition').get('sections') as FormArray).controls.forEach((section, index) => {
|
|
|
|
section.get('ordinal').setValue(index + 1);
|
|
|
|
});
|
2024-01-18 10:59:42 +01:00
|
|
|
|
|
|
|
//Reapply validators
|
|
|
|
DmpBlueprintEditorModel.reApplySectionValidators(
|
|
|
|
{
|
|
|
|
formGroup: this.formGroup,
|
|
|
|
validationErrorModel: this.editorModel.validationErrorModel
|
|
|
|
}
|
|
|
|
);
|
|
|
|
this.formGroup.get('definition').get('sections').markAsDirty();
|
|
|
|
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
dropSections(event: CdkDragDrop<string[]>) {
|
|
|
|
const sectionsFormArray = (this.formGroup.get('definition').get('sections') as FormArray);
|
|
|
|
|
|
|
|
moveItemInArray(sectionsFormArray.controls, event.previousIndex, event.currentIndex);
|
|
|
|
sectionsFormArray.updateValueAndValidity();
|
|
|
|
sectionsFormArray.controls.forEach((section, index) => {
|
|
|
|
section.get('ordinal').setValue(index + 1);
|
|
|
|
});
|
2024-01-25 14:49:34 +01:00
|
|
|
DmpBlueprintEditorModel.reApplySectionValidators(
|
|
|
|
{
|
|
|
|
formGroup: this.formGroup,
|
|
|
|
validationErrorModel: this.editorModel.validationErrorModel
|
|
|
|
}
|
|
|
|
);
|
|
|
|
this.formGroup.get('definition').get('sections').markAsDirty();
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Fields
|
|
|
|
//
|
|
|
|
//
|
2024-02-09 21:46:05 +01:00
|
|
|
|
|
|
|
addField(sectionIndex: number) {
|
|
|
|
((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields') as FormArray)
|
|
|
|
.push(this.editorModel.createChildField(sectionIndex, ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields') as FormArray).length));
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
2024-02-09 21:46:05 +01:00
|
|
|
removeField(sectionIndex: number, fieldIndex: number): void {
|
|
|
|
const formArray = ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields') as FormArray);
|
|
|
|
formArray.removeAt(fieldIndex);
|
|
|
|
formArray.controls.forEach((section, index) => {
|
2023-10-25 16:47:48 +02:00
|
|
|
section.get('ordinal').setValue(index + 1);
|
|
|
|
});
|
2024-01-25 14:49:34 +01:00
|
|
|
|
2024-02-09 21:46:05 +01:00
|
|
|
//Reapply validators
|
2024-01-25 14:49:34 +01:00
|
|
|
DmpBlueprintEditorModel.reApplySectionValidators(
|
|
|
|
{
|
|
|
|
formGroup: this.formGroup,
|
|
|
|
validationErrorModel: this.editorModel.validationErrorModel
|
|
|
|
}
|
|
|
|
);
|
2024-02-09 21:46:05 +01:00
|
|
|
(this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields').markAsDirty();
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
2024-02-09 21:46:05 +01:00
|
|
|
systemFieldDisabled(systemField: DmpBlueprintSystemFieldType) {
|
|
|
|
return (this.formGroup.get('definition').get('sections') as FormArray)?.controls.some(x => (x.get('fields') as FormArray).controls.some(y => (y as UntypedFormGroup).get('systemFieldType')?.value === systemField));
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
2024-02-09 21:46:05 +01:00
|
|
|
fieldCategoryChanged(sectionIndex: number, fieldIndex: number) {
|
2024-01-18 10:59:42 +01:00
|
|
|
//Reapply validators
|
|
|
|
DmpBlueprintEditorModel.reApplySectionValidators(
|
|
|
|
{
|
|
|
|
formGroup: this.formGroup,
|
|
|
|
validationErrorModel: this.editorModel.validationErrorModel
|
|
|
|
}
|
|
|
|
);
|
|
|
|
(this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields').markAsDirty();
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
dropFields(event: CdkDragDrop<string[]>, sectionIndex: number) {
|
|
|
|
const fieldsFormArray = ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields') as FormArray);
|
|
|
|
|
|
|
|
moveItemInArray(fieldsFormArray.controls, event.previousIndex, event.currentIndex);
|
|
|
|
fieldsFormArray.updateValueAndValidity();
|
|
|
|
fieldsFormArray.controls.forEach((section, index) => {
|
|
|
|
section.get('ordinal').setValue(index + 1);
|
|
|
|
});
|
2024-01-25 14:49:34 +01:00
|
|
|
|
|
|
|
DmpBlueprintEditorModel.reApplySectionValidators({
|
|
|
|
formGroup: this.formGroup,
|
|
|
|
validationErrorModel: this.editorModel.validationErrorModel
|
|
|
|
}
|
|
|
|
);
|
|
|
|
(this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('fields').markAsDirty();
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
2024-01-29 12:13:30 +01:00
|
|
|
//Description Templates
|
2023-10-25 16:47:48 +02:00
|
|
|
|
2024-02-09 21:46:05 +01:00
|
|
|
removeAllDescriptionTemplates(matCheckBox: MatCheckboxChange, sectionIndex: number) {
|
|
|
|
if (matCheckBox.checked == false) {
|
2024-01-29 12:13:30 +01:00
|
|
|
const descriptionTemplateSize = ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray).length;
|
2024-02-09 21:46:05 +01:00
|
|
|
for (let i = 0; i < descriptionTemplateSize; i++) this.removeDescriptionTemplate(sectionIndex, 0);
|
2024-01-29 12:13:30 +01:00
|
|
|
}
|
2024-01-25 14:49:34 +01:00
|
|
|
}
|
2023-10-25 16:47:48 +02:00
|
|
|
|
2024-01-29 12:13:30 +01:00
|
|
|
addDescriptionTemplate(sectionIndex: number): void {
|
2024-02-09 21:46:05 +01:00
|
|
|
const descriptionTempaltesArray = (this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray;
|
2024-01-29 12:13:30 +01:00
|
|
|
descriptionTempaltesArray.push(this.editorModel.createChildDescriptionTemplate(sectionIndex, ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray).length));
|
|
|
|
}
|
|
|
|
|
2024-02-09 21:46:05 +01:00
|
|
|
getUsedDescriptionTemplateGroupIds(): Guid[] {
|
2024-01-29 12:13:30 +01:00
|
|
|
let excludedGroupIds: Guid[] = [];
|
|
|
|
(this.formGroup.get('definition').get('sections') as FormArray).controls.forEach((section, index) => {
|
|
|
|
const descriptionTempaltesArray = (this.formGroup.get('definition').get('sections') as FormArray).at(index).get('descriptionTemplates') as FormArray;
|
2024-02-09 21:46:05 +01:00
|
|
|
if (descriptionTempaltesArray.length > 1) {
|
2024-01-29 12:13:30 +01:00
|
|
|
descriptionTempaltesArray.controls.forEach((template, index) => {
|
2024-02-09 21:46:05 +01:00
|
|
|
if (template.get('descriptionTemplateGroupId').value != undefined) excludedGroupIds.push(template.get('descriptionTemplateGroupId').value as Guid);
|
2024-01-29 12:13:30 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
});
|
2024-02-09 21:46:05 +01:00
|
|
|
|
2024-01-29 12:13:30 +01:00
|
|
|
return excludedGroupIds;
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
2024-01-29 12:13:30 +01:00
|
|
|
removeDescriptionTemplate(sectionIndex: number, descriptionTemplateIndex: number): void {
|
2024-02-09 21:46:05 +01:00
|
|
|
const descriptionTempaltesArray = (this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray;
|
2024-01-29 12:13:30 +01:00
|
|
|
descriptionTempaltesArray.removeAt(descriptionTemplateIndex);
|
2024-01-18 10:59:42 +01:00
|
|
|
|
2024-01-29 12:13:30 +01:00
|
|
|
DmpBlueprintEditorModel.reApplySectionValidators(
|
|
|
|
{
|
|
|
|
formGroup: this.formGroup,
|
|
|
|
validationErrorModel: this.editorModel.validationErrorModel
|
|
|
|
}
|
|
|
|
);
|
|
|
|
descriptionTempaltesArray.markAsDirty();
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
2024-01-29 12:13:30 +01:00
|
|
|
dropDescriptionTemplates(event: CdkDragDrop<string[]>, sectionIndex: number) {
|
|
|
|
const descriptionTemplatesFormArray = ((this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates') as FormArray);
|
|
|
|
|
|
|
|
moveItemInArray(descriptionTemplatesFormArray.controls, event.previousIndex, event.currentIndex);
|
|
|
|
descriptionTemplatesFormArray.updateValueAndValidity();
|
|
|
|
|
|
|
|
DmpBlueprintEditorModel.reApplySectionValidators({
|
|
|
|
formGroup: this.formGroup,
|
|
|
|
validationErrorModel: this.editorModel.validationErrorModel
|
|
|
|
}
|
|
|
|
);
|
|
|
|
(this.formGroup.get('definition').get('sections') as FormArray).at(sectionIndex).get('descriptionTemplates').markAsDirty();
|
|
|
|
}
|
2023-10-25 16:47:48 +02:00
|
|
|
|
|
|
|
|
2024-01-25 19:55:42 +01:00
|
|
|
onPreviewDescriptionTemplate(event: DescriptionTemplate, sectionId: Guid) {
|
|
|
|
const dialogRef = this.dialog.open(DescriptionTemplatePreviewDialogComponent, {
|
|
|
|
width: '590px',
|
|
|
|
minHeight: '200px',
|
|
|
|
restoreFocus: false,
|
|
|
|
data: {
|
|
|
|
descriptionTemplateId: event.id
|
|
|
|
},
|
|
|
|
panelClass: 'custom-modalbox'
|
|
|
|
});
|
|
|
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
|
|
|
// if (result) {
|
|
|
|
// let blueprints = this.sectionsArray().at(sectionIndex).get('descriptionTemplates').value;//this.formGroup.get('blueprints').value;
|
|
|
|
// const blueprint: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor();
|
|
|
|
// blueprint.id = Guid.create().toString();
|
|
|
|
// blueprint.descriptionTemplateId = event.id;
|
|
|
|
// blueprint.label = event.label;
|
|
|
|
// blueprints.push(blueprint.buildForm());
|
|
|
|
// this.sectionsArray().at(sectionIndex).get('descriptionTemplates').setValue(blueprints);//this.formGroup.get('blueprints').setValue(blueprints);
|
|
|
|
// this.blueprintsAutoCompleteConfiguration = {
|
|
|
|
// filterFn: this.filterProfiles.bind(this),
|
|
|
|
// initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
|
|
|
// displayFn: (item) => item['label'],
|
|
|
|
// titleFn: (item) => item['label'],
|
|
|
|
// subtitleFn: (item) => item['description'],
|
|
|
|
// popupItemActionIcon: 'visibility'
|
|
|
|
// };
|
|
|
|
// }
|
|
|
|
});
|
|
|
|
}
|
2023-10-25 16:47:48 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
checkValidity() {
|
|
|
|
this.formService.touchAllFormFields(this.formGroup);
|
|
|
|
if (!this.isFormValid()) { return false; }
|
|
|
|
let errorMessages = [];
|
|
|
|
if (!this.hasTitle()) {
|
|
|
|
errorMessages.push("Title should be set.");
|
|
|
|
}
|
|
|
|
if (!this.hasDescription()) {
|
|
|
|
errorMessages.push("Description should be set.");
|
|
|
|
}
|
|
|
|
if (!this.hasDescriptionTemplates()) {
|
|
|
|
errorMessages.push("At least one section should have description templates.");
|
|
|
|
}
|
|
|
|
if (errorMessages.length > 0) {
|
|
|
|
this.showValidationErrorsDialog(undefined, errorMessages);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
hasTitle(): boolean {
|
|
|
|
const dmpBlueprint: DmpBlueprintPersist = this.formGroup.value;
|
2024-02-09 21:46:05 +01:00
|
|
|
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category == DmpBlueprintFieldCategory.System) && (field as SystemFieldInSection).systemFieldType === DmpBlueprintSystemFieldType.Title));
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
hasDescription(): boolean {
|
|
|
|
const dmpBlueprint: DmpBlueprintPersist = this.formGroup.value;
|
2024-02-09 21:46:05 +01:00
|
|
|
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category == DmpBlueprintFieldCategory.System) && (field as SystemFieldInSection).systemFieldType === DmpBlueprintSystemFieldType.Description));
|
2023-10-25 16:47:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
hasDescriptionTemplates(): boolean {
|
|
|
|
const dmpBlueprint: DmpBlueprintPersist = this.formGroup.value;
|
|
|
|
return dmpBlueprint.definition.sections.some(section => section.hasTemplates == true);
|
|
|
|
}
|
|
|
|
|
|
|
|
private showValidationErrorsDialog(projectOnly?: boolean, errmess?: string[]) {
|
|
|
|
|
|
|
|
const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, {
|
|
|
|
disableClose: true,
|
|
|
|
autoFocus: false,
|
|
|
|
restoreFocus: false,
|
|
|
|
data: {
|
|
|
|
errorMessages: errmess,
|
|
|
|
projectOnly: projectOnly
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public cancel(): void {
|
|
|
|
this.router.navigate(['/dmp-blueprints']);
|
|
|
|
}
|
|
|
|
|
|
|
|
finalize() {
|
|
|
|
if (this.checkValidity()) {
|
|
|
|
this.formGroup.get('status').setValue(DmpBlueprintStatus.Finalized);
|
|
|
|
this.formSubmit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
downloadXML(): void {
|
|
|
|
const blueprintId = this.formGroup.get('id').value;
|
|
|
|
if (blueprintId == null) return;
|
|
|
|
this.dmpBlueprintService.downloadXML(blueprintId)
|
|
|
|
.pipe(takeUntil(this._destroyed))
|
|
|
|
.subscribe(response => {
|
|
|
|
const blob = new Blob([response.body], { type: 'application/xml' });
|
|
|
|
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
|
|
|
|
|
|
|
|
FileSaver.saveAs(blob, filename);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|