-
-
-
-

{{'DMP-BLUEPRINT-EDITOR.TITLE.NEW' | translate}}

-

- {{'DMP-BLUEPRINT-EDITOR.TITLE.CLONE' | translate}} - {{formGroup.get('label').value}} -

-

{{formGroup.get('label').value}}

-
-
-
- -
-
- -
-
- -
+ +
+
+
+

{{'DMP-BLUEPRINT-EDITOR.TITLE.NEW' | translate}}

+

+ {{'DMP-BLUEPRINT-EDITOR.TITLE.CLONE' | translate}} + {{formGroup.get('label').value}} +

+

{{formGroup.get('label').value}}

-
- - - -
- - Name - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -

Sections

- - -
-
- + +
+ + Name + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +

Sections

+ +
+
+
+ + + Section {{sectionIndex + 1}} + drag_indicator + +
+ + + Section name + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + + Section description + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
- - - Section {{sectionIndex + 1}} - drag_indicator - -
-
-
- - Section name - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -
-
- - Section description - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -
+ +
+
+
+ + System fields + + {{f.label}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+
+
-
-
+
+
+
-
- - System fields - - {{f.label}} - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -
-
- - -
-
-
- -
- -
-
- -
-
-
-
-
- {{fieldIndex + 1}} -
-
- drag_indicator -
-
-
- -
- - System Field - - -
-
- - Label - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -
-
- - Placeholder - - -
-
- - Description - - -
-
- Required -
-
- delete - {{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} -
-
- - -
- - Type - - - {{getExtraFieldTypeValue(extraFieldType)}} - - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -
-
- - Label - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -
-
- - Placeholder - - -
-
- - Description - - -
-
- - Required - -
-
- delete - {{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} -
-
- -
+
+
+
+ {{fieldIndex + 1}}
- +
+ drag_indicator +
+
+ + + +
+ + System Field + + +
+
+ + Label + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + Placeholder + + +
+
+ + Description + + +
+
+ Required +
+
+ delete + {{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} +
+
+ + +
+ + Type + + + {{getExtraFieldTypeValue(extraFieldType)}} + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + Label + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + Placeholder + + +
+
+ + Description + + +
+
+ + Required + +
+
+ delete + {{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} +
+
+
- -
- -
-
- -
-
-
- - Description Templates -
-
+
+
+ +
+
+ +
+
+
+ + Description Templates + +
+
+
+ +
-
- -
- -
-
-
- - Label - - -
-
- - Min Multiplicity - - -
-
- - Max Multiplicity - - -
-
-
-
-
-
- -
-
- -
- delete - {{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} -
-
+
--> +
+
+
+
+ + Label + + +
+
+ + Min Multiplicity + + +
+
+ + Max Multiplicity + +
- +
+ +
+
+ +
+ delete + {{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} +
+
- -
-
-
- -
+
+
+ + +
+
+
+
-
-
- -
-
-
- -
+
+
+
+
- - - -
+
+
+ +
+
+ + +
+ \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts index 7dff3cc02..75f199026 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts @@ -1,657 +1,795 @@ -import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; -import { HttpClient } from '@angular/common/http'; -import { AfterViewInit, Component } from '@angular/core'; -import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Component, OnInit } from '@angular/core'; +import { UntypedFormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute, Params, Router } from '@angular/router'; -import { DmpBlueprintFieldDataType } from '@app/core/common/enum/dmp-blueprint-field-type'; -import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status'; -import { DmpBlueprintType } from '@app/core/common/enum/dmp-blueprint-type'; -import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; -import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; -import { DmpBlueprint, ExtraFieldType, FieldCategory, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; -import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { ActivatedRoute, Router } from '@angular/router'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; -import { DmpService } from '@app/core/services/dmp/dmp.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; -import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; -import { DmpBlueprintExternalAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dmp-blueprint/editor/external-autocomplete/dmp-blueprint-external-autocomplete-field-editor.model'; // import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; -import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; -import { BaseComponent } from '@common/base/base.component'; +import { DatePipe } from '@angular/common'; +import { AppPermission } from '@app/core/common/enum/permission.enum'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { LoggingService } from '@app/core/services/logging/logging-service'; +import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; +import { BaseEditor } from '@common/base/base-editor'; import { FormService } from '@common/forms/form-service'; -import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component'; -import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; +import { FilterService } from '@common/modules/text-filter/filter-service'; import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; -import * as FileSaver from 'file-saver'; -import { Observable, of as observableOf } from 'rxjs'; import { map, takeUntil } from 'rxjs/operators'; -import { DescriptionTemplatesInSectionEditor, DmpBlueprintEditor, FieldInSectionEditor, SectionDmpBlueprintEditor } from './dmp-blueprint-editor.model'; -import { DmpBlueprintEditorModel } from './dmp-profile-editor.model'; +import { DmpBlueprintEditorModel } from './dmp-blueprint-editor.model'; +import { DmpBlueprintEditorResolver } from './dmp-blueprint-editor.resolver'; +import { DmpBlueprintEditorService } from './dmp-blueprint-editor.service'; +import { DmpBlueprint, DmpBlueprintPersist } from '@app/core/model/dmp-blueprint/dmp-blueprint'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category'; @Component({ selector: 'app-dmp-blueprint-editor-component', templateUrl: 'dmp-blueprint-editor.component.html', - styleUrls: ['./dmp-blueprint-editor.component.scss'] + styleUrls: ['./dmp-blueprint-editor.component.scss'], + providers: [DmpBlueprintEditorService] }) -export class DmpBlueprintEditorComponent extends BaseComponent implements AfterViewInit { +export class DmpBlueprintEditorComponent extends BaseEditor implements OnInit { isNew = true; - isClone = false; - viewOnly = false; - dmpBlueprintEditorModel = new DmpBlueprintEditorModel(); - dmpBlueprintEditor = new DmpBlueprintEditor(); + isDeleted = false; formGroup: UntypedFormGroup = null; - host: string; - dmpBlueprintId: string; - // breadCrumbs: Observable; + showInactiveDetails = false; + dmpBlueprintSectionFieldCategory = DmpBlueprintSectionFieldCategory; - dmpBlueprintsFormGroup: UntypedFormGroup = null; - blueprintsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; + protected get canDelete(): boolean { + return !this.isDeleted && !this.isNew && this.hasPermission(this.authService.permissionEnum.DeleteDmpBlueprint); + } - fieldList = [ - { label: 'Title', type: SystemFieldType.TEXT }, - { label: 'Description', type: SystemFieldType.HTML_TEXT }, - { label: 'Researchers', type: SystemFieldType.RESEARCHERS }, - { label: 'Organizations', type: SystemFieldType.ORGANIZATIONS }, - { label: 'Language', type: SystemFieldType.LANGUAGE }, - { label: 'Contact', type: SystemFieldType.CONTACT }, - { label: 'Funder', type: SystemFieldType.FUNDER }, - { label: 'Grant', type: SystemFieldType.GRANT }, - { label: 'Project', type: SystemFieldType.PROJECT }, - { label: 'License', type: SystemFieldType.LICENSE }, - { label: 'Access Rights', type: SystemFieldType.ACCESS_RIGHTS } - ]; - systemFieldListPerSection: Array> = new Array(); - descriptionTemplatesPerSection: Array> = new Array>(); + protected get canSave(): boolean { + return !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditDmpBlueprint); + } + + protected get canFinalize(): boolean { + return !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditDmpBlueprint); + } + + + private hasPermission(permission: AppPermission): boolean { + return this.authService.hasPermission(permission) || this.editorModel?.permissions?.includes(permission); + } 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 _service: DmpService, - private route: ActivatedRoute, - private router: Router, - private language: TranslateService, - private enumUtils: EnumUtils, - private uiNotificationService: UiNotificationService, - private formService: FormService, - private fb: UntypedFormBuilder, - private configurationService: ConfigurationService, - private httpClient: HttpClient, - private matomoService: MatomoService, - private dialog: MatDialog + private logger: LoggingService, + private dmpBlueprintEditorService: DmpBlueprintEditorService ) { - super(); - this.host = configurationService.server; + super(dialog, language, formService, router, uiNotificationService, httpErrorHandlingService, filterService, datePipe, route, queryParamsService); } - ngAfterViewInit() { - this.matomoService.trackPageView('Admin: DMP Profile Edit'); - - 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' - }; - - this.route.params - .pipe(takeUntil(this._destroyed)) - .subscribe((params: Params) => { - this.dmpBlueprintId = params['id']; - const cloneId = params['cloneid']; - - if (this.dmpBlueprintId != null) { - this.isNew = false; - this.dmpBlueprintService.getSingleBlueprint(this.dmpBlueprintId).pipe(map(data => data as any)) - .pipe(takeUntil(this._destroyed)) - .subscribe(data => { - this.dmpBlueprintEditor = new DmpBlueprintEditor().fromModel(data); - this.formGroup = this.dmpBlueprintEditor.buildForm(); - this.buildSystemFields(); - this.fillDescriptionTemplatesInMultAutocomplete(); - if (this.dmpBlueprintEditor.status == DmpBlueprintStatus.Finalized) { - this.formGroup.disable(); - this.viewOnly = true - } - // this.breadCrumbs = observableOf([{ - // parentComponentName: 'DmpBlueprintListingComponent', - // label: this.language.instant('NAV-BAR.TEMPLATE'), - // url: '/dmp-blueprints/' + this.dmpBlueprintId - // }]); - }); - } else if (cloneId != null) { - this.isClone = true; - this.dmpBlueprintService.clone(cloneId).pipe(map(data => data as any), takeUntil(this._destroyed)) - .subscribe( - data => { - this.dmpBlueprintEditor = new DmpBlueprintEditor().fromModel(data); - this.dmpBlueprintEditor.id = null; - this.dmpBlueprintEditor.status = DmpBlueprintStatus.Draft; - this.formGroup = this.dmpBlueprintEditor.buildForm(); - this.buildSystemFields(); - this.fillDescriptionTemplatesInMultAutocomplete(); - }, - error => this.onCallbackError(error) - ); - } else { - this.dmpBlueprintEditorModel = new DmpBlueprintEditorModel(); - this.dmpBlueprintEditor = new DmpBlueprintEditor(); - setTimeout(() => { - // this.formGroup = this.dmpBlueprintModel.buildForm(); - // this.addField(); - this.dmpBlueprintEditor.status = DmpBlueprintStatus.Draft; - this.formGroup = this.dmpBlueprintEditor.buildForm(); - }); - // this.breadCrumbs = observableOf([{ - // parentComponentName: 'DmpBlueprintListingComponent', - // label: this.language.instant('NAV-BAR.TEMPLATE'), - // url: '/dmp-blueprints/' + this.dmpBlueprintId - // }]); - } - }); - + ngOnInit(): void { + super.ngOnInit(); } - buildSystemFields() { - const sections = this.sectionsArray().controls.length; - for (let i = 0; i < sections; i++) { - let systemFieldsInSection = new Array(); - this.fieldsArray(i).controls.forEach((field) => { - if ((field.get('category').value == FieldCategory.SYSTEM || field.get('category').value == 'SYSTEM')) { - systemFieldsInSection.push(this.fieldList.find(f => f.type == field.get('type').value).type); - } - }) - this.systemFieldListPerSection.push(systemFieldsInSection); - } - } - - fillDescriptionTemplatesInMultAutocomplete() { - const sections = this.sectionsArray().controls.length; - for (let i = 0; i < sections; i++) { - let descriptionTemplatesInSection = new Array(); - this.descriptionTemplatesArray(i).controls.forEach((template) => { - descriptionTemplatesInSection.push({ id: template.value.descriptionTemplateId, label: template.value.label, description: "" }); - }) - this.descriptionTemplatesPerSection.push(descriptionTemplatesInSection); - } - } - - checkForProfiles(event, sectionIndex: number) { - if (event.checked === false) { - this.descriptionTemplatesPerSection[sectionIndex] = new Array(); - this.descriptionTemplatesArray(sectionIndex).clear(); - } - } - - filterProfiles(value: string): Observable { - const request = new DataTableRequest(null, null, { fields: ['+label'] }); - const criteria = new DatasetProfileCriteria(); - criteria.like = value; - request.criteria = criteria; - return this._service.searchDmpBlueprints(request); - } - - sectionsArray(): UntypedFormArray { - //return this.dmpBlueprintsFormGroup.get('sections') as FormArray; - return this.formGroup.get('definition').get('sections') as UntypedFormArray; - } - - addSection(): void { - const section: SectionDmpBlueprintEditor = new SectionDmpBlueprintEditor(); - section.id = Guid.create().toString(); - section.ordinal = this.sectionsArray().length + 1; - section.hasTemplates = false; - this.sectionsArray().push(section.buildForm()); - this.systemFieldListPerSection.push(new Array()); - } - - removeSection(sectionIndex: number): void { - this.systemFieldListPerSection.splice(sectionIndex, 1); - this.sectionsArray().removeAt(sectionIndex); - this.sectionsArray().controls.forEach((section, index) => { - section.get('ordinal').setValue(index + 1); - }); - } - - fieldsArray(sectionIndex: number): UntypedFormArray { - return this.sectionsArray().at(sectionIndex).get('fields') as UntypedFormArray; - } - - addField(sectionIndex: number, fieldCategory: FieldCategory, fieldType?: number): void { - const field: FieldInSectionEditor = new FieldInSectionEditor(); - field.id = Guid.create().toString(); - field.ordinal = this.fieldsArray(sectionIndex).length + 1; - field.category = fieldCategory; - if (!isNullOrUndefined(fieldType)) { - field.type = fieldType - } - field.required = (!isNullOrUndefined(fieldType) && (fieldType == 0 || fieldType == 1)) ? true : false; - this.fieldsArray(sectionIndex).push(field.buildForm()); - } - - removeField(sectionIndex: number, fieldIndex: number): void { - this.fieldsArray(sectionIndex).removeAt(fieldIndex); - } - - systemFieldsArray(sectionIndex: number): UntypedFormArray { - return this.sectionsArray().at(sectionIndex).get('systemFields') as UntypedFormArray; - } - - initSystemField(systemField?: SystemFieldType): UntypedFormGroup { - return this.fb.group({ - id: this.fb.control(Guid.create().toString()), - type: this.fb.control(systemField), - label: this.fb.control(''), - placeholder: this.fb.control(''), - description: this.fb.control(''), - required: this.fb.control(true), - ordinal: this.fb.control('') - }); - } - - addSystemField(sectionIndex: number, systemField?: SystemFieldType): void { - this.addField(sectionIndex, FieldCategory.SYSTEM, systemField); - } - - transfromEnumToString(type: SystemFieldType): string { - return this.fieldList.find(f => f.type == type).label; - } - - selectedFieldType(type: SystemFieldType, sectionIndex: number): void { - let index = this.systemFieldListPerSection[sectionIndex].indexOf(type); - if (index == -1) { - this.systemFieldListPerSection[sectionIndex].push(type); - this.addSystemField(sectionIndex, type); - } - else { - this.systemFieldListPerSection[sectionIndex].splice(index, 1); - this.removeSystemField(sectionIndex, type); - } - } - - systemFieldDisabled(systemField: SystemFieldType, sectionIndex: number) { - let i = 0; - for (let s in this.sectionsArray().controls) { - if (i != sectionIndex) { - for (let f of this.fieldsArray(i).controls) { - if ((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField) { - return true; - } - } - } - i++; - } - return false; - } - - removeSystemFieldWithIndex(sectionIndex: number, fieldIndex: number): void { - let type: SystemFieldType = this.fieldsArray(sectionIndex).at(fieldIndex).get('type').value; - let index = this.systemFieldListPerSection[sectionIndex].indexOf(type); - this.systemFieldListPerSection[sectionIndex] = this.systemFieldListPerSection[sectionIndex].filter(types => types != type); - this.fieldsArray(sectionIndex).removeAt(fieldIndex); - } - - removeSystemField(sectionIndex: number, systemField: SystemFieldType): void { - let i = 0; - for (let f of this.fieldsArray(sectionIndex).controls) { - if ((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField) { - this.fieldsArray(sectionIndex).removeAt(i); - return; - } - i++; - } - } - - descriptionTemplatesArray(sectionIndex: number): UntypedFormArray { - return this.sectionsArray().at(sectionIndex).get('descriptionTemplates') as UntypedFormArray; - } - - addDescriptionTemplate(descriptionTemplate, sectionIndex: number): void { - this.descriptionTemplatesArray(sectionIndex).push(this.fb.group({ - label: this.fb.control(descriptionTemplate.value) - })); - } - - removeDescriptionTemplate(sectionIndex: number, templateIndex: number): void { - this.descriptionTemplatesArray(sectionIndex).removeAt(templateIndex); - } - - extraFieldsArray(sectionIndex: number): UntypedFormArray { - return this.sectionsArray().at(sectionIndex).get('extraFields') as UntypedFormArray; - } - - addExtraField(sectionIndex: number): void { - this.addField(sectionIndex, FieldCategory.EXTRA); - } - - removeExtraField(sectionIndex: number, fieldIndex: number): void { - this.fieldsArray(sectionIndex).removeAt(fieldIndex); - } - - getExtraFieldTypes(): Number[] { - let keys: string[] = Object.keys(ExtraFieldType); - keys = keys.slice(0, keys.length / 2); - const values: Number[] = keys.map(Number); - return values; - } - - getExtraFieldTypeValue(extraFieldType: ExtraFieldType): string { - switch (extraFieldType) { - case ExtraFieldType.TEXT: return 'Text'; - case ExtraFieldType.RICH_TEXT: return 'Rich Text'; - case ExtraFieldType.DATE: return 'Date'; - case ExtraFieldType.NUMBER: return 'Number'; - } - } - - drop(event: CdkDragDrop, sectionIndex: number) { - moveItemInArray(this.fieldsArray(sectionIndex).controls, event.previousIndex, event.currentIndex); - moveItemInArray(this.fieldsArray(sectionIndex).value, event.previousIndex, event.currentIndex); - } - - dropSections(event: CdkDragDrop) { - moveItemInArray(this.sectionsArray().controls, event.previousIndex, event.currentIndex); - moveItemInArray(this.sectionsArray().value, event.previousIndex, event.currentIndex); - this.sectionsArray().controls.forEach((section, index) => { - section.get('ordinal').setValue(index + 1); - }); - } - - moveItemInFormArray(formArray: UntypedFormArray, fromIndex: number, toIndex: number): void { - const dir = toIndex > fromIndex ? 1 : -1; - - const item = formArray.at(fromIndex); - for (let i = fromIndex; i * dir < toIndex * dir; i = i + dir) { - const current = formArray.at(i + dir); - formArray.setControl(i, current); - } - formArray.setControl(toIndex, item); - } - - // clearForm(): void{ - // this.dmpBlueprintsFormGroup.reset(); - // } - - onRemoveTemplate(event, sectionIndex: number) { - const blueprints = this.descriptionTemplatesArray(sectionIndex).controls; - const foundIndex = blueprints.findIndex(blueprint => blueprint.get('descriptionTemplateId').value === event.id); - foundIndex !== -1 && this.descriptionTemplatesArray(sectionIndex).removeAt(foundIndex); - } - - // onPreviewTemplate(event, sectionIndex: number) { - // const dialogRef = this.dialog.open(DatasetPreviewDialogComponent, { - // width: '590px', - // minHeight: '200px', - // restoreFocus: false, - // data: { - // template: event - // }, - // 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' - // }; - // } - // }); - // } - - onOptionSelected(item, sectionIndex) { - const blueprint: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor(); - blueprint.id = Guid.create().toString(); - blueprint.descriptionTemplateId = item.id; - blueprint.label = item.label; - this.descriptionTemplatesArray(sectionIndex).push(blueprint.buildForm()); - } - - 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; - } - - formSubmit(): void { - if (this.checkValidity()) - this.onSubmit(); - } - - public isFormValid() { - return this.formGroup.valid; - } - - hasTitle(): boolean { - const dmpBlueprint: DmpBlueprint = this.formGroup.value; - return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === FieldCategory.SYSTEM || field.category as unknown === 'SYSTEM') && field.type === SystemFieldType.TEXT)); - } - - hasDescription(): boolean { - const dmpBlueprint: DmpBlueprint = this.formGroup.value; - return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === FieldCategory.SYSTEM || field.category as unknown === 'SYSTEM') && field.type === SystemFieldType.HTML_TEXT)); - } - - hasDescriptionTemplates(): boolean { - const dmpBlueprint: DmpBlueprint = 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 - }, - }); - - } - - onSubmit(): void { - this.dmpBlueprintService.createBlueprint(this.formGroup.value) - .pipe(takeUntil(this._destroyed)) + getItem(itemId: Guid, successFunction: (item: DmpBlueprint) => void) { + this.dmpBlueprintService.getSingle(itemId, DmpBlueprintEditorResolver.lookupFields()) + .pipe(map(data => data as DmpBlueprint), takeUntil(this._destroyed)) .subscribe( - complete => this.onCallbackSuccess(), + data => successFunction(data), error => this.onCallbackError(error) ); } - onCallbackSuccess(): void { - this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); - this.router.navigate(['/dmp-blueprints']); + 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); + } } - onCallbackError(errorResponse: any) { - this.setErrorModel(errorResponse.error); + buildForm() { + this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.authService.hasPermission(AppPermission.EditDmpBlueprint)); + this.dmpBlueprintEditorService.setValidationErrorModel(this.editorModel.validationErrorModel); + } + + refreshData(): void { + this.getItem(this.editorModel.id, (data: DmpBlueprint) => this.prepareForm(data)); + } + + refreshOnNavigateToData(id?: Guid): void { + this.formGroup.markAsPristine(); + let route = []; + + if (id === null) { + route.push('../..'); + } else if (this.isNew) { + route.push('../' + id); + } else { + route.push('..'); + } + + this.router.navigate(route, { queryParams: { 'lookup': this.queryParamsService.serializeLookup(this.lookupParams), 'lv': ++this.lv }, replaceUrl: true, relativeTo: this.route }); + } + + persistEntity(onSuccess?: (response) => void): void { + 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) + ); + } + + formSubmit(): void { + this.formService.touchAllFormFields(this.formGroup); + if (!this.isFormValid()) { + return; + } + + this.persistEntity(); + } + + 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') + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.dmpBlueprintService.delete(value.id).pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(), + error => this.onCallbackError(error) + ); + } + }); + } + } + + clearErrorModel() { + this.editorModel.validationErrorModel.clear(); this.formService.validateAllFormFields(this.formGroup); } - - public setErrorModel(validationErrorModel: ValidationErrorModel) { - Object.keys(validationErrorModel).forEach(item => { - (this.dmpBlueprintEditor.validationErrorModel)[item] = (validationErrorModel)[item]; - }); - } - - public cancel(): void { - this.router.navigate(['/dmp-blueprints']); - } - - // addField() { - // (this.formGroup.get('definition').get('fields')).push(new DmpBlueprintFieldEditorModel().buildForm()); - // } - - // removeField(index: number) { - // (this.formGroup.get('definition').get('fields')).controls.splice(index, 1); - // } - - getDmpBlueprintFieldDataTypeValues(): Number[] { - let keys: string[] = Object.keys(DmpBlueprintFieldDataType); - keys = keys.slice(0, keys.length / 2); - const values: Number[] = keys.map(Number); - return values; - } - - getDmpBlueprintFieldDataTypeWithLanguage(fieldType: DmpBlueprintFieldDataType): string { - let result = ''; - this.language.get(this.enumUtils.toDmpBlueprintFieldDataTypeString(fieldType)) - .pipe(takeUntil(this._destroyed)) - .subscribe((value: string) => { - result = value; - }); - return result; - } - - getDmpBlueprintFieldTypeValues(): Number[] { - let keys: string[] = Object.keys(DmpBlueprintType); - keys = keys.slice(0, keys.length / 2); - const values: Number[] = keys.map(Number); - return values; - } - - getDmpBlueprintFieldTypeWithLanguage(blueprintType: DmpBlueprintType): string { - let result = ''; - this.language.get(this.enumUtils.toDmpBlueprintTypeString(blueprintType)) - .pipe(takeUntil(this._destroyed)) - .subscribe((value: string) => { - result = value; - }); - return result; - } - - delete() { - this.dialog.open(ConfirmationDialogComponent, { - data: { - isDeleteConfirmation: true, - confirmButton: this.language.instant('DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.CONFIRM-BUTTON'), - cancelButton: this.language.instant("DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.CANCEL-BUTTON"), - message: this.language.instant("DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.MESSAGE") - } - }) - .afterClosed() - .subscribe( - confirmed => { - if (confirmed) { - if (this.formGroup.get('status').value == DmpBlueprintStatus.Draft) { - // this.formGroup.get('status').setValue(DmpBlueprintStatus.Deleted); - this.dmpBlueprintService.createBlueprint(this.formGroup.value) - .pipe(takeUntil(this._destroyed)) - .subscribe( - complete => this.onCallbackSuccess(), - error => this.onCallbackError(error) - ); - } - else { - // this.dmpBlueprintService.delete(this.dmpBlueprintId) - // .pipe(takeUntil(this._destroyed)) - // .subscribe( - // complete => this.onCallbackSuccess(), - // error => { - // if (error.error.statusCode == 674) { - // this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DMP-BLUEPRINT-DELETE'), SnackBarNotificationLevel.Error); - // } else { - // this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); - // } - // } - // ); - } - } - } - ) - - } - - finalize() { - if (this.checkValidity()) { - this.formGroup.get('status').setValue(DmpBlueprintStatus.Finalized); - this.onSubmit(); - } - } - - downloadXML(): void { - this.dmpBlueprintService.downloadXML(this.dmpBlueprintId) - .pipe(takeUntil(this._destroyed)) - .subscribe(response => { - const blob = new Blob([response.body], { type: 'application/xml' }); - const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); - - FileSaver.saveAs(blob, filename); - }); - } - - - getFilenameFromContentDispositionHeader(header: string): string { - const regex: RegExp = new RegExp(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/g); - - const matches = header.match(regex); - let filename: string; - for (let i = 0; i < matches.length; i++) { - const match = matches[i]; - if (match.includes('filename="')) { - filename = match.substring(10, match.length - 1); - break; - } else if (match.includes('filename=')) { - filename = match.substring(9); - break; - } - } - return filename; - } - - isExternalAutocomplete(formGroup: UntypedFormGroup) { - if (formGroup.get('dataType').value == DmpBlueprintFieldDataType.ExternalAutocomplete) { - this.addControl(formGroup); - return true; - } else { - this.removeControl(formGroup); - return false; - } - } - - addControl(formGroup: UntypedFormGroup) { - if (formGroup.get('dataType').value == 3) - formGroup.addControl('externalAutocomplete', new DmpBlueprintExternalAutoCompleteFieldDataEditorModel().buildForm()); - } - - removeControl(formGroup: UntypedFormGroup) { - if (formGroup.get('dataType').value != 3) - formGroup.removeControl('externalAutocomplete'); - } } + + +// extends BaseComponent implements AfterViewInit { + +// isNew = true; +// isClone = false; +// viewOnly = false; +// dmpBlueprintEditorModel = new DmpBlueprintEditorModel(); +// dmpBlueprintEditor = new DmpBlueprintEditor(); +// formGroup: UntypedFormGroup = null; +// host: string; +// dmpBlueprintId: string; +// // breadCrumbs: Observable; + +// dmpBlueprintsFormGroup: UntypedFormGroup = null; + +// blueprintsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; + +// fieldList = [ +// { label: 'Title', type: SystemFieldType.TEXT }, +// { label: 'Description', type: SystemFieldType.HTML_TEXT }, +// { label: 'Researchers', type: SystemFieldType.RESEARCHERS }, +// { label: 'Organizations', type: SystemFieldType.ORGANIZATIONS }, +// { label: 'Language', type: SystemFieldType.LANGUAGE }, +// { label: 'Contact', type: SystemFieldType.CONTACT }, +// { label: 'Funder', type: SystemFieldType.FUNDER }, +// { label: 'Grant', type: SystemFieldType.GRANT }, +// { label: 'Project', type: SystemFieldType.PROJECT }, +// { label: 'License', type: SystemFieldType.LICENSE }, +// { label: 'Access Rights', type: SystemFieldType.ACCESS_RIGHTS } +// ]; +// systemFieldListPerSection: Array> = new Array(); +// descriptionTemplatesPerSection: Array> = new Array>(); + +// constructor( +// private dmpBlueprintService: DmpBlueprintService, +// private _service: DmpService, +// private route: ActivatedRoute, +// private router: Router, +// private language: TranslateService, +// private enumUtils: EnumUtils, +// private uiNotificationService: UiNotificationService, +// private formService: FormService, +// private fb: UntypedFormBuilder, +// private configurationService: ConfigurationService, +// private httpClient: HttpClient, +// private matomoService: MatomoService, +// private dialog: MatDialog +// ) { +// super(); +// this.host = configurationService.server; +// } + +// ngAfterViewInit() { +// this.matomoService.trackPageView('Admin: DMP Profile Edit'); + +// 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' +// }; + +// this.route.params +// .pipe(takeUntil(this._destroyed)) +// .subscribe((params: Params) => { +// this.dmpBlueprintId = params['id']; +// const cloneId = params['cloneid']; + +// if (this.dmpBlueprintId != null) { +// this.isNew = false; +// this.dmpBlueprintService.getSingleBlueprint(this.dmpBlueprintId).pipe(map(data => data as any)) +// .pipe(takeUntil(this._destroyed)) +// .subscribe(data => { +// this.dmpBlueprintEditor = new DmpBlueprintEditor().fromModel(data); +// this.formGroup = this.dmpBlueprintEditor.buildForm(); +// this.buildSystemFields(); +// this.fillDescriptionTemplatesInMultAutocomplete(); +// if (this.dmpBlueprintEditor.status == DmpBlueprintStatus.Finalized) { +// this.formGroup.disable(); +// this.viewOnly = true +// } +// // this.breadCrumbs = observableOf([{ +// // parentComponentName: 'DmpBlueprintListingComponent', +// // label: this.language.instant('NAV-BAR.TEMPLATE'), +// // url: '/dmp-blueprints/' + this.dmpBlueprintId +// // }]); +// }); +// } else if (cloneId != null) { +// this.isClone = true; +// this.dmpBlueprintService.clone(cloneId).pipe(map(data => data as any), takeUntil(this._destroyed)) +// .subscribe( +// data => { +// this.dmpBlueprintEditor = new DmpBlueprintEditor().fromModel(data); +// this.dmpBlueprintEditor.id = null; +// this.dmpBlueprintEditor.status = DmpBlueprintStatus.Draft; +// this.formGroup = this.dmpBlueprintEditor.buildForm(); +// this.buildSystemFields(); +// this.fillDescriptionTemplatesInMultAutocomplete(); +// }, +// error => this.onCallbackError(error) +// ); +// } else { +// this.dmpBlueprintEditorModel = new DmpBlueprintEditorModel(); +// this.dmpBlueprintEditor = new DmpBlueprintEditor(); +// setTimeout(() => { +// // this.formGroup = this.dmpBlueprintModel.buildForm(); +// // this.addField(); +// this.dmpBlueprintEditor.status = DmpBlueprintStatus.Draft; +// this.formGroup = this.dmpBlueprintEditor.buildForm(); +// }); +// // this.breadCrumbs = observableOf([{ +// // parentComponentName: 'DmpBlueprintListingComponent', +// // label: this.language.instant('NAV-BAR.TEMPLATE'), +// // url: '/dmp-blueprints/' + this.dmpBlueprintId +// // }]); +// } +// }); + +// } + +// buildSystemFields() { +// const sections = this.sectionsArray().controls.length; +// for (let i = 0; i < sections; i++) { +// let systemFieldsInSection = new Array(); +// this.fieldsArray(i).controls.forEach((field) => { +// if ((field.get('category').value == FieldCategory.SYSTEM || field.get('category').value == 'SYSTEM')) { +// systemFieldsInSection.push(this.fieldList.find(f => f.type == field.get('type').value).type); +// } +// }) +// this.systemFieldListPerSection.push(systemFieldsInSection); +// } +// } + +// fillDescriptionTemplatesInMultAutocomplete() { +// const sections = this.sectionsArray().controls.length; +// for (let i = 0; i < sections; i++) { +// let descriptionTemplatesInSection = new Array(); +// this.descriptionTemplatesArray(i).controls.forEach((template) => { +// descriptionTemplatesInSection.push({ id: template.value.descriptionTemplateId, label: template.value.label, description: "" }); +// }) +// this.descriptionTemplatesPerSection.push(descriptionTemplatesInSection); +// } +// } + +// checkForProfiles(event, sectionIndex: number) { +// if (event.checked === false) { +// this.descriptionTemplatesPerSection[sectionIndex] = new Array(); +// this.descriptionTemplatesArray(sectionIndex).clear(); +// } +// } + +// filterProfiles(value: string): Observable { +// const request = new DataTableRequest(null, null, { fields: ['+label'] }); +// const criteria = new DatasetProfileCriteria(); +// criteria.like = value; +// request.criteria = criteria; +// return this._service.searchDmpBlueprints(request); +// } + +// sectionsArray(): UntypedFormArray { +// //return this.dmpBlueprintsFormGroup.get('sections') as FormArray; +// return this.formGroup.get('definition').get('sections') as UntypedFormArray; +// } + +// addSection(): void { +// const section: SectionDmpBlueprintEditor = new SectionDmpBlueprintEditor(); +// section.id = Guid.create().toString(); +// section.ordinal = this.sectionsArray().length + 1; +// section.hasTemplates = false; +// this.sectionsArray().push(section.buildForm()); +// this.systemFieldListPerSection.push(new Array()); +// } + +// removeSection(sectionIndex: number): void { +// this.systemFieldListPerSection.splice(sectionIndex, 1); +// this.sectionsArray().removeAt(sectionIndex); +// this.sectionsArray().controls.forEach((section, index) => { +// section.get('ordinal').setValue(index + 1); +// }); +// } + +// fieldsArray(sectionIndex: number): UntypedFormArray { +// return this.sectionsArray().at(sectionIndex).get('fields') as UntypedFormArray; +// } + +// addField(sectionIndex: number, fieldCategory: FieldCategory, fieldType?: number): void { +// const field: FieldInSectionEditor = new FieldInSectionEditor(); +// field.id = Guid.create().toString(); +// field.ordinal = this.fieldsArray(sectionIndex).length + 1; +// field.category = fieldCategory; +// if (!isNullOrUndefined(fieldType)) { +// field.type = fieldType +// } +// field.required = (!isNullOrUndefined(fieldType) && (fieldType == 0 || fieldType == 1)) ? true : false; +// this.fieldsArray(sectionIndex).push(field.buildForm()); +// } + +// removeField(sectionIndex: number, fieldIndex: number): void { +// this.fieldsArray(sectionIndex).removeAt(fieldIndex); +// } + +// systemFieldsArray(sectionIndex: number): UntypedFormArray { +// return this.sectionsArray().at(sectionIndex).get('systemFields') as UntypedFormArray; +// } + +// initSystemField(systemField?: SystemFieldType): UntypedFormGroup { +// return this.fb.group({ +// id: this.fb.control(Guid.create().toString()), +// type: this.fb.control(systemField), +// label: this.fb.control(''), +// placeholder: this.fb.control(''), +// description: this.fb.control(''), +// required: this.fb.control(true), +// ordinal: this.fb.control('') +// }); +// } + +// addSystemField(sectionIndex: number, systemField?: SystemFieldType): void { +// this.addField(sectionIndex, FieldCategory.SYSTEM, systemField); +// } + +// transfromEnumToString(type: SystemFieldType): string { +// return this.fieldList.find(f => f.type == type).label; +// } + +// selectedFieldType(type: SystemFieldType, sectionIndex: number): void { +// let index = this.systemFieldListPerSection[sectionIndex].indexOf(type); +// if (index == -1) { +// this.systemFieldListPerSection[sectionIndex].push(type); +// this.addSystemField(sectionIndex, type); +// } +// else { +// this.systemFieldListPerSection[sectionIndex].splice(index, 1); +// this.removeSystemField(sectionIndex, type); +// } +// } + +// systemFieldDisabled(systemField: SystemFieldType, sectionIndex: number) { +// let i = 0; +// for (let s in this.sectionsArray().controls) { +// if (i != sectionIndex) { +// for (let f of this.fieldsArray(i).controls) { +// if ((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField) { +// return true; +// } +// } +// } +// i++; +// } +// return false; +// } + +// removeSystemFieldWithIndex(sectionIndex: number, fieldIndex: number): void { +// let type: SystemFieldType = this.fieldsArray(sectionIndex).at(fieldIndex).get('type').value; +// let index = this.systemFieldListPerSection[sectionIndex].indexOf(type); +// this.systemFieldListPerSection[sectionIndex] = this.systemFieldListPerSection[sectionIndex].filter(types => types != type); +// this.fieldsArray(sectionIndex).removeAt(fieldIndex); +// } + +// removeSystemField(sectionIndex: number, systemField: SystemFieldType): void { +// let i = 0; +// for (let f of this.fieldsArray(sectionIndex).controls) { +// if ((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField) { +// this.fieldsArray(sectionIndex).removeAt(i); +// return; +// } +// i++; +// } +// } + +// descriptionTemplatesArray(sectionIndex: number): UntypedFormArray { +// return this.sectionsArray().at(sectionIndex).get('descriptionTemplates') as UntypedFormArray; +// } + +// addDescriptionTemplate(descriptionTemplate, sectionIndex: number): void { +// this.descriptionTemplatesArray(sectionIndex).push(this.fb.group({ +// label: this.fb.control(descriptionTemplate.value) +// })); +// } + +// removeDescriptionTemplate(sectionIndex: number, templateIndex: number): void { +// this.descriptionTemplatesArray(sectionIndex).removeAt(templateIndex); +// } + +// extraFieldsArray(sectionIndex: number): UntypedFormArray { +// return this.sectionsArray().at(sectionIndex).get('extraFields') as UntypedFormArray; +// } + +// addExtraField(sectionIndex: number): void { +// this.addField(sectionIndex, FieldCategory.EXTRA); +// } + +// removeExtraField(sectionIndex: number, fieldIndex: number): void { +// this.fieldsArray(sectionIndex).removeAt(fieldIndex); +// } + +// getExtraFieldTypes(): Number[] { +// let keys: string[] = Object.keys(ExtraFieldType); +// keys = keys.slice(0, keys.length / 2); +// const values: Number[] = keys.map(Number); +// return values; +// } + +// getExtraFieldTypeValue(extraFieldType: ExtraFieldType): string { +// switch (extraFieldType) { +// case ExtraFieldType.TEXT: return 'Text'; +// case ExtraFieldType.RICH_TEXT: return 'Rich Text'; +// case ExtraFieldType.DATE: return 'Date'; +// case ExtraFieldType.NUMBER: return 'Number'; +// } +// } + +// drop(event: CdkDragDrop, sectionIndex: number) { +// moveItemInArray(this.fieldsArray(sectionIndex).controls, event.previousIndex, event.currentIndex); +// moveItemInArray(this.fieldsArray(sectionIndex).value, event.previousIndex, event.currentIndex); +// } + +// dropSections(event: CdkDragDrop) { +// moveItemInArray(this.sectionsArray().controls, event.previousIndex, event.currentIndex); +// moveItemInArray(this.sectionsArray().value, event.previousIndex, event.currentIndex); +// this.sectionsArray().controls.forEach((section, index) => { +// section.get('ordinal').setValue(index + 1); +// }); +// } + +// moveItemInFormArray(formArray: UntypedFormArray, fromIndex: number, toIndex: number): void { +// const dir = toIndex > fromIndex ? 1 : -1; + +// const item = formArray.at(fromIndex); +// for (let i = fromIndex; i * dir < toIndex * dir; i = i + dir) { +// const current = formArray.at(i + dir); +// formArray.setControl(i, current); +// } +// formArray.setControl(toIndex, item); +// } + +// // clearForm(): void{ +// // this.dmpBlueprintsFormGroup.reset(); +// // } + +// onRemoveTemplate(event, sectionIndex: number) { +// const blueprints = this.descriptionTemplatesArray(sectionIndex).controls; +// const foundIndex = blueprints.findIndex(blueprint => blueprint.get('descriptionTemplateId').value === event.id); +// foundIndex !== -1 && this.descriptionTemplatesArray(sectionIndex).removeAt(foundIndex); +// } + +// // onPreviewTemplate(event, sectionIndex: number) { +// // const dialogRef = this.dialog.open(DatasetPreviewDialogComponent, { +// // width: '590px', +// // minHeight: '200px', +// // restoreFocus: false, +// // data: { +// // template: event +// // }, +// // 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' +// // }; +// // } +// // }); +// // } + +// onOptionSelected(item, sectionIndex) { +// const blueprint: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor(); +// blueprint.id = Guid.create().toString(); +// blueprint.descriptionTemplateId = item.id; +// blueprint.label = item.label; +// this.descriptionTemplatesArray(sectionIndex).push(blueprint.buildForm()); +// } + +// 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; +// } + +// formSubmit(): void { +// if (this.checkValidity()) +// this.onSubmit(); +// } + +// public isFormValid() { +// return this.formGroup.valid; +// } + +// hasTitle(): boolean { +// const dmpBlueprint: DmpBlueprint = this.formGroup.value; +// return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === FieldCategory.SYSTEM || field.category as unknown === 'SYSTEM') && field.type === SystemFieldType.TEXT)); +// } + +// hasDescription(): boolean { +// const dmpBlueprint: DmpBlueprint = this.formGroup.value; +// return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === FieldCategory.SYSTEM || field.category as unknown === 'SYSTEM') && field.type === SystemFieldType.HTML_TEXT)); +// } + +// hasDescriptionTemplates(): boolean { +// const dmpBlueprint: DmpBlueprint = 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 +// }, +// }); + +// } + +// onSubmit(): void { +// this.dmpBlueprintService.createBlueprint(this.formGroup.value) +// .pipe(takeUntil(this._destroyed)) +// .subscribe( +// complete => this.onCallbackSuccess(), +// error => this.onCallbackError(error) +// ); +// } + +// onCallbackSuccess(): void { +// this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); +// this.router.navigate(['/dmp-blueprints']); +// } + +// onCallbackError(errorResponse: any) { +// this.setErrorModel(errorResponse.error); +// this.formService.validateAllFormFields(this.formGroup); +// } + +// public setErrorModel(validationErrorModel: ValidationErrorModel) { +// Object.keys(validationErrorModel).forEach(item => { +// (this.dmpBlueprintEditor.validationErrorModel)[item] = (validationErrorModel)[item]; +// }); +// } + +// public cancel(): void { +// this.router.navigate(['/dmp-blueprints']); +// } + +// // addField() { +// // (this.formGroup.get('definition').get('fields')).push(new DmpBlueprintFieldEditorModel().buildForm()); +// // } + +// // removeField(index: number) { +// // (this.formGroup.get('definition').get('fields')).controls.splice(index, 1); +// // } + +// getDmpBlueprintFieldDataTypeValues(): Number[] { +// let keys: string[] = Object.keys(DmpBlueprintFieldDataType); +// keys = keys.slice(0, keys.length / 2); +// const values: Number[] = keys.map(Number); +// return values; +// } + +// getDmpBlueprintFieldDataTypeWithLanguage(fieldType: DmpBlueprintFieldDataType): string { +// let result = ''; +// this.language.get(this.enumUtils.toDmpBlueprintFieldDataTypeString(fieldType)) +// .pipe(takeUntil(this._destroyed)) +// .subscribe((value: string) => { +// result = value; +// }); +// return result; +// } + +// getDmpBlueprintFieldTypeValues(): Number[] { +// let keys: string[] = Object.keys(DmpBlueprintType); +// keys = keys.slice(0, keys.length / 2); +// const values: Number[] = keys.map(Number); +// return values; +// } + +// getDmpBlueprintFieldTypeWithLanguage(blueprintType: DmpBlueprintType): string { +// let result = ''; +// this.language.get(this.enumUtils.toDmpBlueprintTypeString(blueprintType)) +// .pipe(takeUntil(this._destroyed)) +// .subscribe((value: string) => { +// result = value; +// }); +// return result; +// } + +// delete() { +// this.dialog.open(ConfirmationDialogComponent, { +// data: { +// isDeleteConfirmation: true, +// confirmButton: this.language.instant('DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.CONFIRM-BUTTON'), +// cancelButton: this.language.instant("DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.CANCEL-BUTTON"), +// message: this.language.instant("DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.MESSAGE") +// } +// }) +// .afterClosed() +// .subscribe( +// confirmed => { +// if (confirmed) { +// if (this.formGroup.get('status').value == DmpBlueprintStatus.Draft) { +// // this.formGroup.get('status').setValue(DmpBlueprintStatus.Deleted); +// this.dmpBlueprintService.createBlueprint(this.formGroup.value) +// .pipe(takeUntil(this._destroyed)) +// .subscribe( +// complete => this.onCallbackSuccess(), +// error => this.onCallbackError(error) +// ); +// } +// else { +// // this.dmpBlueprintService.delete(this.dmpBlueprintId) +// // .pipe(takeUntil(this._destroyed)) +// // .subscribe( +// // complete => this.onCallbackSuccess(), +// // error => { +// // if (error.error.statusCode == 674) { +// // this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DMP-BLUEPRINT-DELETE'), SnackBarNotificationLevel.Error); +// // } else { +// // this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); +// // } +// // } +// // ); +// } +// } +// } +// ) + +// } + +// finalize() { +// if (this.checkValidity()) { +// this.formGroup.get('status').setValue(DmpBlueprintStatus.Finalized); +// this.onSubmit(); +// } +// } + +// downloadXML(): void { +// this.dmpBlueprintService.downloadXML(this.dmpBlueprintId) +// .pipe(takeUntil(this._destroyed)) +// .subscribe(response => { +// const blob = new Blob([response.body], { type: 'application/xml' }); +// const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + +// FileSaver.saveAs(blob, filename); +// }); +// } + + +// getFilenameFromContentDispositionHeader(header: string): string { +// const regex: RegExp = new RegExp(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/g); + +// const matches = header.match(regex); +// let filename: string; +// for (let i = 0; i < matches.length; i++) { +// const match = matches[i]; +// if (match.includes('filename="')) { +// filename = match.substring(10, match.length - 1); +// break; +// } else if (match.includes('filename=')) { +// filename = match.substring(9); +// break; +// } +// } +// return filename; +// } + +// isExternalAutocomplete(formGroup: UntypedFormGroup) { +// if (formGroup.get('dataType').value == DmpBlueprintFieldDataType.ExternalAutocomplete) { +// this.addControl(formGroup); +// return true; +// } else { +// this.removeControl(formGroup); +// return false; +// } +// } + +// addControl(formGroup: UntypedFormGroup) { +// if (formGroup.get('dataType').value == 3) +// formGroup.addControl('externalAutocomplete', new DmpBlueprintExternalAutoCompleteFieldDataEditorModel().buildForm()); +// } + +// removeControl(formGroup: UntypedFormGroup) { +// if (formGroup.get('dataType').value != 3) +// formGroup.removeControl('externalAutocomplete'); +// } +// } diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.model.ts b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.model.ts index ab99ca39b..482e1b2ff 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.model.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.model.ts @@ -1,257 +1,356 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; +import { DmpBlueprintExtraFieldDataType } from "@app/core/common/enum/dmp-blueprint-field-type"; +import { DmpBlueprintSectionFieldCategory } from "@app/core/common/enum/dmp-blueprint-section-field-category"; import { DmpBlueprintStatus } from "@app/core/common/enum/dmp-blueprint-status"; -import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, FieldCategory, FieldInSection, SectionDmpBlueprint } from "@app/core/model/dmp/dmp-blueprint/dmp-blueprint"; +import { DmpBlueprintSystemFieldType } from "@app/core/common/enum/dmp-blueprint-system-field-type"; +import { DescriptionTemplatesInSection, DescriptionTemplatesInSectionPersist, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionPersist, DmpBlueprintDefinitionSection, DmpBlueprintDefinitionSectionPersist, DmpBlueprintPersist, FieldInSection, FieldInSectionPersist } from "@app/core/model/dmp-blueprint/dmp-blueprint"; +import { BaseEditorModel } from "@common/base/base-form-editor-model"; import { BackendErrorValidator } from "@common/forms/validation/custom-validator"; import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; -import { ValidationContext } from "@common/forms/validation/validation-context"; +import { Validation, ValidationContext } from "@common/forms/validation/validation-context"; +import { Guid } from "@common/types/guid"; -export class DmpBlueprintEditor { - public id: string; +export class DmpBlueprintEditorModel extends BaseEditorModel implements DmpBlueprintPersist { + label: string; + definition: DmpBlueprintDefinitionEditorModel; + status: DmpBlueprintStatus = DmpBlueprintStatus.Draft; + description: string; + permissions: string[]; + + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor() { super(); } + + public fromModel(item: DmpBlueprint): DmpBlueprintEditorModel { + if (item) { + super.fromModel(item); + this.label = item.label; + this.status = item.status; + this.description = item.description; + this.definition = new DmpBlueprintDefinitionEditorModel().fromModel(item.definition); + } + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup { + if (context == null) { context = this.createValidationContext(); } + + return this.formBuilder.group({ + id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators], + label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators], + status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators], + definition: this.definition.buildForm({ + rootPath: `definition.` + }), + hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators] + }); + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] }); + baseValidationArray.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); + baseValidationArray.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] }); + baseValidationArray.push({ key: 'hash', validators: [] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } +} + +export class DmpBlueprintDefinitionEditorModel implements DmpBlueprintDefinitionPersist { + sections: DmpBlueprintDefinitionSectionEditorModel[] = []; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + public fromModel(item: DmpBlueprintDefinition): DmpBlueprintDefinitionEditorModel { + if (item) { + if (item.sections) { item.sections.map(x => this.sections.push(new DmpBlueprintDefinitionSectionEditorModel().fromModel(x))); } + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = DmpBlueprintDefinitionEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + sections: this.formBuilder.array( + (this.sections ?? []).map( + (item, index) => new DmpBlueprintDefinitionSectionEditorModel( + this.validationErrorModel + ).fromModel(item).buildForm({ + rootPath: `sections[${index}].` + }), context.getValidation('sections') + ) + ), + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'sections', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}sections`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + +} + +export class DmpBlueprintDefinitionSectionEditorModel implements DmpBlueprintDefinitionSectionPersist { + id: Guid; + label: string; + description: string; + ordinal: number; + fields: FieldInSectionEditorModel[] = []; + hasTemplates: boolean; + descriptionTemplates?: DescriptionTemplatesInSectionEditorModel[] = []; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + public fromModel(item: DmpBlueprintDefinitionSection): DmpBlueprintDefinitionSectionEditorModel { + if (item) { + this.id = item.id; + this.label = item.label; + this.description = item.description; + this.ordinal = item.ordinal; + this.hasTemplates = item.hasTemplates; + if (item.fields) { item.fields.map(x => this.fields.push(new FieldInSectionEditorModel().fromModel(x))); } + if (item.descriptionTemplates) { item.descriptionTemplates.map(x => this.descriptionTemplates.push(new DescriptionTemplatesInSectionEditorModel().fromModel(x))); } + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = DmpBlueprintDefinitionSectionEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators], + label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators], + ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal').validators], + description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators], + hasTemplates: [{ value: this.hasTemplates, disabled: disabled }, context.getValidation('hasTemplates').validators], + fields: this.formBuilder.array( + (this.fields ?? []).map( + (item, index) => new FieldInSectionEditorModel( + this.validationErrorModel + ).fromModel(item).buildForm({ + rootPath: `fields[${index}].` + }), context.getValidation('fields') + ) + ), + descriptionTemplates: this.formBuilder.array( + (this.descriptionTemplates ?? []).map( + (item, index) => new DescriptionTemplatesInSectionEditorModel( + this.validationErrorModel + ).fromModel(item).buildForm({ + rootPath: `fields[${index}].` + }), context.getValidation('descriptionTemplates') + ) + ) + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}id`)] }); + baseValidationArray.push({ key: 'label', validators: [Validators.required,BackendErrorValidator(validationErrorModel, `${rootPath}label`)] }); + baseValidationArray.push({ key: 'ordinal', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}ordinal`)] }); + baseValidationArray.push({ key: 'description', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}description`)] }); + baseValidationArray.push({ key: 'hasTemplates', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}hasTemplates`)] }); + baseValidationArray.push({ key: 'fields', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}fields`)] }); + baseValidationArray.push({ key: 'descriptionTemplates', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}descriptionTemplates`)] }); + baseValidationArray.push({ key: 'hash', validators: [] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + +} + +export class FieldInSectionEditorModel implements FieldInSectionPersist { + public id: Guid; + public category: DmpBlueprintSectionFieldCategory; + public dataType: DmpBlueprintExtraFieldDataType; + public systemFieldType: DmpBlueprintSystemFieldType; public label: string; - public definition: DmpBlueprintDefinitionEditor = new DmpBlueprintDefinitionEditor(); - public status: DmpBlueprintStatus; - public created: Date; - public modified: Date; - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + public placeholder: string; + public description: string; + public required: boolean; + public ordinal: number; - fromModel(item: DmpBlueprint): DmpBlueprintEditor { - this.id = item.id; - this.label = item.label; - this.definition = new DmpBlueprintDefinitionEditor().fromModel(item.definition); - this.status = item.status; - this.created = item.created; - this.modified = item.modified; - return this; - } + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); - buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup { - if (context == null) { context = this.createValidationContext(); } - const formGroup = new UntypedFormBuilder().group({ - id: [{ value: this.id, disabled: disabled }, context.getValidation('id')], - label: [{ value: this.label, disabled: disabled }, context.getValidation('label')], - status: [{ value: this.status, disabled: disabled }, context.getValidation('status')], - created: [{ value: this.created, disabled: disabled }, context.getValidation('created')], - modified: [{ value: this.modified, disabled: disabled }, context.getValidation('modified')], - }); - formGroup.addControl('definition', this.definition.buildForm()); - return formGroup; - } + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } - createValidationContext(): ValidationContext { - const baseContext: ValidationContext = new ValidationContext(); - baseContext.validation.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] }); - baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); - baseContext.validation.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] }); - baseContext.validation.push({ key: 'definition', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'definition')] }); - baseContext.validation.push({ key: 'created', validators: [] }); - baseContext.validation.push({ key: 'modified', validators: [] }); - return baseContext; - } - -} - -export class DmpBlueprintDefinitionEditor { - - public sections: SectionDmpBlueprintEditor[] = new Array(); - - fromModel(item: DmpBlueprintDefinition): DmpBlueprintDefinitionEditor { - if (item.sections) { item.sections.map(x => this.sections.push(new SectionDmpBlueprintEditor().fromModel(x))); } - return this; - } - - buildForm(): UntypedFormGroup { - const formBuilder = new UntypedFormBuilder(); - const formGroup = formBuilder.group({}); - const sectionsFormArray = new Array(); - this.sections.forEach(item => { - const form: UntypedFormGroup = item.buildForm(); - sectionsFormArray.push(form); - }); - formGroup.addControl('sections', formBuilder.array(sectionsFormArray)); - return formGroup; - } -} - -export class SectionDmpBlueprintEditor { - public id: string; - public label: string; - public description: string; - public ordinal: number; - public fields: FieldInSectionEditor[] = new Array(); - public hasTemplates: boolean; - public descriptionTemplates: DescriptionTemplatesInSectionEditor[] = new Array(); - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); - - fromModel(item: SectionDmpBlueprint): SectionDmpBlueprintEditor { - this.id = item.id; - this.label = item.label; - this.description = item.description; - this.ordinal = item.ordinal; - if (item.fields) { item.fields.map(x => this.fields.push(new FieldInSectionEditor().fromModel(x))); } - this.hasTemplates = item.hasTemplates; - if (item.descriptionTemplates) { item.descriptionTemplates.map(x => this.descriptionTemplates.push(new DescriptionTemplatesInSectionEditor().fromModel(x))); } - return this; - } - - buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup { - if (context == null) { context = this.createValidationContext(); } - const formGroup = new UntypedFormBuilder().group({ - id: [{ value: this.id, disabled: disabled }, context.getValidation('id')], - label: [{ value: this.label, disabled: disabled }, context.getValidation('label')], - description: [{ value: this.description, disabled: disabled }, context.getValidation('description')], - ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal')], - hasTemplates: [{ value: this.hasTemplates, disabled: disabled }, context.getValidation('hasTemplates')] - }); - const formBuilder = new UntypedFormBuilder(); - const fieldsFormArray = new Array(); - this.fields.forEach(item => { - const form: UntypedFormGroup = item.buildForm(); - fieldsFormArray.push(form); - }); - formGroup.addControl('fields', formBuilder.array(fieldsFormArray)); - const descriptionTemplatesFormArray = new Array(); - this.descriptionTemplates.forEach(item => { - const form: UntypedFormGroup = item.buildForm(); - descriptionTemplatesFormArray.push(form); - }); - formGroup.addControl('descriptionTemplates', formBuilder.array(descriptionTemplatesFormArray)); - return formGroup; - } - - createValidationContext(): ValidationContext { - const baseContext: ValidationContext = new ValidationContext(); - baseContext.validation.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] }); - baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); - baseContext.validation.push({ key: 'description', validators: [BackendErrorValidator(this.validationErrorModel, 'description')] }); - baseContext.validation.push({ key: 'ordinal', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'ordinal')] }); - baseContext.validation.push({ key: 'hasTemplates', validators: [BackendErrorValidator(this.validationErrorModel, 'hasTemplates')] }); - baseContext.validation.push({ key: 'descriptionTemplates', validators: [BackendErrorValidator(this.validationErrorModel, 'descriptionTemplates')] }); - return baseContext; - } -} - -export class FieldInSectionEditor { - public id: string; - public category: FieldCategory; - public type: number; - public label: string; - public placeholder: string; - public description: string; - public required: boolean; - public ordinal: number; - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); - - fromModel(item: FieldInSection): FieldInSectionEditor { + fromModel(item: FieldInSection): FieldInSectionEditorModel { this.id = item.id; this.category = item.category; - this.type = item.type; + this.dataType = item.dataType; + this.systemFieldType = item.systemFieldType; this.label = item.label; - this.placeholder = item.placeholder; - this.description = item.description; - this.required = item.required; - this.ordinal = item.ordinal; + this.placeholder = item.placeholder; + this.description = item.description; + this.required = item.required; + this.ordinal = item.ordinal; return this; } - buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup { - if (context == null) { context = this.createValidationContext(); } - const formGroup = new UntypedFormBuilder().group({ - id: [{ value: this.id, disabled: disabled }, context.getValidation('id')], - category: [{ value: this.category, disabled: disabled }, context.getValidation('category')], - type: [{ value: this.type, disabled: disabled }, context.getValidation('type')], - label: [{ value: this.label, disabled: disabled }, context.getValidation('label')], - placeholder: [{ value: this.placeholder, disabled: disabled }, context.getValidation('placeholder')], - description: [{ value: this.description, disabled: disabled }, context.getValidation('description')], - required: [{ value: this.required, disabled: disabled }, context.getValidation('required')], - ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal')] + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = FieldInSectionEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators], + + category: [{ value: this.category, disabled: disabled }, context.getValidation('category').validators], + dataType: [{ value: this.dataType, disabled: disabled }, context.getValidation('dataType').validators], + systemFieldType: [{ value: this.systemFieldType, disabled: disabled }, context.getValidation('systemFieldType').validators], + label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators], + placeholder: [{ value: this.placeholder, disabled: disabled }, context.getValidation('placeholder').validators], + description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators], + required: [{ value: this.required, disabled: disabled }, context.getValidation('required').validators], + ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal').validators], + }); - return formGroup; } - createValidationContext(): ValidationContext { + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + const baseContext: ValidationContext = new ValidationContext(); - baseContext.validation.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] }); - baseContext.validation.push({ key: 'category', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'category')] }); - baseContext.validation.push({ key: 'type', validators: [BackendErrorValidator(this.validationErrorModel, 'type')] }); - baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); - baseContext.validation.push({ key: 'placeholder', validators: [BackendErrorValidator(this.validationErrorModel, 'placeholder')] }); - baseContext.validation.push({ key: 'description', validators: [BackendErrorValidator(this.validationErrorModel, 'description')] }); - baseContext.validation.push({ key: 'required', validators: [BackendErrorValidator(this.validationErrorModel, 'required')] }); - baseContext.validation.push({ key: 'ordinal', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'ordinal')] }); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}id`)] }); + + baseValidationArray.push({ key: 'category', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}category`)] }); + baseValidationArray.push({ key: 'dataType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}dataType`)] }); + baseValidationArray.push({ key: 'systemFieldType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}systemFieldType`)] }); + baseValidationArray.push({ key: 'label', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}label`)] }); + baseValidationArray.push({ key: 'placeholder', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}placeholder`)] }); + baseValidationArray.push({ key: 'description', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}description`)] }); + baseValidationArray.push({ key: 'required', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}required`)] }); + baseValidationArray.push({ key: 'ordinal', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}ordinal`)] }); + + baseContext.validation = baseValidationArray; return baseContext; } } -export class DescriptionTemplatesInSectionEditor { - public id: string; - public descriptionTemplateId: string; - public label: string; - public minMultiplicity: number; - public maxMultiplicity: number; - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); +export class DescriptionTemplatesInSectionEditorModel implements DescriptionTemplatesInSectionPersist { + id: Guid; + descriptionTemplateId: Guid; + label: string; + minMultiplicity: number; + maxMultiplicity: number; - fromModel(item: DescriptionTemplatesInSection): DescriptionTemplatesInSectionEditor { + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + fromModel(item: DescriptionTemplatesInSection): DescriptionTemplatesInSectionEditorModel { this.id = item.id; this.descriptionTemplateId = item.descriptionTemplateId; - this.label = item.label; - this.minMultiplicity = item.minMultiplicity; - this.maxMultiplicity = item.maxMultiplicity; + this.label = item.label; + this.minMultiplicity = item.minMultiplicity; + this.maxMultiplicity = item.maxMultiplicity; return this; } - buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup { - if (context == null) { context = this.createValidationContext(); } - const formGroup = new UntypedFormBuilder().group({ - id: [{ value: this.id, disabled: disabled }, context.getValidation('id')], - descriptionTemplateId: [{ value: this.descriptionTemplateId, disabled: disabled }, context.getValidation('descriptionTemplateId')], - label: [{ value: this.label, disabled: disabled }, context.getValidation('label')], - minMultiplicity: [{ value: this.minMultiplicity, disabled: disabled }, context.getValidation('minMultiplicity')], - maxMultiplicity: [{ value: this.maxMultiplicity, disabled: disabled }, context.getValidation('maxMultiplicity')] + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = DescriptionTemplatesInSectionEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators], + descriptionTemplateId: [{ value: this.descriptionTemplateId, disabled: disabled }, context.getValidation('descriptionTemplateId').validators], + label: [{ value: this.label, disabled: disabled }, context.getValidation('label').validators], + minMultiplicity: [{ value: this.minMultiplicity, disabled: disabled }, context.getValidation('minMultiplicity').validators], + maxMultiplicity: [{ value: this.maxMultiplicity, disabled: disabled }, context.getValidation('maxMultiplicity').validators], + }); - return formGroup; } - createValidationContext(): ValidationContext { + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + const baseContext: ValidationContext = new ValidationContext(); - baseContext.validation.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] }); - baseContext.validation.push({ key: 'descriptionTemplateId', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'descriptionTemplateId')] }); - baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); - baseContext.validation.push({ key: 'minMultiplicity', validators: [BackendErrorValidator(this.validationErrorModel, 'minMultiplicity')] }); - baseContext.validation.push({ key: 'maxMultiplicity', validators: [BackendErrorValidator(this.validationErrorModel, 'maxMultiplicity')] }); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}id`)] }); + baseValidationArray.push({ key: 'descriptionTemplateId', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}descriptionTemplateId`)] }); + baseValidationArray.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}label`)] }); + baseValidationArray.push({ key: 'minMultiplicity', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}minMultiplicity`)] }); + baseValidationArray.push({ key: 'maxMultiplicity', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}maxMultiplicity`)] }); + + baseContext.validation = baseValidationArray; return baseContext; } -} - -// export class ExtraFieldsInSectionEditor { -// public id: string; -// public label: string; -// public description: string; -// public placeholder: string; -// public type: ExtraFieldType; -// public required: boolean; -// public ordinal: number; - -// fromModel(item: ExtraFieldInSection): ExtraFieldsInSectionEditor { -// this.id = item.id; -// this.label = item.label; -// this.description = item.description; -// this.placeholder = item.placeholder; -// this.type = item.type; -// this.required = item.required; -// this.ordinal = item.ordinal; -// return this; -// } - -// buildForm(): FormGroup { -// const formGroup = new FormBuilder().group({ -// id: [this.id], -// label: [this.label], -// description: [this.description], -// placeholder: [this.placeholder], -// type: [this.type], -// required: [this.required], -// ordinal: [this.ordinal] -// }); -// return formGroup; -// } -// } \ No newline at end of file +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.resolver.ts b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.resolver.ts new file mode 100644 index 000000000..9dadf47c7 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.resolver.ts @@ -0,0 +1,60 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; +import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection, FieldInSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; +import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; +import { BaseEditorResolver } from '@common/base/base-editor.resolver'; +import { Guid } from '@common/types/guid'; +import { takeUntil, tap } from 'rxjs/operators'; +import { nameof } from 'ts-simple-nameof'; + +@Injectable() +export class DmpBlueprintEditorResolver extends BaseEditorResolver { + + constructor(private dmpBlueprintService: DmpBlueprintService, private breadcrumbService: BreadcrumbService) { + super(); + } + + public static lookupFields(): string[] { + return [ + ...BaseEditorResolver.lookupFields(), + nameof(x => x.id), + nameof(x => x.label), + nameof(x => x.status), + nameof(x => x.description), + nameof(x => x.status), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.id)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.label)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.description)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.ordinal)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.hasTemplates)].join('.'), + + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.id)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.category)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.dataType)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.systemFieldType)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.label)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.placeholder)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.description)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.required)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fields), nameof(x => x.ordinal)].join('.'), + + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.id)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.descriptionTemplateId)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.label)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.minMultiplicity)].join('.'), + [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.maxMultiplicity)].join('.'), + nameof(x => x.createdAt), + nameof(x => x.hash), + nameof(x => x.isActive) + ] + } + + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + + const fields = [ + ...DmpBlueprintEditorResolver.lookupFields() + ]; + return this.dmpBlueprintService.getSingle(Guid.parse(route.paramMap.get('id')), fields).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed)); + } +} diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.service.ts b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.service.ts new file mode 100644 index 000000000..6070d257b --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.service.ts @@ -0,0 +1,15 @@ +import { Injectable } from "@angular/core"; +import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; + +@Injectable() +export class DmpBlueprintEditorService { + private validationErrorModel: ValidationErrorModel; + + public setValidationErrorModel(validationErrorModel: ValidationErrorModel): void { + this.validationErrorModel = validationErrorModel; + } + + public getValidationErrorModel(): ValidationErrorModel { + return this.validationErrorModel; + } +} diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-profile-editor.model.ts b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-profile-editor.model.ts deleted file mode 100644 index 8d4d23181..000000000 --- a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-profile-editor.model.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; -import { DmpBlueprintFieldDataType } from '@app/core/common/enum/dmp-blueprint-field-type'; -import { DmpBlueprintType } from '@app/core/common/enum/dmp-blueprint-type'; -import { DmpBlueprint } from '@app/core/model/dmp-blueprint/dmp-blueprint'; -import { DmpBlueprintField } from '@app/core/model/dmp-blueprint/dmp-blueprint-field'; -import { DmpBlueprintDefinition } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; -import { DmpBlueprintExternalAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dmp-blueprint/editor/external-autocomplete/dmp-blueprint-external-autocomplete-field-editor.model'; -import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; - -export class DmpBlueprintEditorModel { - - public id: string; - public label: string; - public definition: DmpBlueprintDefinitionEditorModel = new DmpBlueprintDefinitionEditorModel(); - public status: number; - public created: Date; - public modified: Date; - public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); - - fromModel(item: DmpBlueprint): DmpBlueprintEditorModel { - // this.id = item.id; - // this.label = item.label; - // this.definition = new DmpBlueprintDefinitionEditorModel().fromModel(item.definition); - // this.status = item.status; - // this.created = item.created; - // this.modified = item.modified; - return this; - } - - buildForm(): UntypedFormGroup { - const formGroup = new UntypedFormBuilder().group({ - id: [this.id], - label: [this.label], - status: [this.status], - created: [this.created], - modified: [this.modified] - }); - formGroup.addControl('definition', this.definition.buildForm()); - return formGroup; - } -} - -export class DmpBlueprintDefinitionEditorModel { - - public fields: DmpBlueprintFieldEditorModel[] = new Array(); - - fromModel(item: DmpBlueprintDefinition): DmpBlueprintDefinitionEditorModel { - if (item.fields) { item.fields.map(x => this.fields.push(new DmpBlueprintFieldEditorModel().fromModel(x))); } - return this; - } - - buildForm(): UntypedFormGroup { - const formBuilder = new UntypedFormBuilder(); - const formGroup = formBuilder.group({}); - const fieldsFormArray = new Array(); - this.fields.forEach(item => { - const form: UntypedFormGroup = item.buildForm(); - fieldsFormArray.push(form); - }); - formGroup.addControl('fields', formBuilder.array(fieldsFormArray)); - return formGroup; - } -} - -export class DmpBlueprintFieldEditorModel { - public id: string; - public type: DmpBlueprintType; - public dataType: DmpBlueprintFieldDataType; - public required = false; - public label: string; - public value: any; - public externalAutocomplete?: DmpBlueprintExternalAutoCompleteFieldDataEditorModel; - - fromModel(item: DmpBlueprintField): DmpBlueprintFieldEditorModel { - this.type = item.type; - this.dataType = item.dataType; - this.required = item.required; - this.label = item.label; - this.id = item.id; - this.value = item.value; - if (item.externalAutocomplete) - this.externalAutocomplete = new DmpBlueprintExternalAutoCompleteFieldDataEditorModel().fromModel(item.externalAutocomplete); - return this; - } - - buildForm(): UntypedFormGroup { - const formGroup = new UntypedFormBuilder().group({ - type: [this.type], - id: [this.id], - dataType: [this.dataType], - required: [this.required], - label: [this.label] - }); - if (this.externalAutocomplete) { - formGroup.addControl('externalAutocomplete', this.externalAutocomplete.buildForm()); - } - return formGroup; - } -} diff --git a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts index 98396352e..563ae7ecb 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts @@ -42,8 +42,9 @@ import {FunderFormModel} from "@app/ui/dmp/editor/grant-tab/funder-form-model"; import {ExtraPropertiesFormModel} from "@app/ui/dmp/editor/general-tab/extra-properties-form.model"; import {CloneDialogComponent} from "@app/ui/dmp/clone/clone-dialog/clone-dialog.component"; import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; -import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; @Component({ selector: 'app-drafts', @@ -238,7 +239,7 @@ export class DraftsComponent extends BaseComponent implements OnInit { this.dmpFormGroup = this.dmpModel.buildForm(); if (!isNullOrUndefined(this.formGroup.get('profile').value)) { - this.dmpBlueprintService.getSingleBlueprint(this.formGroup.get('profile').value) + this.dmpBlueprintService.getSingle(this.formGroup.get('profile').value) .pipe(takeUntil(this._destroyed)) .subscribe(result => { this.checkForGrant(result.definition); @@ -258,7 +259,7 @@ export class DraftsComponent extends BaseComponent implements OnInit { let hasGrant = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) { hasGrant = true; } } @@ -272,7 +273,7 @@ export class DraftsComponent extends BaseComponent implements OnInit { let hasFunder = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) { hasFunder = true; } } @@ -286,7 +287,7 @@ export class DraftsComponent extends BaseComponent implements OnInit { let hasProject = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) { hasProject = true; } } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts index e56fd9c63..dc9fea686 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts @@ -43,7 +43,8 @@ import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { HttpClient } from '@angular/common/http'; import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; -import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; @Component({ selector: 'app-recent-edited-activity', @@ -324,7 +325,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn let hasGrant = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) { hasGrant = true; } } @@ -338,7 +339,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn let hasFunder = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) { hasFunder = true; } } @@ -352,7 +353,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn let hasProject = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) { hasProject = true; } } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts index 3d5f407e8..285547fa3 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts @@ -35,7 +35,8 @@ import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { HttpClient } from '@angular/common/http'; import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; -import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; @Component({ selector: 'app-recent-edited-dmp-activity', @@ -277,7 +278,7 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O let hasGrant = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) { hasGrant = true; } } @@ -291,7 +292,7 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O let hasFunder = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) { hasFunder = true; } } @@ -305,7 +306,7 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O let hasProject = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) { hasProject = true; } } diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.ts index b5ed1f52e..6e2ffc9d4 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.ts @@ -10,6 +10,7 @@ import { takeUntil } from 'rxjs/operators'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; import { MatDialog } from '@angular/material/dialog'; import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; +import { Guid } from '@common/types/guid'; @Component({ selector: 'app-dataset-editor-component', @@ -58,7 +59,7 @@ export class DatasetEditorComponent extends BaseComponent { .subscribe(result => { const section = result.definition.sections[dmpSectionIndex]; if(section.hasTemplates){ - const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === profile.id); + const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === Guid.parse(profile.id)); if (foundTemplate !== undefined) { let count = 0; if(this.formGroup.get('dmp').value.datasets != null){ diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts index fa896a0b3..84eea7f58 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts @@ -9,6 +9,7 @@ import { ProgressIndicationService } from "@app/core/services/progress-indicatio import { SingleAutoCompleteConfiguration } from "@app/library/auto-complete/single/single-auto-complete-configuration"; import { PopupNotificationDialogComponent } from "@app/library/notification/popup/popup-notification.component"; import { BaseComponent } from "@common/base/base.component"; +import { Guid } from "@common/types/guid"; import { TranslateService } from "@ngx-translate/core"; import { Observable } from "rxjs"; import { map, takeUntil } from "rxjs/operators"; @@ -65,7 +66,7 @@ export class PrefillDatasetComponent extends BaseComponent implements OnInit { .subscribe(result => { const section = result.definition.sections[dmpSectionIndex]; if (section.hasTemplates) { - const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === profile.id); + const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === Guid.parse(profile.id)); if (foundTemplate !== undefined) { let count = 0; if (this.data.datasetFormGroup.get('dmp').value.datasets != null) { @@ -98,7 +99,7 @@ export class PrefillDatasetComponent extends BaseComponent implements OnInit { .subscribe(result => { const section = result.definition.sections[dmpSectionIndex]; if (section.hasTemplates) { - const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === profile.id); + const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === Guid.parse(profile.id)); if (foundTemplate !== undefined) { let count = 0; if (this.data.datasetFormGroup.get('dmp').value.datasets != null) { diff --git a/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.ts b/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.ts index 927fbba6d..d88eae205 100644 --- a/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.ts +++ b/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.ts @@ -28,7 +28,8 @@ import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog import { MatDialog } from '@angular/material/dialog'; import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; -import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; @Component({ @@ -143,7 +144,7 @@ export class DmpCloneComponent extends BaseComponent implements OnInit { let hasGrant = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) { hasGrant = true; } } @@ -157,7 +158,7 @@ export class DmpCloneComponent extends BaseComponent implements OnInit { let hasFunder = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) { hasFunder = true; } } @@ -171,7 +172,7 @@ export class DmpCloneComponent extends BaseComponent implements OnInit { let hasProject = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) { hasProject = true; } } diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts index 09d3fe54f..e45b3664c 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts @@ -1,61 +1,62 @@ import { Component, OnInit } from '@angular/core'; -import { AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; +import { AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Params, Router } from '@angular/router'; +import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status'; +import { DmpStatus } from '@app/core/common/enum/dmp-status'; +import { Role } from '@app/core/common/enum/role'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; -import { DmpBlueprintDefinition, ExtraFieldType, FieldCategory, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; +import { DmpModel } from '@app/core/model/dmp/dmp'; +import { DmpDatasetProfile } from '@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile'; +import { DmpDatasetProfileSectionsFormModel } from '@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile-sections-form.model'; +import { ExternalSourceItemModel } from '@app/core/model/external-sources/external-source-item'; +import { LanguageInfo } from '@app/core/model/language-info'; +import { LockModel } from '@app/core/model/lock/lock.model'; +import { UserModel } from '@app/core/model/user/user'; +import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; +import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria'; import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria'; +import { LicenseCriteria } from '@app/core/query/license/license-criteria'; +import { RequestItem } from '@app/core/query/request-item'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { LanguageInfoService } from '@app/core/services/culture/language-info-service'; +import { DatasetService } from '@app/core/services/dataset/dataset.service'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; +import { DmpService } from '@app/core/services/dmp/dmp.service'; +import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service'; +import { LockService } from '@app/core/services/lock/lock.service'; +import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { OrganisationService } from '@app/core/services/organisation/organisation.service'; +import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; -import { DmpBlueprintEditor } from '@app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.model'; -import { debounceTime, filter, map, switchMap, takeUntil, tap } from 'rxjs/operators'; +import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate.component'; +import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; +import { GrantEditorModel } from '@app/ui/grant/editor/grant-editor.model'; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { FormService } from '@common/forms/form-service'; +import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component'; +import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { Guid } from '@common/types/guid'; +import { TranslateService } from '@ngx-translate/core'; +import { Observable, interval } from 'rxjs'; +import { map, takeUntil } from 'rxjs/operators'; +import { DatasetPreviewDialogComponent } from '../dataset-preview/dataset-preview-dialog.component'; +import { DmpToDatasetDialogComponent } from '../dmp-to-dataset/dmp-to-dataset-dialog.component'; +import { AddOrganizationComponent } from '../editor/add-organization/add-organization.component'; +import { AddResearcherComponent } from '../editor/add-researcher/add-researcher.component'; +import { AvailableProfilesComponent } from '../editor/available-profiles/available-profiles.component'; import { DmpEditorModel, DmpExtraFieldEditorModel } from '../editor/dmp-editor.model'; import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties-form.model'; import { FunderFormModel } from '../editor/grant-tab/funder-form-model'; import { GrantTabModel } from '../editor/grant-tab/grant-tab-model'; import { ProjectFormModel } from '../editor/grant-tab/project-form-model'; -import { AuthService } from '@app/core/services/auth/auth.service'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; -import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; -import { LanguageInfoService } from '@app/core/services/culture/language-info-service'; -import { LanguageInfo } from '@app/core/model/language-info'; -import { UserModel } from '@app/core/model/user/user'; -import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; -import { TranslateService } from '@ngx-translate/core'; -import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service'; -import { Observable, interval } from 'rxjs'; -import { ExternalSourceItemModel } from '@app/core/model/external-sources/external-source-item'; -import { OrganisationService } from '@app/core/services/organisation/organisation.service'; -import { MatDialog } from '@angular/material/dialog'; -import { AddResearcherComponent } from '../editor/add-researcher/add-researcher.component'; -import { AddOrganizationComponent } from '../editor/add-organization/add-organization.component'; -import { RequestItem } from '@app/core/query/request-item'; -import { LicenseCriteria } from '@app/core/query/license/license-criteria'; -import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; -import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria'; -import { DmpService } from '@app/core/services/dmp/dmp.service'; -import { AvailableProfilesComponent } from '../editor/available-profiles/available-profiles.component'; -import { DatasetPreviewDialogComponent } from '../dataset-preview/dataset-preview-dialog.component'; -import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; -import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component'; -import { DmpStatus } from '@app/core/common/enum/dmp-status'; -import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; -import { DmpModel } from '@app/core/model/dmp/dmp'; -import { ActivatedRoute, Params, Router } from '@angular/router'; -import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; -import { DmpToDatasetDialogComponent } from '../dmp-to-dataset/dmp-to-dataset-dialog.component'; -import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; -import { FormService } from '@common/forms/form-service'; -import { DmpDatasetProfile } from '@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile'; -import { DmpDatasetProfileSectionsFormModel } from '@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile-sections-form.model'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; -import { LockService } from '@app/core/services/lock/lock.service'; -import { Role } from '@app/core/common/enum/role'; -import { LockModel } from '@app/core/model/lock/lock.model'; -import { Guid } from '@common/types/guid'; -import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; -import { GrantEditorModel } from '@app/ui/grant/editor/grant-editor.model'; -import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate.component'; -import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status'; -import { DatasetService } from '@app/core/services/dataset/dataset.service'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintExtraFieldDataType } from '@app/core/common/enum/dmp-blueprint-extra-field-data-type'; +import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; interface Visible { value: boolean; @@ -63,9 +64,9 @@ interface Visible { } @Component({ - selector: 'app-dmp-editor-blueprint', - templateUrl: './dmp-editor-blueprint.component.html', - styleUrls: ['./dmp-editor-blueprint.component.scss'] + selector: 'app-dmp-editor-blueprint', + templateUrl: './dmp-editor-blueprint.component.html', + styleUrls: ['./dmp-editor-blueprint.component.scss'] }) export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent implements OnInit { @@ -83,7 +84,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im hasChanges = false; isDiscarded = false; - isCreateNew = false; + isCreateNew = false; isCreateNewProject = false; isCreateNewFunder = false; @@ -110,7 +111,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im sectionTemplates: Array> = new Array>(); - extraFieldTypesEnum = ExtraFieldType; + extraFieldTypesEnum = DmpBlueprintExtraFieldDataType; private associates: UserModel[] = []; @@ -151,7 +152,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im super(); } - ngOnInit(): void { + ngOnInit(): void { this.matomoService.trackPageView('DMP Editor'); this.route.params .pipe(takeUntil(this._destroyed)) @@ -197,7 +198,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im this.setIsUserOwner(); if (!this.isUserOwner) { - if(this.isUserMember()){ + if (this.isUserMember()) { this.router.navigate(['plans', 'overview', itemId]); return; } @@ -227,11 +228,13 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im .subscribe(x => { this.formChanged(); }); - if(this.lockStatus){ - this.dialog.open(PopupNotificationDialogComponent,{data:{ - title:this.language.instant('DMP-EDITOR.LOCKED.TITLE'), - message:this.language.instant('DMP-EDITOR.LOCKED.MESSAGE') - }, maxWidth:'30em'}); + if (this.lockStatus) { + this.dialog.open(PopupNotificationDialogComponent, { + data: { + title: this.language.instant('DMP-EDITOR.LOCKED.TITLE'), + message: this.language.instant('DMP-EDITOR.LOCKED.MESSAGE') + }, maxWidth: '30em' + }); } }); }); @@ -286,10 +289,10 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im this.formGroup.get('extraProperties').get('language').patchValue('en'); } - try{ + try { const profiles = this.formGroup.get('profiles').value as DmpDatasetProfile[]; - profiles.sort((a,b)=>a.label.localeCompare(b.label)); - }catch{ + profiles.sort((a, b) => a.label.localeCompare(b.label)); + } catch { console.info('Could not sort profiles'); } } @@ -304,7 +307,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im subtitleFn: (item) => item['description'], popupItemActionIcon: 'visibility' }; - } + } extraFieldsArray(): UntypedFormArray { return this.formGroup.get('extraFields') as UntypedFormArray; @@ -313,15 +316,15 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im setIsUserOwner() { if (this.dmp) { const principalId: string = this.authService.userId()?.toString(); - this.isUserOwner = !!this.dmp.users.find(x => (x.role === Role.Owner) && (x.id === principalId) ); + this.isUserOwner = !!this.dmp.users.find(x => (x.role === Role.Owner) && (x.id === principalId)); } } - isUserMember(): boolean{ - try{ + isUserMember(): boolean { + try { const principalId: string = this.authService.userId()?.toString(); - return !!this.dmp.users.find(x => (x.role === Role.Member) && (x.id === principalId) ); - }catch{ + return !!this.dmp.users.find(x => (x.role === Role.Member) && (x.id === principalId)); + } catch { return false; } } @@ -414,7 +417,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im this.saving = true; this.formService.touchAllFormFields(this.formGroup); - if(!this._isDMPDescriptionValid()){ + if (!this._isDMPDescriptionValid()) { const errmess = this._buildDMPDescriptionErrorMessages(); this.showValidationErrorsDialog(undefined, errmess); this.hintErrors = true; @@ -432,13 +435,13 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im selectDefaultBlueprint() { this.dmpBlueprintService.getSingleBlueprint(this.defaultBlueprintId) - .pipe(takeUntil(this._destroyed)) - .subscribe(result => { - this.selectedDmpBlueprintDefinition = result.definition; - this.formGroup.get('profile').setValue(result); - this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; - this.nextStep(); - }); + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.selectedDmpBlueprintDefinition = result.definition; + this.formGroup.get('profile').setValue(result); + this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; + this.nextStep(); + }); } selectBlueprint() { @@ -479,7 +482,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im addDataset(dmpSectionIndex: number) { this.saving = true; - if(!this._isDMPDescriptionValid()){ + if (!this._isDMPDescriptionValid()) { const errmess = this._buildDMPDescriptionErrorMessages(); this.showValidationErrorsDialog(undefined, errmess); this.hintErrors = true; @@ -573,7 +576,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im // On save keep editor position this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); if (dmp) { - if(this.isNew){ + if (this.isNew) { this.router.navigate(['/plans', 'edit', dmp.id]); } let dmpEditorModel: DmpEditorModel; @@ -593,7 +596,8 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im this.formGroup.valueChanges.pipe(takeUntil(this._destroyed)) .subscribe(x => { this.formChanged(); - });}); + }); + }); setTimeout(() => { document.getElementById('editor-form').scrollTop = this.scrollTop; }); this.saving = false; this.isNew = false; @@ -628,10 +632,10 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im this.saving = false; } - editDataset(id: string, isNew: boolean, showModal:boolean = false) { + editDataset(id: string, isNew: boolean, showModal: boolean = false) { - if(showModal){ + if (showModal) { const dialogRef = this.dialog.open(DmpToDatasetDialogComponent, { width: '500px', autoFocus: false, @@ -646,7 +650,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im } } }); - }else{ + } else { if (isNew) { this.router.navigate(['/datasets', 'new', id, this.dmpSectionIndex]); } else { @@ -697,38 +701,38 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im } //checks if the dpm is valid not taking into account the datasets validity - private _isDMPDescriptionValid():boolean{ + private _isDMPDescriptionValid(): boolean { const form: UntypedFormGroup = this.formGroup; - if(form.controls){ + if (form.controls) { return Object.keys(form.controls) - .map(controlName=>{//get validity of each control - if(controlName === 'datasets'){//we dont care if datasets are valid - return true; - } - return !form.get(controlName).invalid;//!! in case the control is disabled, we consider it valid - }) - .reduce((isFormValid,isControlValid)=>{//aggregate validities - return isControlValid && isFormValid; - }, true); + .map(controlName => {//get validity of each control + if (controlName === 'datasets') {//we dont care if datasets are valid + return true; + } + return !form.get(controlName).invalid;//!! in case the control is disabled, we consider it valid + }) + .reduce((isFormValid, isControlValid) => {//aggregate validities + return isControlValid && isFormValid; + }, true); } return true; } private showValidationErrorsDialog(projectOnly?: boolean, errmess?: string[]) { - if(errmess){ + if (errmess) { const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, { disableClose: true, autoFocus: false, restoreFocus: false, data: { - errorMessages:errmess, + errorMessages: errmess, projectOnly: projectOnly }, }); - }else{ + } else { const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, { disableClose: true, autoFocus: false, @@ -742,10 +746,10 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im } - private _buildDMPDescriptionErrorMessages(): string[]{//not including datasets + private _buildDMPDescriptionErrorMessages(): string[] {//not including datasets const errmess: string[] = []; - Object.keys(this.formGroup.controls).forEach(controlName=>{ - if(controlName != 'datasets' && this.formGroup.get(controlName).invalid){ + Object.keys(this.formGroup.controls).forEach(controlName => { + if (controlName != 'datasets' && this.formGroup.get(controlName).invalid) { errmess.push(...this._buildErrorMessagesForAbstractControl(this.formGroup.get(controlName), controlName)); } }) @@ -754,16 +758,16 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im } // takes as an input an abstract control and gets its error messages[] - private _buildErrorMessagesForAbstractControl(aControl: AbstractControl, controlName: string):string[]{ - const errmess:string[] = []; + private _buildErrorMessagesForAbstractControl(aControl: AbstractControl, controlName: string): string[] { + const errmess: string[] = []; - if(aControl.invalid){ + if (aControl.invalid) { - if(aControl.errors){ + if (aControl.errors) { //check if has placeholder - if( (aControl).nativeElement !== undefined && (aControl).nativeElement !== null){ + if ((aControl).nativeElement !== undefined && (aControl).nativeElement !== null) { const placeholder = this._getPlaceHolder(aControl); - if(placeholder){ + if (placeholder) { controlName = placeholder; } } @@ -774,19 +778,19 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im /*in case the aControl is FormControl then the it should have provided its error messages above. No need to check case of FormControl below*/ - if(aControl instanceof UntypedFormGroup){ + if (aControl instanceof UntypedFormGroup) { const fg = aControl as UntypedFormGroup; //check children - Object.keys(fg.controls).forEach(controlName=>{ + Object.keys(fg.controls).forEach(controlName => { errmess.push(...this._buildErrorMessagesForAbstractControl(fg.get(controlName), controlName)); }); - }else if(aControl instanceof UntypedFormArray){ + } else if (aControl instanceof UntypedFormArray) { const fa = aControl as UntypedFormArray; - fa.controls.forEach((control,index)=>{ - errmess.push(... this._buildErrorMessagesForAbstractControl(control, `${controlName} --> ${index+1}`)); + fa.controls.forEach((control, index) => { + errmess.push(... this._buildErrorMessagesForAbstractControl(control, `${controlName} --> ${index + 1}`)); }); } @@ -830,23 +834,23 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im return this.dmpService.searchDmpBlueprints(request); } - registerFormEventsForDmpBlueprint(): void { + registerFormEventsForDmpBlueprint(): void { this.formGroup.get('profile').valueChanges - .pipe( - takeUntil(this._destroyed)) - .subscribe(Option => { - if (Option instanceof Object) { - this.selectedDmpBlueprintDefinition = Option.definition; - this.checkForGrant(); - this.checkForFunder(); - this.checkForProject(); - this.buildExtraFields(); - this.addProfiles(); - } - else { - this.selectedDmpBlueprintDefinition = null; - } - }) + .pipe( + takeUntil(this._destroyed)) + .subscribe(Option => { + if (Option instanceof Object) { + this.selectedDmpBlueprintDefinition = Option.definition; + this.checkForGrant(); + this.checkForFunder(); + this.checkForProject(); + this.buildExtraFields(); + this.addProfiles(); + } + else { + this.selectedDmpBlueprintDefinition = null; + } + }) } private buildExtraFields(): void { @@ -854,10 +858,10 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im this.selectedDmpBlueprintDefinition.sections.forEach(section => section.fields.forEach(field => { if (field.category as unknown == 'EXTRA') { let extraField = new DmpExtraFieldEditorModel(); - extraField.id = field.id; + extraField.id = field.id.toString(); if (!isNullOrUndefined(this.dmp.extraFields)) { - let found = this.dmp.extraFields.find(f => f.id === field.id); - if(found !== undefined) { + let found = this.dmp.extraFields.find(f => Guid.parse(f.id) === field.id); + if (found !== undefined) { extraField.value = found.value; } } @@ -870,7 +874,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im getExtraFieldIndex(id: string): string { let foundFieldIndex: number; (this.formGroup.get('extraFields') as UntypedFormArray).controls.forEach((element, index) => { - if(element.value.id === id) { + if (element.value.id === id) { foundFieldIndex = index; } }); @@ -881,7 +885,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im let hasGrant = false; this.selectedDmpBlueprintDefinition.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) { hasGrant = true; } } @@ -895,7 +899,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im let hasFunder = false; this.selectedDmpBlueprintDefinition.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) { hasFunder = true; } } @@ -909,7 +913,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im let hasProject = false; this.selectedDmpBlueprintDefinition.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) { hasProject = true; } } @@ -920,31 +924,31 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im } private addProfiles(profiles?: DmpDatasetProfile[]) { - for(let i = 0; i < this.selectedDmpBlueprintDefinition.sections.length; i++){ + for (let i = 0; i < this.selectedDmpBlueprintDefinition.sections.length; i++) { this.sectionTemplates.push(new Array()); } const templates: Array = new Array(); this.selectedDmpBlueprintDefinition.sections.forEach(section => { if (profiles !== undefined) { - profiles.filter(profile => profile.data.dmpSectionIndex.includes(section.ordinal - 1)).forEach(profile => this.sectionTemplates[section.ordinal - 1].push({id: profile.descriptionTemplateId, label: profile.label, description: ""})); + profiles.filter(profile => profile.data.dmpSectionIndex.includes(section.ordinal - 1)).forEach(profile => this.sectionTemplates[section.ordinal - 1].push({ id: profile.descriptionTemplateId, label: profile.label, description: "" })); } else { section.descriptionTemplates.forEach(template => { - this.sectionTemplates[section.ordinal - 1].push({id: template.descriptionTemplateId, label: template.label, description: ""}) - let found: DmpDatasetProfile = templates.find(dmpDatasetProfile => dmpDatasetProfile.descriptionTemplateId == template.descriptionTemplateId); + this.sectionTemplates[section.ordinal - 1].push({ id: template.descriptionTemplateId.toString(), label: template.label, description: "" }) + let found: DmpDatasetProfile = templates.find(dmpDatasetProfile => Guid.parse(dmpDatasetProfile.descriptionTemplateId) == template.descriptionTemplateId); if (found === undefined) { - let data: DmpDatasetProfileSectionsFormModel= new DmpDatasetProfileSectionsFormModel(); + let data: DmpDatasetProfileSectionsFormModel = new DmpDatasetProfileSectionsFormModel(); data.dmpSectionIndex.push(section.ordinal - 1); let id = null; if (profiles !== undefined) { - let existedProfile = profiles.find(profile => profile.descriptionTemplateId == template.descriptionTemplateId); + let existedProfile = profiles.find(profile => Guid.parse(profile.descriptionTemplateId) == template.descriptionTemplateId); if (existedProfile !== undefined) { id = existedProfile.id; } } let profile: DmpDatasetProfile = { id: id, - descriptionTemplateId: template.descriptionTemplateId, + descriptionTemplateId: template.descriptionTemplateId.toString(), label: template.label, data: data }; @@ -960,7 +964,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im } - dmpBlueprintAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { + dmpBlueprintAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { filterFn: this.dmpBlueprintSearch.bind(this), initialItems: (extraData) => this.dmpBlueprintSearch(''), displayFn: (item) => item['label'], @@ -976,7 +980,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im return this.dmpBlueprintService.getPagedBlueprint(request).pipe(map(x => x.data)); } - getLanguageInfos(): LanguageInfo[] { + getLanguageInfos(): LanguageInfo[] { return this.languageInfoService.getLanguageInfoValues(); } @@ -992,7 +996,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im return associates; } - organisationsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = { + organisationsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = { filterFn: this.filterOrganisations.bind(this), initialItems: (excludedItems: any[]) => this.filterOrganisations('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), displayFn: (item) => item['name'], @@ -1007,7 +1011,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im subtitleFn: (item) => item['tag'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['tag'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE')) }; - // Researchers + // Researchers filterResearchers(value: string): Observable { return this.externalSourcesService.searchDMPResearchers({ criteria: { name: value, like: null } }); } @@ -1075,7 +1079,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im }); } - showToggleButton() { + showToggleButton() { return (!this.isFinalized && this.isUserOwner) || this.isClone; } @@ -1119,7 +1123,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im }; } - else{ + else { this.sectionTemplates[sectionIndex] = this.sectionTemplates[sectionIndex].filter(sectionProfile => sectionProfile.id !== event.id); profiles = profiles.filter(sectionProfile => sectionProfile.descriptionTemplateId !== event.id); this.formGroup.get('profiles').setValue(profiles); @@ -1129,18 +1133,18 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im addProfile(event, sectionIndex: number) { const profiles = this.formGroup.get('profiles').value as DmpDatasetProfile[]; let found = profiles.find((value) => value.id === event.id); - if(found !== undefined) { - if(found.data.dmpSectionIndex.indexOf(sectionIndex) === -1){ + if (found !== undefined) { + if (found.data.dmpSectionIndex.indexOf(sectionIndex) === -1) { found.data.dmpSectionIndex.push(sectionIndex); } - else{ + else { this.sectionTemplates[sectionIndex].pop(); } } - else{ + else { let dmpDatasetProfileSection: DmpDatasetProfileSectionsFormModel = new DmpDatasetProfileSectionsFormModel(); dmpDatasetProfileSection.dmpSectionIndex = [sectionIndex]; - profiles.push({id: null, descriptionTemplateId: event.id, label: event.label, data: dmpDatasetProfileSection}); + profiles.push({ id: null, descriptionTemplateId: event.id, label: event.label, data: dmpDatasetProfileSection }); } this.formGroup.get('profiles').setValue(profiles); } @@ -1169,8 +1173,8 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im } }); } - onOptionSelected(event, sectionIndex: number){ - try{ + onOptionSelected(event, sectionIndex: number) { + try { this.addProfile(event, sectionIndex); // const profileCounts: Map = new Map(); // profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id): 0 ) + 1)); @@ -1183,7 +1187,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im // }); // duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1)); // profiles.sort((a,b)=> a.label.localeCompare(b.label)); - }catch{ + } catch { console.info('Could not sort Dataset Templates') } } diff --git a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.ts index cdf9e9e86..b19660994 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.ts @@ -1,27 +1,27 @@ -import { BaseComponent } from '@common/base/base.component'; -import { OnInit, Component, Input, Output, EventEmitter } from '@angular/core'; -import { UntypedFormGroup, FormArray } from '@angular/forms'; -import { TranslateService } from '@ngx-translate/core'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; -import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; -import { map, takeUntil } from 'rxjs/operators'; -import { Observable } from 'rxjs'; -import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { UntypedFormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; -import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; -import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria'; +import { ActivatedRoute, Router } from '@angular/router'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; -import { DmpService } from '@app/core/services/dmp/dmp.service'; +import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; +import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria'; +import { RequestItem } from '@app/core/query/request-item'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; +import { DmpService } from '@app/core/services/dmp/dmp.service'; +import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; +import { DatasetDescriptionFormEditorModel } from '@app/ui/misc/dataset-description-form/dataset-description-form.model'; +import { BaseComponent } from '@common/base/base.component'; +import { TranslateService } from '@ngx-translate/core'; +import { Observable } from 'rxjs'; +import { map, takeUntil } from 'rxjs/operators'; +import { DatasetPreviewDialogComponent } from '../../dataset-preview/dataset-preview-dialog.component'; import { AvailableProfilesComponent } from '../available-profiles/available-profiles.component'; import { DmpEditorModel } from '../dmp-editor.model'; -import { Router, Params, ActivatedRoute } from '@angular/router'; -import { RequestItem } from '@app/core/query/request-item'; -import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service'; -import { DatasetDescriptionFormEditorModel } from '@app/ui/misc/dataset-description-form/dataset-description-form.model'; -import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service'; -import { DatasetPreviewDialogComponent } from '../../dataset-preview/dataset-preview-dialog.component'; -import { DmpBlueprintDefinition } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; @Component({ selector: 'dataset-info', @@ -66,10 +66,10 @@ export class DatasetInfoComponent extends BaseComponent implements OnInit { ngOnInit() { - try{ - const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[]; - profiles.sort((a,b)=>a.label.localeCompare(b.label)); - }catch{ + try { + const profiles = this.formGroup.get('profiles').value as { id: string, label: string }[]; + profiles.sort((a, b) => a.label.localeCompare(b.label)); + } catch { console.info('Could not sort profiles'); } @@ -245,11 +245,11 @@ export class DatasetInfoComponent extends BaseComponent implements OnInit { } }); } - onOptionSelected(){ - try{ - const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[]; + onOptionSelected() { + try { + const profiles = this.formGroup.get('profiles').value as { id: string, label: string }[]; const profileCounts: Map = new Map(); - profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id): 0 ) + 1)); + profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id) : 0) + 1)); const duplicateProfiles = profiles.filter((value) => { let isOk = profileCounts.get(value.id) > 1; if (isOk) { @@ -258,8 +258,8 @@ export class DatasetInfoComponent extends BaseComponent implements OnInit { return isOk; }); duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1)); - profiles.sort((a,b)=> a.label.localeCompare(b.label)); - }catch{ + profiles.sort((a, b) => a.label.localeCompare(b.label)); + } catch { console.info('Could not sort Dataset Templates') } } diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts index 3abd6c700..2f2c3d340 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts @@ -6,9 +6,7 @@ import { ActivatedRoute, Params, Router } from '@angular/router'; import { DmpStatus } from '@app/core/common/enum/dmp-status'; import { Role } from "@app/core/common/enum/role"; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; -import { DmpBlueprintListing } from '@app/core/model/dmp-blueprint/dmp-blueprint-listing'; import { DmpModel } from '@app/core/model/dmp/dmp'; -import { DmpBlueprintDefinition } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; import { LockModel } from '@app/core/model/lock/lock.model'; import { UserModel } from '@app/core/model/user/user'; import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; @@ -47,6 +45,7 @@ import { Observable, interval, of as observableOf } from 'rxjs'; import { map, takeUntil } from 'rxjs/operators'; import { DmpToDatasetDialogComponent } from '../dmp-to-dataset/dmp-to-dataset-dialog.component'; import { ExtraPropertiesFormModel } from './general-tab/extra-properties-form.model'; +import { DmpBlueprint, DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; @Component({ selector: 'app-dmp-editor-component', @@ -83,7 +82,7 @@ export class DmpEditorComponent extends CheckDeactivateBaseComponent implements associatedUsers: Array; people: Array; - filteredOptions: DmpBlueprintListing[]; + filteredOptions: DmpBlueprint[]; selectedDmpBlueprintDefinition: DmpBlueprintDefinition; DynamicDmpFieldResolverComponent: any; diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts index 6cfacea36..ffd71195b 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts @@ -1,5 +1,5 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; -import { DmpBlueprintFieldDataType } from '@app/core/common/enum/dmp-blueprint-field-type'; +import { DmpBlueprintExtraFieldDataType } from '@app/core/common/enum/dmp-blueprint-field-type'; import { DmpBlueprintType } from '@app/core/common/enum/dmp-blueprint-type'; import { DmpStatus } from '@app/core/common/enum/dmp-status'; import { DmpBlueprintField } from '@app/core/model/dmp-blueprint/dmp-blueprint-field'; @@ -218,7 +218,7 @@ export class DmpDynamicFieldDependencyEditorModel { export class DmpDefinitionFieldEditorModel implements DmpBlueprintField { public id: string; public type: DmpBlueprintType; - public dataType: DmpBlueprintFieldDataType; + public dataType: DmpBlueprintExtraFieldDataType; public required = false; public label: string; public value: any; diff --git a/dmp-frontend/src/app/ui/dmp/editor/dynamic-field-resolver/dynamic-dmp-field-resolver.component.html b/dmp-frontend/src/app/ui/dmp/editor/dynamic-field-resolver/dynamic-dmp-field-resolver.component.html index f12101db5..a70b0e056 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dynamic-field-resolver/dynamic-dmp-field-resolver.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/dynamic-field-resolver/dynamic-dmp-field-resolver.component.html @@ -1,6 +1,5 @@ -
+
-
-
+
+//TODO: dtziotzios +--> + diff --git a/dmp-frontend/src/app/ui/dmp/editor/dynamic-field-resolver/dynamic-dmp-field-resolver.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dynamic-field-resolver/dynamic-dmp-field-resolver.component.ts index 367d02406..9b1475771 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dynamic-field-resolver/dynamic-dmp-field-resolver.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dynamic-field-resolver/dynamic-dmp-field-resolver.component.ts @@ -1,8 +1,8 @@ import { Component, Input, OnDestroy, OnInit, SimpleChanges } from '@angular/core'; import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; -import { DmpBlueprintFieldDataType } from '@app/core/common/enum/dmp-blueprint-field-type'; +import { DmpBlueprintExtraFieldDataType } from '@app/core/common/enum/dmp-blueprint-field-type'; import { DmpBlueprintType } from '@app/core/common/enum/dmp-blueprint-type'; -import { DmpBlueprintDefinition } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { DmpBlueprintExternalAutocompleteCriteria } from '@app/core/query/dmp/dmp-profile-external-autocomplete-criteria'; import { RequestItem } from '@app/core/query/request-item'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; @@ -17,7 +17,7 @@ import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/sing export class DynamicDmpFieldResolverComponent implements OnInit, OnDestroy { - dmpBlueprintFieldDataType = DmpBlueprintFieldDataType; + dmpBlueprintFieldDataType = DmpBlueprintExtraFieldDataType; dmpBlueprintTypeEnum = DmpBlueprintType; singleAutocompleteMap: { [id: string]: SingleAutoCompleteConfiguration; } = {}; multiAutocompleteMap: { [id: string]: MultipleAutoCompleteConfiguration; } = {}; @@ -35,29 +35,30 @@ export class DynamicDmpFieldResolverComponent implements OnInit, OnDestroy { this.createControleFields(); if (this.dmpBlueprintDefinition) { - this.dmpBlueprintDefinition.fields.forEach( - field => { - if (field.externalAutocomplete) { - if (field.externalAutocomplete.multiAutoComplete) { - const multiConf: MultipleAutoCompleteConfiguration = { - filterFn: this.externalAutocomplete.bind(this, field), - initialItems: (extraData) => this.externalAutocomplete('', field.id), - displayFn: (item) => item['label'], - titleFn: (item) => item['label'] - } - this.multiAutocompleteMap[field.id] = multiConf; - } else { - const singleConf: SingleAutoCompleteConfiguration = { - filterFn: this.externalAutocomplete.bind(this, field), - initialItems: (extraData) => this.externalAutocomplete('', field.id), - displayFn: (item) => item['label'], - titleFn: (item) => item['label'] - } - this.singleAutocompleteMap[field.id] = singleConf; - } - } - } - ); + // this.dmpBlueprintDefinition.fields.forEach( + // field => { + // if (field.externalAutocomplete) { + // if (field.externalAutocomplete.multiAutoComplete) { + // const multiConf: MultipleAutoCompleteConfiguration = { + // filterFn: this.externalAutocomplete.bind(this, field), + // initialItems: (extraData) => this.externalAutocomplete('', field.id), + // displayFn: (item) => item['label'], + // titleFn: (item) => item['label'] + // } + // this.multiAutocompleteMap[field.id] = multiConf; + // } else { + // const singleConf: SingleAutoCompleteConfiguration = { + // filterFn: this.externalAutocomplete.bind(this, field), + // initialItems: (extraData) => this.externalAutocomplete('', field.id), + // displayFn: (item) => item['label'], + // titleFn: (item) => item['label'] + // } + // this.singleAutocompleteMap[field.id] = singleConf; + // } + // } + // } + // ); + //TODO: dtziotzios } } @@ -72,12 +73,13 @@ export class DynamicDmpFieldResolverComponent implements OnInit, OnDestroy { const diasableBoolean = this.formGroup.disabled; this.formGroup.addControl('properties', new UntypedFormBuilder().group([])); (this.formGroup.get('properties')).addControl('fields', new UntypedFormBuilder().array([])); - this.dmpBlueprintDefinition.fields.forEach(item => { - (this.formGroup.get('properties').get('fields')).push(new UntypedFormBuilder().group({ - id: [{ value: item.id, disabled: diasableBoolean }], - value: [{ value: item.value, disabled: diasableBoolean }] - })); - }); + // this.dmpBlueprintDefinition.fields.forEach(item => { + // (this.formGroup.get('properties').get('fields')).push(new UntypedFormBuilder().group({ + // id: [{ value: item.id, disabled: diasableBoolean }], + // value: [{ value: item.value, disabled: diasableBoolean }] + // })); + // }); + //TODO: dtziotzios } if (this.dmpBlueprintDefinition == null) { this.formGroup.removeControl('properties'); diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts index 1bb346b94..97af76afd 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts @@ -27,7 +27,7 @@ import { LanguageInfo } from '@app/core/model/language-info'; import { LicenseCriteria } from '@app/core/query/license/license-criteria'; import { AddCostComponent } from '../cost-editor/add-cost/add-cost.component'; import { CostEditorModel } from '../cost-editor/add-cost/add-cost.model'; -import { DmpBlueprintDefinition } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; interface Visible { value: boolean; diff --git a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts index 47ef4410c..431a5092a 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts +++ b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts @@ -28,7 +28,8 @@ import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { HttpClient } from '@angular/common/http'; import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; -import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; @Component({ selector: 'app-dmp-listing-item-component', @@ -196,7 +197,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { let hasGrant = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) { hasGrant = true; } } @@ -210,7 +211,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { let hasFunder = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) { hasFunder = true; } } @@ -224,7 +225,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { let hasProject = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) { hasProject = true; } } diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts index ac586d17b..929862626 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts @@ -46,8 +46,10 @@ import {DepositRepositoriesService} from '@app/core/services/deposit-repositorie import {DepositConfigurationModel} from '@app/core/model/deposit/deposit-configuration'; import {DoiModel} from '@app/core/model/doi/doi'; import {isNullOrUndefined} from '@app/utilities/enhancers/utils'; -import { DmpBlueprintDefinition, FieldCategory, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; +import { Guid } from '@common/types/guid'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; @Component({ selector: 'app-dmp-overview', @@ -230,7 +232,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { let hasGrant = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) { hasGrant = true; } } @@ -244,7 +246,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { let hasFunder = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) { hasFunder = true; } } @@ -258,7 +260,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { let hasProject = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) { hasProject = true; } } @@ -643,7 +645,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { private checkIfAnyProfileIsUsedLessThanMin(dmpModel: DmpModel): Observable { const blueprintId = dmpModel.profile.id; - return this.dmpBlueprintService.getSingleBlueprint(blueprintId) + return this.dmpBlueprintService.getSingle(Guid.parse(blueprintId)) .pipe(map(result => { return result.definition.sections.some(section => { if(!section.hasTemplates) @@ -653,7 +655,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { return false; let count = 0; dmpModel.datasets.filter(dataset => dataset.dmpSectionIndex === (section.ordinal - 1)).forEach(dataset => { - if(dataset.profile.id === template.descriptionTemplateId){ + if(Guid.parse(dataset.profile.id) === template.descriptionTemplateId){ count++; } }) diff --git a/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard.component.ts b/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard.component.ts index bf4841909..d5a124466 100644 --- a/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard.component.ts +++ b/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard.component.ts @@ -4,8 +4,9 @@ import { Component, OnInit } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { MatSnackBar } from '@angular/material/snack-bar'; import { ActivatedRoute, Params, Router } from '@angular/router'; +import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { DmpModel } from '@app/core/model/dmp/dmp'; -import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; import { DmpService } from '@app/core/services/dmp/dmp.service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; @@ -63,7 +64,7 @@ export class DmpWizardComponent extends BaseComponent implements OnInit { //IBre this.formGroup = this.dmp.buildForm(); if (!isNullOrUndefined(this.formGroup.get('profile').value)) { - this.dmpBlueprintService.getSingleBlueprint(this.formGroup.get('profile').value) + this.dmpBlueprintService.getSingle(this.formGroup.get('profile').value) .pipe(takeUntil(this._destroyed)) .subscribe(result => { this.checkForGrant(result.definition); @@ -93,7 +94,7 @@ export class DmpWizardComponent extends BaseComponent implements OnInit { //IBre let hasGrant = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) { hasGrant = true; } } @@ -107,7 +108,7 @@ export class DmpWizardComponent extends BaseComponent implements OnInit { //IBre let hasFunder = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) { hasFunder = true; } } @@ -121,7 +122,7 @@ export class DmpWizardComponent extends BaseComponent implements OnInit { //IBre let hasProject = false; blueprint.sections.forEach(section => section.fields.forEach( field => { - if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + if (field.category as unknown === 'SYSTEM' && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) { hasProject = true; } } diff --git a/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts b/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts index 643d8c139..576bf9458 100644 --- a/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts +++ b/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts @@ -1,8 +1,8 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { DmpStatus } from '@app/core/common/enum/dmp-status'; import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; +import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { DmpModel } from '@app/core/model/dmp/dmp'; -import { DmpBlueprintDefinition } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; import { ValidJsonValidator } from '@app/library/auto-complete/auto-complete-custom-validator'; import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';