more dmp blueprint frontend changes

This commit is contained in:
Diamantis Tziotzios 2023-10-24 10:40:26 +03:00
parent 167d3d4a4b
commit 2472f6de42
38 changed files with 1861 additions and 1585 deletions

View File

@ -1,4 +1,4 @@
export enum DescriptionTemplateTypeStatus {
Draft = 'Draft',
Finalized = 'Finalized'
Draft = 0,
Finalized = 1
}

View File

@ -0,0 +1,6 @@
export enum DmpBlueprintExtraFieldDataType {
TEXT = 0,
RICH_TEXT = 1,
DATE = 2,
NUMBER = 3
}

View File

@ -1,4 +1,4 @@
export enum DmpBlueprintFieldDataType {
export enum DmpBlueprintExtraFieldDataType {
Date = 0,
Number = 1,
Text = 2,

View File

@ -0,0 +1,4 @@
export enum DmpBlueprintSectionFieldCategory {
SYSTEM = 0,
EXTRA = 1
}

View File

@ -1,4 +1,4 @@
export enum DmpBlueprintStatus {
Draft = 'Draft',
Finalized = 'Finalized'
Draft = 0,
Finalized = 1
}

View File

@ -0,0 +1,13 @@
export enum DmpBlueprintSystemFieldType {
TEXT = 0,
HTML_TEXT = 1,
RESEARCHERS = 2,
ORGANIZATIONS = 3,
LANGUAGE = 4,
CONTACT = 5,
FUNDER = 6,
GRANT = 7,
PROJECT = 8,
LICENSE = 9,
ACCESS_RIGHTS = 10
}

View File

@ -4,6 +4,11 @@ export enum AppPermission {
EditDescriptionTemplateType = "EditDescriptionTemplateType",
DeleteDescriptionTemplateType = "DeleteDescriptionTemplateType",
//DmpBlueprint
BrowseDmpBlueprint = "BrowseDmpBlueprint",
EditDmpBlueprint = "EditDmpBlueprint",
DeleteDmpBlueprint = "DeleteDmpBlueprint",
// UI Pages
ViewDescriptionTemplateTypePage = "ViewDescriptionTemplateTypePage",
ViewDmpBlueprintPage = "ViewDmpBlueprintPage"

View File

@ -1,11 +1,11 @@
import { DmpBlueprintFieldDataType } from '../../common/enum/dmp-blueprint-field-type';
import { DmpBlueprintExtraFieldDataType } from '../../common/enum/dmp-blueprint-field-type';
import { DmpBlueprintType } from '../../common/enum/dmp-blueprint-type';
import { DmpBlueprintExternalAutoCompleteFieldDataEditorModel } from '../../../ui/admin/dmp-blueprint/editor/external-autocomplete/dmp-blueprint-external-autocomplete-field-editor.model';
export interface DmpBlueprintField {
id: string;
type: DmpBlueprintType;
dataType: DmpBlueprintFieldDataType;
dataType: DmpBlueprintExtraFieldDataType;
required: boolean;
label: string;
value: any;

View File

@ -1,10 +0,0 @@
import { DmpBlueprintDefinition } from "../dmp/dmp-blueprint/dmp-blueprint";
export interface DmpBlueprintListing {
id: string;
label: string;
definition: DmpBlueprintDefinition;
status: number;
created: Date;
modified: Date;
}

View File

@ -1,6 +1,9 @@
import { DmpBlueprintSectionFieldCategory } from "@app/core/common/enum/dmp-blueprint-section-field-category";
import { DmpBlueprintStatus } from "@app/core/common/enum/dmp-blueprint-status";
import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model";
import { DmpBlueprintDefinition } from "../dmp/dmp-blueprint/dmp-blueprint";
import { Guid } from "@common/types/guid";
import { DmpBlueprintExtraFieldDataType } from "@app/core/common/enum/dmp-blueprint-field-type";
import { DmpBlueprintSystemFieldType } from "@app/core/common/enum/dmp-blueprint-system-field-type";
export interface DmpBlueprint extends BaseEntity {
@ -10,10 +13,81 @@ export interface DmpBlueprint extends BaseEntity {
description: string;
}
export interface DmpBlueprintDefinition {
sections?: DmpBlueprintDefinitionSection[];
}
export interface DmpBlueprintDefinitionSection {
id: Guid;
label: string;
description: string;
ordinal: number;
fields: FieldInSection[];
hasTemplates: boolean;
descriptionTemplates?: DescriptionTemplatesInSection[];
}
export interface DescriptionTemplatesInSection {
id: Guid;
descriptionTemplateId: Guid;
label: string;
minMultiplicity: number;
maxMultiplicity: number;
}
export interface FieldInSection {
id: Guid;
category: DmpBlueprintSectionFieldCategory;
dataType: DmpBlueprintExtraFieldDataType;
systemFieldType: DmpBlueprintSystemFieldType;
label: string;
placeholder: string;
description: string;
required: boolean;
ordinal: number;
}
//
// Persist
//
export interface DmpBlueprintPersist extends BaseEntityPersist {
label: string;
definition: DmpBlueprintDefinition;
status: number;
definition: DmpBlueprintDefinitionPersist;
status: DmpBlueprintStatus;
description: string;
}
export interface DmpBlueprintDefinitionPersist {
sections?: DmpBlueprintDefinitionSectionPersist[];
}
export interface DmpBlueprintDefinitionSectionPersist {
id: Guid;
label: string;
description: string;
ordinal: number;
fields: FieldInSectionPersist[];
hasTemplates: boolean;
descriptionTemplates?: DescriptionTemplatesInSectionPersist[];
}
export interface DescriptionTemplatesInSectionPersist {
id: Guid;
descriptionTemplateId: Guid;
label: string;
minMultiplicity: number;
maxMultiplicity: number;
}
export interface FieldInSectionPersist {
id: Guid;
category: DmpBlueprintSectionFieldCategory;
dataType: DmpBlueprintExtraFieldDataType;
systemFieldType: DmpBlueprintSystemFieldType;
label: string;
placeholder: string;
description: string;
required: boolean;
ordinal: number;
}

View File

@ -1,10 +0,0 @@
import { DmpBlueprintDefinition } from "./dmp-blueprint";
export interface DmpBlueprintListing {
id: string;
label: string;
definition: DmpBlueprintDefinition;
status: number;
created: Date;
modified: Date;
}

View File

@ -1,72 +0,0 @@
import { DmpBlueprintStatus } from "@app/core/common/enum/dmp-blueprint-status";
import { DmpBlueprintField } from "../../dmp-blueprint/dmp-blueprint-field";
export interface DmpBlueprint {
id: string;
label: string;
definition: DmpBlueprintDefinition;
status: DmpBlueprintStatus;
created: Date;
modified: Date;
description: string;
}
export interface DmpBlueprintDefinition {
sections: SectionDmpBlueprint[];
fields: DmpBlueprintField[];
}
export interface SectionDmpBlueprint {
id: string;
label: string;
description: string;
ordinal: number;
fields: FieldInSection[];
hasTemplates: boolean;
descriptionTemplates?: DescriptionTemplatesInSection[];
}
export interface FieldInSection {
id: string;
category: FieldCategory;
type: number;
label: string;
placeholder: string;
description: string;
required: boolean;
ordinal: number;
}
export enum FieldCategory {
SYSTEM = 0,
EXTRA = 1
}
export enum SystemFieldType {
TEXT = 0,
HTML_TEXT = 1,
RESEARCHERS = 2,
ORGANIZATIONS = 3,
LANGUAGE = 4,
CONTACT = 5,
FUNDER = 6,
GRANT = 7,
PROJECT = 8,
LICENSE = 9,
ACCESS_RIGHTS = 10
}
export interface DescriptionTemplatesInSection {
id: string;
descriptionTemplateId: string;
label: string;
minMultiplicity: number;
maxMultiplicity: number;
}
export enum ExtraFieldType {
TEXT = 0,
RICH_TEXT = 1,
DATE = 2,
NUMBER = 3
}

View File

@ -1,22 +1,21 @@
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { DataTableData } from '@app/core/model/data-table/data-table-data';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing';
import { DmpBlueprint, DmpBlueprintPersist } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { DmpBlueprintListing } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing';
import { DmpBlueprintLookup } from '@app/core/query/dmp-blueprint.lookup';
import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria';
import { DmpBlueprintExternalAutocompleteCriteria } from '@app/core/query/dmp/dmp-profile-external-autocomplete-criteria';
import { RequestItem } from '@app/core/query/request-item';
import { BaseHttpParams } from '@common/http/base-http-params';
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
import { QueryResult } from '@common/model/query-result';
import { Guid } from '@common/types/guid';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { ConfigurationService } from '../configuration/configuration.service';
import { BaseHttpV2Service } from '../http/base-http-v2.service';
import { Guid } from '@common/types/guid';
import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria';
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
@Injectable()
export class DmpBlueprintService {
@ -61,17 +60,17 @@ export class DmpBlueprintService {
}
getPaged(dataTableRequest: DataTableRequest<DmpBlueprintCriteria>): Observable<DataTableData<DmpBlueprintListing>> {
return this.http.post<DataTableData<DmpBlueprintListing>>(this.actionUrl + 'getPaged', dataTableRequest, { headers: this.headers });
getPaged(dataTableRequest: DataTableRequest<DmpBlueprintCriteria>): Observable<DataTableData<DmpBlueprint>> {
return this.http.post<DataTableData<DmpBlueprint>>(this.actionUrl + 'getPaged', dataTableRequest, { headers: this.headers });
}
getPagedBlueprint(dataTableRequest: DataTableRequest<DmpBlueprintCriteria>): Observable<DataTableData<DmpBlueprintListing>> {
return this.http.post<DataTableData<DmpBlueprintListing>>(this.actionUrl + 'getPagedBlueprint', dataTableRequest, { headers: this.headers });
getPagedBlueprint(dataTableRequest: DataTableRequest<DmpBlueprintCriteria>): Observable<DataTableData<DmpBlueprint>> {
return this.http.post<DataTableData<DmpBlueprint>>(this.actionUrl + 'getPagedBlueprint', dataTableRequest, { headers: this.headers });
}
getSingleBlueprint(id: String): Observable<DmpBlueprintListing> {
return this.http.get<DmpBlueprintListing>(this.actionUrl + 'getSingleBlueprint/' + id, { headers: this.headers });
getSingleBlueprint(id: String): Observable<DmpBlueprint> {
return this.http.get<DmpBlueprint>(this.actionUrl + 'getSingleBlueprint/' + id, { headers: this.headers });
}
createDmp(dataManagementPlanModel: DmpBlueprint): Observable<DmpBlueprint> {

View File

@ -4,7 +4,7 @@ import { AppRole } from '../../common/enum/app-role';
import { DatasetProfileComboBoxType } from '../../common/enum/dataset-profile-combo-box-type';
import { DatasetProfileFieldViewStyle } from '../../common/enum/dataset-profile-field-view-style';
import { DatasetStatus } from '../../common/enum/dataset-status';
import { DmpBlueprintFieldDataType } from '../../common/enum/dmp-blueprint-field-type';
import { DmpBlueprintExtraFieldDataType } from '../../common/enum/dmp-blueprint-field-type';
import { DmpBlueprintType } from '../../common/enum/dmp-blueprint-type';
import { DmpStatus } from '../../common/enum/dmp-status';
import { ValidationType } from '../../common/enum/validation-type';
@ -35,12 +35,12 @@ export class EnumUtils {
}
}
toDmpBlueprintFieldDataTypeString(type: DmpBlueprintFieldDataType): string {
toDmpBlueprintFieldDataTypeString(type: DmpBlueprintExtraFieldDataType): string {
switch (type) {
case DmpBlueprintFieldDataType.Date: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.DATE');
case DmpBlueprintFieldDataType.Number: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.NUMBER');
case DmpBlueprintFieldDataType.Text: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.TEXT');
case DmpBlueprintFieldDataType.ExternalAutocomplete: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.EXTERNAL-AUTOCOMPLETE');
case DmpBlueprintExtraFieldDataType.Date: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.DATE');
case DmpBlueprintExtraFieldDataType.Number: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.NUMBER');
case DmpBlueprintExtraFieldDataType.Text: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.TEXT');
case DmpBlueprintExtraFieldDataType.ExternalAutocomplete: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.EXTERNAL-AUTOCOMPLETE');
}
}

View File

@ -3,16 +3,74 @@ import { RouterModule, Routes } from '@angular/router';
import { AdminAuthGuard } from '@app/core/admin-auth-guard.service';
import { DmpBlueprintEditorComponent } from './editor/dmp-blueprint-editor.component';
import { DmpBlueprintListingComponent } from './listing/dmp-blueprint-listing.component';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { AuthGuard } from '@app/core/auth-guard.service';
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
import { PendingChangesGuard } from '@common/forms/pending-form-changes/pending-form-changes-guard.service';
import { DmpBlueprintEditorResolver } from './editor/dmp-blueprint-editor.resolver';
const routes: Routes = [
{ path: '', component: DmpBlueprintListingComponent, canActivate: [AdminAuthGuard] },
{ path: 'new', component: DmpBlueprintEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-NEW' } },
{ path: 'clone/:cloneid', component: DmpBlueprintEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-CLONE' } },
{ path: ':id', component: DmpBlueprintEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-EDIT' } },
{
path: '',
component: DmpBlueprintListingComponent,
canActivate: [AuthGuard]
},
{
path: 'new',
canActivate: [AuthGuard],
data: {
authContext: {
permissions: [AppPermission.EditDmpBlueprint]
},
...BreadcrumbService.generateRouteDataConfiguration({
title: 'BREADCRUMBS.NEW-DESCRIPTION-TEMPLATE-TYPE'
})
},
component: DmpBlueprintEditorComponent,
canDeactivate: [PendingChangesGuard],
},
{
path: 'clone/:cloneid',
canActivate: [AuthGuard],
component: DmpBlueprintEditorComponent,
canDeactivate: [PendingChangesGuard],
resolve: {
'entity': DmpBlueprintEditorResolver
},
data: {
...BreadcrumbService.generateRouteDataConfiguration({
title: 'BREADCRUMBS.EDIT-DESCRIPTION-TEMPLATE-TYPE'
}),
authContext: {
permissions: [AppPermission.EditDmpBlueprint]
}
}
},
{
path: ':id',
canActivate: [AuthGuard],
component: DmpBlueprintEditorComponent,
canDeactivate: [PendingChangesGuard],
resolve: {
'entity': DmpBlueprintEditorResolver
},
data: {
...BreadcrumbService.generateRouteDataConfiguration({
title: 'BREADCRUMBS.EDIT-DESCRIPTION-TEMPLATE-TYPE'
}),
authContext: {
permissions: [AppPermission.EditDmpBlueprint]
}
}
},
{ path: '**', loadChildren: () => import('@common/modules/page-not-found/page-not-found.module').then(m => m.PageNotFoundModule) },
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
exports: [RouterModule],
providers: [DmpBlueprintEditorResolver]
})
export class DmpBlueprintRoutingModule { }

View File

@ -1,33 +1,31 @@
<div class="main-content">
<div class="container-fluid dmp-blueprint-editor">
<div class="row align-items-center mb-4" *ngIf="formGroup">
<div class="col-auto">
<h3 *ngIf="isNew && !isClone">{{'DMP-BLUEPRINT-EDITOR.TITLE.NEW' | translate}}</h3>
<h3 *ngIf="isNew && isClone">
<span>{{'DMP-BLUEPRINT-EDITOR.TITLE.CLONE' | translate}}</span>
{{formGroup.get('label').value}}
</h3>
<h3 *ngIf="!isNew">{{formGroup.get('label').value}}</h3>
</div>
<div class="col"></div>
<div class="col-auto" *ngIf="!isNew">
<button mat-button class="action-btn" type="button" (click)="delete()">
<mat-icon>delete</mat-icon>
{{'DMP-BLUEPRINT-EDITOR.ACTIONS.DELETE' | translate}}
</button>
</div>
<div class="col-auto" *ngIf="formGroup.get('status').value==1">
<button mat-button class="finalize-btn" (click)="downloadXML()"
type="button">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.DOWNLOAD-XML' | translate }}</button>
</div>
<div *ngIf="formGroup.get('status').value!=1" class="col-auto">
<button mat-button class="finalize-btn" (click)="finalize()"
[disabled]="!this.isFormValid()" type="button">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
</div>
<!-- <div class="main-content"> -->
<div class="container-fluid dmp-blueprint-editor">
<div class="row align-items-center mb-4" *ngIf="formGroup">
<div class="col-auto">
<h3 *ngIf="isNew && !isClone">{{'DMP-BLUEPRINT-EDITOR.TITLE.NEW' | translate}}</h3>
<h3 *ngIf="isNew && isClone">
<span>{{'DMP-BLUEPRINT-EDITOR.TITLE.CLONE' | translate}}</span>
{{formGroup.get('label').value}}
</h3>
<h3 *ngIf="!isNew">{{formGroup.get('label').value}}</h3>
</div>
<form *ngIf="formGroup" (ngSubmit)="formSubmit()" [formGroup]="formGroup">
<mat-card style="padding: 2em;">
<!-- <mat-card-header>
<div class="col"></div>
<div class="col-auto" *ngIf="!isNew">
<button mat-button class="action-btn" type="button" (click)="delete()">
<mat-icon>delete</mat-icon>
{{'DMP-BLUEPRINT-EDITOR.ACTIONS.DELETE' | translate}}
</button>
</div>
<div class="col-auto" *ngIf="formGroup.get('status').value==1">
<button mat-button class="finalize-btn" (click)="downloadXML()" type="button">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.DOWNLOAD-XML' | translate }}</button>
</div>
<div *ngIf="formGroup.get('status').value!=1" class="col-auto">
<button mat-button class="finalize-btn" (click)="finalize()" [disabled]="!this.isFormValid()" type="button">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
</div>
</div>
<form *ngIf="formGroup" (ngSubmit)="formSubmit()" [formGroup]="formGroup">
<mat-card>
<!-- <mat-card-header>
<mat-card-title *ngIf="isNew">
<h4>{{'DMP-BLUEPRINT-EDITOR.TITLE.NEW' | translate}}</h4>
</mat-card-title>
@ -35,270 +33,253 @@
<h4>{{formGroup.get('label').value}}</h4>
</mat-card-title>
</mat-card-header> -->
<mat-card-content>
<div class="row" style="gap:1em">
<mat-form-field class="col-lg-6" >
<mat-label>Name</mat-label>
<input matInput type="text" name="label" formControlName="label" required>
<mat-error *ngIf="formGroup.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<h4 class="col-12">Sections</h4>
<ng-container formGroupName="definition">
<div formArrayName="sections" style="width: 100%;" cdkDropList (cdkDropListDropped)="dropSections($event)">
<div *ngFor="let section of sectionsArray().controls; let sectionIndex=index;" class="section-input" cdkDrag [cdkDragDisabled]="viewOnly">
<ng-container [formGroupName]="sectionIndex">
<mat-card-content>
<div class="row">
<mat-form-field class="col-lg-6">
<mat-label>Name</mat-label>
<input matInput type="text" name="label" formControlName="label" required>
<mat-error *ngIf="formGroup.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<h4 class="col-12">Sections</h4>
<div class="col-12" cdkDropList (cdkDropListDropped)="dropSections($event)">
<div *ngFor="let section of formGroup.get('definition').get('sections').controls; let sectionIndex=index;" class="row section-input" cdkDrag [cdkDragDisabled]="viewOnly">
<div class="col-12">
<mat-card>
<mat-card-header>
<mat-card-title>Section {{sectionIndex + 1}}</mat-card-title>
<mat-icon cdkDragHandle style="cursor: move; color: #129d99;">drag_indicator</mat-icon>
</mat-card-header>
<div class="row">
<mat-form-field class="col-6">
<mat-label>Section name</mat-label>
<input matInput type="text" name="label" [formControl]="section.get('label')" required>
<mat-error *ngIf="section.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="col-6">
<mat-label>Section description</mat-label>
<input matInput type="text" name="description" [formControl]="section.get('description')">
<mat-error *ngIf="section.get('description').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<div class="col-12">
<div class="row">
<mat-card class="col-11" style="width: 100%; margin-bottom: 1%;">
<mat-card-header>
<mat-card-title>Section {{sectionIndex + 1}}</mat-card-title>
<mat-icon cdkDragHandle style="cursor: move; color: #129d99;">drag_indicator</mat-icon>
</mat-card-header>
<div class="col-12">
<div class="row">
<div class="col-6">
<mat-form-field>
<mat-label>Section name</mat-label>
<input matInput type="text" name="label" formControlName="label" required>
<mat-error *ngIf="section.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-6">
<mat-form-field>
<mat-label>Section description</mat-label>
<input matInput type="text" name="description" formControlName="description">
<mat-error *ngIf="section.get('description').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-12">
<div class="row">
<div class="col-6">
<mat-form-field>
<mat-label>System fields</mat-label>
<mat-select multiple [disabled]="viewOnly" [value]="systemFieldListPerSection[sectionIndex]">
<mat-option *ngFor="let f of fieldList" [disabled]="systemFieldDisabled(f.type, sectionIndex)" [value]="f.type" (click)="selectedFieldType(f.type, sectionIndex)">{{f.label}}</mat-option>
</mat-select>
<mat-error *ngIf="fieldsArray(sectionIndex).hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-6">
<button mat-button class="action-btn" type="button" (click)="addExtraField(sectionIndex)" [disabled]="viewOnly">Add extra field</button>
</div>
</div>
</div>
<div class="col-12">
<div class="row">
<div class="col-12">
<div cdkDropList (cdkDropListDropped)="drop($event, sectionIndex)">
<div *ngFor="let field of section.get('fields').controls; let fieldIndex=index;" cdkDrag [cdkDragDisabled]="viewOnly">
<div class="col-12">
<div class="row">
<div class="col-6">
<mat-form-field>
<mat-label>System fields</mat-label>
<mat-select multiple [disabled]="viewOnly" [value]="systemFieldListPerSection[sectionIndex]">
<mat-option *ngFor="let f of fieldList" [disabled]="systemFieldDisabled(f.type, sectionIndex)" [value]="f.type" (click)="selectedFieldType(f.type, sectionIndex)">{{f.label}}</mat-option>
</mat-select>
<mat-error *ngIf="fieldsArray(sectionIndex).hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-6">
<button mat-button class="action-btn" type="button" (click)="addExtraField(sectionIndex)" [disabled]="viewOnly">Add extra field</button>
<!-- <button mat-button class="action-btn" style="margin-left: 3%;" type="button" (click)="addExtraField(sectionIndex)">Add description templates</button> -->
</div>
</div>
</div>
<div class="col-12">
<div formArrayName="fields" cdkDropList (cdkDropListDropped)="drop($event, sectionIndex)">
<div *ngFor="let field of fieldsArray(sectionIndex).controls; let fieldIndex=index;" cdkDrag [cdkDragDisabled]="viewOnly">
<ng-container [formGroupName]="fieldIndex">
<div class="col-12" *ngIf="fieldsArray(sectionIndex).length > 0">
<div class="row">
<div class="col-xx-1" style="padding-left: 0;">
<div class="row">
<div class="col-4">
<span style="font-size: 15px;">{{fieldIndex + 1}}</span>
</div>
<div class="col-8">
<mat-icon cdkDragHandle style="cursor: move; color: #129d99;">drag_indicator</mat-icon>
</div>
</div>
</div>
<ng-container *ngIf="field.get('category').value === 0 || field.get('category').value === 'SYSTEM'">
<div class="col-2" >
<mat-form-field>
<mat-label>System Field</mat-label>
<input matInput disabled value="{{transfromEnumToString(field.get('type').value)}}" type="text" name="name">
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Label</mat-label>
<input matInput type="text" name="label" formControlName="label" required>
<mat-error *ngIf="field.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Placeholder</mat-label>
<input matInput type="text" name="placeholder" formControlName="placeholder">
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Description</mat-label>
<input matInput type="text" name="description" formControlName="description">
</mat-form-field>
</div>
<div class="centered-row-item col-1">
<mat-checkbox [disabled]="field.get('type').value === 0 || field.get('type').value === 1" formControlName="required">Required</mat-checkbox>
</div>
<div [hidden]="viewOnly" class="field-delete col-1" (click)="removeSystemFieldWithIndex(sectionIndex, fieldIndex)">
<mat-icon class="field-delete-icon">delete</mat-icon>
<span class="field-delete-text">{{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
</div>
</ng-container>
<ng-container *ngIf="field.get('category').value === 1 || field.get('category').value === 'EXTRA'">
<div class="col-2">
<mat-form-field>
<mat-label>Type</mat-label>
<mat-select placeholder="Type" formControlName="type" required>
<mat-option *ngFor="let extraFieldType of getExtraFieldTypes()" [value]="extraFieldType">
{{getExtraFieldTypeValue(extraFieldType)}}
</mat-option>
</mat-select>
<mat-error *ngIf="field.get('type').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Label</mat-label>
<input matInput type="text" name="label" formControlName="label" required>
<mat-error *ngIf="field.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Placeholder</mat-label>
<input matInput type="text" name="placeholder" formControlName="placeholder">
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Description</mat-label>
<input matInput type="text" name="description" formControlName="description">
</mat-form-field>
</div>
<div class="centered-row-item col-1">
<mat-checkbox formControlName="required">
Required
</mat-checkbox>
</div>
<div [hidden]="viewOnly" class="field-delete col-1" (click)="removeExtraField(sectionIndex, fieldIndex)">
<mat-icon class="field-delete-icon">delete</mat-icon>
<span class="field-delete-text">{{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
</div>
</ng-container>
</div>
<div class="col-xx-1" style="padding-left: 0;">
<div class="row">
<div class="col-4">
<span style="font-size: 15px;">{{fieldIndex + 1}}</span>
</div>
</ng-container>
<div class="col-8">
<mat-icon cdkDragHandle style="cursor: move; color: #129d99;">drag_indicator</mat-icon>
</div>
</div>
</div>
<ng-container *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.SYSTEM">
<div class="col-2">
<mat-form-field>
<mat-label>System Field</mat-label>
<input matInput disabled value="{{transfromEnumToString(field.get('type').value)}}" type="text" name="name">
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Label</mat-label>
<input matInput type="text" name="label" [formControl]="field.get('label')" required>
<mat-error *ngIf="field.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Placeholder</mat-label>
<input matInput type="text" name="placeholder" [formControl]="field.get('placeholder')">
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Description</mat-label>
<input matInput type="text" name="description" [formControl]="field.get('description')">
</mat-form-field>
</div>
<div class="centered-row-item col-1">
<mat-checkbox [disabled]="field.get('type').value === 0 || field.get('type').value === 1" [formControl]="field.get('required')">Required</mat-checkbox>
</div>
<div [hidden]="viewOnly" class="field-delete col-1" (click)="removeSystemFieldWithIndex(sectionIndex, fieldIndex)">
<mat-icon class="field-delete-icon">delete</mat-icon>
<span class="field-delete-text">{{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
</div>
</ng-container>
<ng-container *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.EXTRA">
<div class="col-2">
<mat-form-field>
<mat-label>Type</mat-label>
<mat-select placeholder="Type" formControlName="type" required>
<mat-option *ngFor="let extraFieldType of getExtraFieldTypes()" [value]="extraFieldType">
{{getExtraFieldTypeValue(extraFieldType)}}
</mat-option>
</mat-select>
<mat-error *ngIf="field.get('type').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Label</mat-label>
<input matInput type="text" name="label" formControlName="label" required>
<mat-error *ngIf="field.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Placeholder</mat-label>
<input matInput type="text" name="placeholder" formControlName="placeholder">
</mat-form-field>
</div>
<div class="col-2">
<mat-form-field>
<mat-label>Description</mat-label>
<input matInput type="text" name="description" formControlName="description">
</mat-form-field>
</div>
<div class="centered-row-item col-1">
<mat-checkbox formControlName="required">
Required
</mat-checkbox>
</div>
<div [hidden]="viewOnly" class="field-delete col-1" (click)="removeExtraField(sectionIndex, fieldIndex)">
<mat-icon class="field-delete-icon">delete</mat-icon>
<span class="field-delete-text">{{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
</div>
</ng-container>
</div>
</div>
</div>
</div>
<div class="col-12">
<div class="row">
<div class="col-12">
<mat-checkbox formControlName="hasTemplates" (change)="checkForBlueprints($event, sectionIndex)">
Description Templates
</mat-checkbox>
</div>
</div>
</div>
<div class="col-12" *ngIf="section.get('hasTemplates').value == true">
</div>
</div>
</div>
</div>
<div class="col-12">
<div class="row">
<div class="col-12">
<mat-checkbox [formControl]="section.get('hasTemplates')" (change)="checkForBlueprints($event, sectionIndex)">
Description Templates
</mat-checkbox>
</div>
</div>
</div>
<!-- <div class="col-12" *ngIf="section.get('hasTemplates').value == true">
<div class="row">
<div class="col-12">
<mat-form-field>
<mat-label>Description Templates</mat-label>
<app-multiple-auto-complete placeholder="Description Templates" [disabled]="viewOnly" [value]="descriptionTemplatesPerSection[sectionIndex]" [hidePlaceholder]="true" required='false' [configuration]="blueprintsAutoCompleteConfiguration" (optionRemoved)="onRemoveTemplate($event, sectionIndex)" (optionSelected)="onOptionSelected($event, sectionIndex)">
</app-multiple-auto-complete>
<!-- <button matSuffix class="input-btn" (click)="allAvailableBlueprints($event)">
<mat-icon class="icon-btn">view_list</mat-icon>
</button> -->
</mat-form-field>
</div>
</div>
</div>
<ng-container formArrayName="descriptionTemplates">
<div *ngFor="let descriptionTemplate of descriptionTemplatesArray(sectionIndex).controls; let j=index;" class="section-input" style="width: 100%;">
<ng-container [formGroupName]="j">
<div class="col-12" *ngIf="descriptionTemplatesArray(sectionIndex).length > 0">
<div class="row">
<div class="col-4">
<mat-form-field>
<mat-label>Label</mat-label>
<input matInput type="text" value="descriptionTemplate.get('label')" name="label" formControlName="label">
</mat-form-field>
</div>
<div class="col-4">
<mat-form-field>
<mat-label>Min Multiplicity</mat-label>
<input matInput type="number" min="0" name="minMultiplicity" formControlName="minMultiplicity">
</mat-form-field>
</div>
<div class="col-4">
<mat-form-field>
<mat-label>Max Multiplicity</mat-label>
<input matInput type="number" min="1" name="maxMultiplicity" formControlName="maxMultiplicity">
</mat-form-field>
</div>
</div>
</div>
</ng-container>
</div>
</ng-container>
</mat-card>
<div class="col-1">
<div class="row">
<!-- <div class="col-auto dlt-section-btn">
<button mat-button class="action-btn" type="button" click="removeSection(sectionIndex)">Delete</button>
</div> -->
<div [hidden]="viewOnly" class="action-list-item col-auto dlt-section-btn" (click)="removeSection(sectionIndex)" [disabled]="viewOnly">
<mat-icon class="action-list-icon">delete</mat-icon>
<span class="action-list-text">{{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
</div>
</div>
</div> -->
<div *ngFor="let descriptionTemplate of section.get('descriptionTemplates').controls; let j=index;" class="section-input" style="width: 100%;">
<div class="col-12">
<div class="row">
<div class="col-4">
<mat-form-field>
<mat-label>Label</mat-label>
<input matInput type="text" value="descriptionTemplate.get('label')" name="label" [formControl]="descriptionTemplate.get('label')">
</mat-form-field>
</div>
<div class="col-4">
<mat-form-field>
<mat-label>Min Multiplicity</mat-label>
<input matInput type="number" min="0" name="minMultiplicity" [formControl]="descriptionTemplate.get('minMultiplicity')">
</mat-form-field>
</div>
<div class="col-4">
<mat-form-field>
<mat-label>Max Multiplicity</mat-label>
<input matInput type="number" min="1" name="maxMultiplicity" [formControl]="descriptionTemplate.get('maxMultiplicity')">
</mat-form-field>
</div>
</div>
</div>
</ng-container>
</div>
</mat-card>
<div class="col-1">
<div class="row">
<!-- <div class="col-auto dlt-section-btn">
<button mat-button class="action-btn" type="button" click="removeSection(sectionIndex)">Delete</button>
</div> -->
<div [hidden]="viewOnly" class="action-list-item col-auto dlt-section-btn" (click)="removeSection(sectionIndex)" [disabled]="viewOnly">
<mat-icon class="action-list-icon">delete</mat-icon>
<span class="action-list-text">{{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
</div>
</div>
</div>
</div>
</ng-container>
<div class="col-12">
<div class="row">
<div class="col-auto">
<button mat-button class="action-btn" type="button" (click)="addSection()" [disabled]="viewOnly">Add section</button>
</div>
</div>
</div>
<div class="col-12">
<div class="row">
<div class="col-auto">
<button mat-button class="action-btn" type="button" (click)="addSection()" [disabled]="viewOnly">Add section</button>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-auto">
<button mat-button class="action-btn" (click)="cancel()" type="button">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.CANCEL' | translate}}</button>
</div>
<div class="col"></div>
<div class="col-auto" *ngIf="!viewOnly">
<button mat-button class="action-btn" type="submit">
{{'DMP-BLUEPRINT-EDITOR.ACTIONS.SAVE' | translate}}
</button>
</div>
</div>
<div class="row mt-4">
<div class="col-auto">
<button mat-button class="action-btn" (click)="cancel()" type="button">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.CANCEL' | translate}}</button>
</div>
</mat-card-content>
</mat-card>
</form>
</div>
<div class="col"></div>
<div class="col-auto" *ngIf="!viewOnly">
<button mat-button class="action-btn" type="submit">
{{'DMP-BLUEPRINT-EDITOR.ACTIONS.SAVE' | translate}}
</button>
</div>
</div>
</mat-card-content>
</mat-card>
</form>
</div>
<!-- </div> -->

View File

@ -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<Validation>();
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<Validation>();
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<Validation>();
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<SectionDmpBlueprintEditor>();
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<UntypedFormGroup>();
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<FieldInSectionEditor>();
public hasTemplates: boolean;
public descriptionTemplates: DescriptionTemplatesInSectionEditor[] = new Array<DescriptionTemplatesInSectionEditor>();
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<UntypedFormGroup>();
this.fields.forEach(item => {
const form: UntypedFormGroup = item.buildForm();
fieldsFormArray.push(form);
});
formGroup.addControl('fields', formBuilder.array(fieldsFormArray));
const descriptionTemplatesFormArray = new Array<UntypedFormGroup>();
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<Validation>();
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<Validation>();
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;
// }
// }
}

View File

@ -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<DmpBlueprint>(x => x.id),
nameof<DmpBlueprint>(x => x.label),
nameof<DmpBlueprint>(x => x.status),
nameof<DmpBlueprint>(x => x.description),
nameof<DmpBlueprint>(x => x.status),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.description)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.ordinal)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.id)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.category)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.dataType)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.systemFieldType)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.label)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.placeholder)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.description)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.required)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.fields), nameof<FieldInSection>(x => x.ordinal)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.id)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateId)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.label)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.minMultiplicity)].join('.'),
[nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
nameof<DmpBlueprint>(x => x.createdAt),
nameof<DmpBlueprint>(x => x.hash),
nameof<DmpBlueprint>(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));
}
}

View File

@ -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;
}
}

View File

@ -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<DmpBlueprintFieldEditorModel>();
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<UntypedFormGroup>();
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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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){

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -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<Array<DatasetProfileModel>> = new Array<Array<DatasetProfileModel>>();
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( (<any>aControl).nativeElement !== undefined && (<any>aControl).nativeElement !== null){
if ((<any>aControl).nativeElement !== undefined && (<any>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<DatasetProfileModel>());
}
const templates: Array<DmpDatasetProfile> = new Array<DmpDatasetProfile>();
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<ExternalSourceItemModel[]> {
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<String, number> = new Map<String, number>();
// 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')
}
}

View File

@ -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<String, number> = new Map<String, number>();
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')
}
}

View File

@ -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<UserModel>;
people: Array<UserInfoListingModel>;
filteredOptions: DmpBlueprintListing[];
filteredOptions: DmpBlueprint[];
selectedDmpBlueprintDefinition: DmpBlueprintDefinition;
DynamicDmpFieldResolverComponent: any;

View File

@ -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;

View File

@ -1,6 +1,5 @@
<div *ngFor="let field of dmpBlueprintDefinition?.fields; let i = index" class="row">
<!-- <div *ngFor="let field of dmpBlueprintDefinition?.fields; let i = index" class="row">
<div class="col-md-8">
<!-- <div *ngIf="field.type == dmpBlueprintTypeEnum.Input"> -->
<mat-form-field class="full-width" *ngIf="field.dataType == dmpBlueprintFieldDataType.Date">
<input matInput [matDatepicker]="picker" [placeholder]="field.label"
[formControl]="formGroup.get('properties').get('fields').get(''+i).get('value')"
@ -45,8 +44,9 @@
</app-multiple-auto-complete>
</mat-form-field>
</div>
<!-- <mat-error *ngIf="formGroup.get('properties').get('fields').get(''+i).get('value')['errors']">{{'GENERAL.VALIDATION.REQUIRED'
| translate}}</mat-error> -->
</div>
</div>
</div>
</div>
//TODO: dtziotzios
-->

View File

@ -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([]));
(<UntypedFormGroup>this.formGroup.get('properties')).addControl('fields', new UntypedFormBuilder().array([]));
this.dmpBlueprintDefinition.fields.forEach(item => {
(<UntypedFormArray>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 => {
// (<UntypedFormArray>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');

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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<boolean> {
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++;
}
})

View File

@ -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;
}
}

View File

@ -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';