frontend dmp changes

This commit is contained in:
Diamantis Tziotzios 2023-10-27 18:56:19 +03:00
parent 92c165e904
commit 7214745162
41 changed files with 542 additions and 230 deletions

View File

@ -10,75 +10,57 @@ import java.util.UUID;
public class Dmp {
private UUID id;
public static final String _id = "id";
private String label;
public static final String _label = "label";
private Integer version;
public static final String _version = "version";
private DmpStatus status;
public static final String _status = "status";
private String properties;
public static final String _properties = "properties";
private String dmpProperties;
public static final String _dmpProperties = "dmpProperties";
private UUID groupId;
public static final String _groupId = "groupId";
private String description;
public static final String _description = "description";
private boolean isPublic;
public static final String _isPublic = "isPublic";
private String extraProperties;
public static final String _extraProperties = "extraProperties";
private Instant createdAt;
public static final String _createdAt = "createdAt";
private Instant updatedAt;
public static final String _updatedAt = "updatedAt";
private IsActive isActive;
public static final String _isActive = "isActive";
private Instant finalizedAt;
public static final String _finalizedAt = "finalizedAt";
private Instant publishedAt;
public static final String _publishedAt = "publishedAt";
private UUID creator;
public static final String _creator = "creator";
private String hash;
public static final String _hash = "hash";
private List<Description> dmpDescriptions;
public static final String _dmpDescriptions = "dmpDescriptions";
public static final String _dmpReferences = "dmpReferences";

View File

@ -32,7 +32,6 @@ public abstract class FieldPersist {
@NotEmpty(message = "{validation.empty}")
private String label = null;
@NotNull(message = "{validation.empty}")
@NotEmpty(message = "{validation.empty}")
private String placeholder = null;

View File

@ -249,6 +249,7 @@ public class DmpBlueprintServiceImpl implements DmpBlueprintService {
model.setLabel(model.getLabel() + " new ");
model.setId(null);
model.setHash(null);
model.setStatus(DmpBlueprintStatus.Draft);
this.reassignDefinition(model.getDefinition());
return model;

View File

@ -199,6 +199,11 @@
<artifactId>cors-web</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>gr.cite</groupId>
<artifactId>exceptions-web</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>

View File

@ -22,6 +22,7 @@
{ "glob": "**/*", "input": "node_modules/tinymce", "output": "/tinymce/" }
],
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.scss",
"src/assets/scss/material-dashboard.scss",
"src/assets/css/demo.css",

View File

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

View File

@ -1,5 +1,4 @@
export enum DmpStatus {
Draft = 0,
Finalized = 1,
Deleted = 99
Finalized = 1
}

View File

@ -51,11 +51,12 @@ import { SpecialAuthGuard } from './special-auth-guard.service';
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
import { FilterService } from '@common/modules/text-filter/filter-service';
import { PrincipalService } from './services/http/principal.service';
import { ReferenceService } from './services/reference/reference.service';
import { SupportiveMaterialService } from './services/supportive-material/supportive-material.service';
import { UserSettingsHttpService } from './services/user-settings/user-settings-http.service';
import { UserSettingsService } from './services/user-settings/user-settings.service';
import { QueryParamsService } from './services/utilities/query-params.service';
import { FileUtils } from './services/utilities/file-utils.service';
import { QueryParamsService } from './services/utilities/query-params.service';
//
//
// This is shared module that provides all the services. Its imported only once on the AppModule.
@ -130,7 +131,8 @@ export class CoreServiceModule {
UserSettingsService,
UserSettingsHttpService,
FilterService,
FileUtils
FileUtils,
ReferenceService
],
};
}

View File

@ -130,7 +130,7 @@ export interface TagsFieldData extends FieldData {
}
export interface ResearchersFieldData extends FieldData {
multiAutoComplete: boolean;
}
export interface OrganizationsFieldData extends AutoCompleteFieldData {

View File

@ -0,0 +1,81 @@
import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model";
import { Guid } from "@common/types/guid";
export interface DescriptionTemplate extends BaseEntity {
label: string;
definition: DescriptionTemplateDefinition;
description: string;
}
export interface DescriptionTemplateDefinition {
sections?: DescriptionTemplateDefinitionSection[];
}
export interface DescriptionTemplateDefinitionSection {
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;
label: string;
placeholder: string;
description: string;
required: boolean;
ordinal: number;
}
//
// Persist
//
export interface DescriptionTemplatePersist extends BaseEntityPersist {
label: string;
definition: DescriptionTemplateDefinitionPersist;
description: string;
}
export interface DescriptionTemplateDefinitionPersist {
sections?: DescriptionTemplateDefinitionSectionPersist[];
}
export interface DescriptionTemplateDefinitionSectionPersist {
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;
label: string;
placeholder: string;
description: string;
required: boolean;
ordinal: number;
}

View File

@ -0,0 +1,21 @@
import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model";
import { Guid } from "@common/types/guid";
import { Reference } from "../reference/reference";
import { Description } from "./description";
export interface DescriptionReference extends BaseEntity {
description?: Description;
reference?: Reference;
data: String;
}
//
// Persist
//
export interface DescriptionPersist extends BaseEntityPersist {
descriptionId: Guid;
referenceId: Guid;
data: String;
}

View File

@ -0,0 +1,37 @@
import { DescriptionStatus } from "@app/core/common/enum/description-status";
import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model";
import { Guid } from "@common/types/guid";
import { Dmp } from "../dmp/dmp";
import { DescriptionTemplate } from "../description-template/description-template";
import { DescriptionReference } from "./description-reference";
export interface Description extends BaseEntity {
label: string;
description?: String;
dmp: Dmp;
uri: String;
status: DescriptionStatus
finalizedAt: Date;
dmpSectionIndex?: number;
template: DescriptionTemplate;
descriptionReferences: DescriptionReference[];
// registries?: RegistryModel[];
// services?: ServiceModel[];
// dataRepositories?: DataRepositoryModel[];
// tags?: TagModel[];
// externalDatasets?: ExternalDatasetModel[];
// isProfileLatestVersion?: Boolean;
// modified?: Date;
}
//
// Persist
//
export interface DescriptionPersist extends BaseEntityPersist {
}

View File

@ -0,0 +1,21 @@
import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model";
import { Guid } from "@common/types/guid";
import { Reference } from "../reference/reference";
import { Dmp } from "./dmp";
export interface DmpReference extends BaseEntity {
dmp?: Dmp;
reference?: Reference;
data: String;
}
//
// Persist
//
export interface DmpPersist extends BaseEntityPersist {
dmpId: Guid;
referenceId: Guid;
data: String;
}

View File

@ -10,6 +10,8 @@ import { UserInfoListingModel } from "../user/user-info-listing";
import { DmpDatasetProfile } from "./dmp-dataset-profile/dmp-dataset-profile";
import { DmpDynamicField } from "./dmp-dynamic-field";
import { DmpExtraField } from "./dmp-extra-field";
import { BaseEntity } from '@common/base/base-entity.model';
import { Description } from '../description/description';
export interface DmpModel {
id: string;
@ -43,3 +45,36 @@ export interface DmpBlueprint {
id: string;
label: string;
}
export interface Dmp extends BaseEntity {
label: string;
description: String;
version: number;
status: DmpStatus;
groupId: String;
finalizedAt: Date;
blueprint: DmpBlueprint;
dmpDescriptions: Description[];
lockable: boolean;
grant: GrantListingModel;
project: ProjectModel;
funder: FunderModel;
datasets: DatasetWizardModel[];
datasetsToBeFinalized: string[];
profiles: DmpDatasetProfile[];
organisations: OrganizationModel[];
researchers: ResearcherModel[];
associatedUsers: UserModel[];
users: UserInfoListingModel[];
creator: UserModel;
extraFields: Array<DmpExtraField>;
dynamicFields: Array<DmpDynamicField>;
modified: Date;
extraProperties: Map<String, any>;
language: String;
}

View File

@ -1,9 +1,9 @@
import { ReferenceType } from "@app/core/common/enum/reference-type";
import { IsActive } from "@app/core/common/enum/is-active.enum";
import { ReferenceFieldDataType } from "@app/core/common/enum/reference-field-data-type";
import { ReferenceType } from "@app/core/common/enum/reference-type";
import { SourceType } from "@app/core/common/enum/source-type";
import { UUID } from "crypto";
import { DmpModel } from "../dmp/dmp";
import { ReferenceFieldDataType } from "@app/core/common/enum/reference-field-data-type";
export interface Reference {
id: UUID;

View File

@ -0,0 +1,27 @@
import { Lookup } from '@common/model/lookup';
import { Guid } from '@common/types/guid';
import { IsActive } from '../common/enum/is-active.enum';
import { ReferenceType } from '../common/enum/reference-type';
import { SourceType } from '../common/enum/source-type';
export class ReferenceLookup extends Lookup implements ReferenceFilter {
ids: Guid[];
excludedIds: Guid[];
like: string;
isActive: IsActive[];
sourceTypes: SourceType[];
referenceTypes: ReferenceType[];
constructor() {
super();
}
}
export interface ReferenceFilter {
ids: Guid[];
excludedIds: Guid[];
like: string;
isActive: IsActive[];
sourceTypes: SourceType[];
referenceTypes: ReferenceType[];
}

View File

@ -62,7 +62,7 @@ export class DmpBlueprintService {
catchError((error: any) => throwError(error)));
}
clone(id: string, reqFields: string[] = []): Observable<DmpBlueprint> {
clone(id: Guid, reqFields: string[] = []): Observable<DmpBlueprint> {
const url = `${this.apiBase}/clone/${id}`;
const options = { params: { f: reqFields } };

View File

@ -0,0 +1,103 @@
import { Injectable } from '@angular/core';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { ReferenceType } from '@app/core/common/enum/reference-type';
import { SourceType } from '@app/core/common/enum/source-type';
import { Reference, ReferencePersist } from '@app/core/model/reference/reference';
import { ReferenceLookup } from '@app/core/query/reference.lookup';
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 { QueryResult } from '@common/model/query-result';
import { FilterService } from '@common/modules/text-filter/filter-service';
import { Guid } from '@common/types/guid';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { ConfigurationService } from '../configuration/configuration.service';
import { BaseHttpV2Service } from '../http/base-http-v2.service';
@Injectable()
export class ReferenceService {
constructor(
private http: BaseHttpV2Service,
private configurationService: ConfigurationService,
private filterService: FilterService
) {
}
private get apiBase(): string { return `${this.configurationService.server}reference`; }
query(q: ReferenceLookup): Observable<QueryResult<Reference>> {
const url = `${this.apiBase}/query`;
return this.http.post<QueryResult<Reference>>(url, q).pipe(catchError((error: any) => throwError(error)));
}
getSingle(id: Guid, reqFields: string[] = []): Observable<Reference> {
const url = `${this.apiBase}/${id}`;
const options = { params: { f: reqFields } };
return this.http
.get<Reference>(url, options).pipe(
catchError((error: any) => throwError(error)));
}
persist(item: ReferencePersist): Observable<Reference> {
const url = `${this.apiBase}/persist`;
return this.http
.post<Reference>(url, item).pipe(
catchError((error: any) => throwError(error)));
}
delete(id: Guid): Observable<Reference> {
const url = `${this.apiBase}/${id}`;
return this.http
.delete<Reference>(url).pipe(
catchError((error: any) => throwError(error)));
}
//
// Autocomplete Commons
//
public getSingleAutocompleteConfiguration(referenceTypes?: ReferenceType[], sourceTypes?: SourceType[]): SingleAutoCompleteConfiguration {
return {
initialItems: (data?: any) => this.query(this.buildAutocompleteLookup(referenceTypes, sourceTypes)).pipe(map(x => x.items)),
filterFn: (searchQuery: string, data?: any) => this.query(this.buildAutocompleteLookup(referenceTypes, sourceTypes, searchQuery)).pipe(map(x => x.items)),
getSelectedItem: (selectedItem: any) => this.query(this.buildAutocompleteLookup(referenceTypes, sourceTypes, null, null, [selectedItem])).pipe(map(x => x.items[0])),
displayFn: (item: Reference) => item.label,
titleFn: (item: Reference) => item.label,
valueAssign: (item: Reference) => item.id,
};
};
public getMultipleAutoCompleteConfiguration(referenceTypes?: ReferenceType[], sourceTypes?: SourceType[]): MultipleAutoCompleteConfiguration {
return {
initialItems: (excludedItems: any[], data?: any) => this.query(this.buildAutocompleteLookup(referenceTypes, sourceTypes, null, excludedItems ? excludedItems : null)).pipe(map(x => x.items)),
filterFn: (searchQuery: string, excludedItems: any[]) => this.query(this.buildAutocompleteLookup(referenceTypes, sourceTypes, searchQuery, excludedItems)).pipe(map(x => x.items)),
getSelectedItems: (selectedItems: any[]) => this.query(this.buildAutocompleteLookup(referenceTypes, sourceTypes, null, null, selectedItems)).pipe(map(x => x.items)),
displayFn: (item: Reference) => item.label,
titleFn: (item: Reference) => item.label,
valueAssign: (item: Reference) => item.id,
};
}
private buildAutocompleteLookup(referenceTypes?: ReferenceType[], sourceTypes?: SourceType[], like?: string, excludedIds?: Guid[], ids?: Guid[]): ReferenceLookup {
const lookup: ReferenceLookup = new ReferenceLookup();
lookup.page = { size: 100, offset: 0 };
if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; }
if (ids && ids.length > 0) { lookup.ids = ids; }
lookup.isActive = [IsActive.Active];
lookup.project = {
fields: [
nameof<Reference>(x => x.id),
nameof<Reference>(x => x.label)
]
};
if (referenceTypes && referenceTypes.length > 0) { lookup.referenceTypes = referenceTypes; }
if (sourceTypes && sourceTypes.length > 0) { lookup.sourceTypes = sourceTypes; }
lookup.order = { items: [nameof<Reference>(x => x.label)] };
if (like) { lookup.like = this.filterService.transformLike(like); }
return lookup;
}
}

View File

@ -1,21 +1,18 @@
import { FieldDataEditorModel } from "./field-data-editor-model";
import { DatasetProfileInternalDmpEntitiesType } from "../../../../../core/common/enum/dataset-profile-internal-dmp-entities-type";
import { FieldDataOptionEditorModel } from "./field-data-option-editor-model";
import { DatasetsAutoCompleteFieldData } from "../../../../../core/model/dataset-profile-definition/field-data/field-data";
import { UntypedFormGroup } from "@angular/forms";
import { DatasetProfileInternalDmpEntitiesType } from "../../../../../core/common/enum/dataset-profile-internal-dmp-entities-type";
import { DatasetsAutoCompleteFieldData } from "../../../../../core/model/dataset-profile-definition/field-data/field-data";
import { FieldDataEditorModel } from "./field-data-editor-model";
export class DatasetsAutoCompleteFieldDataEditorModel extends FieldDataEditorModel<DatasetsAutoCompleteFieldDataEditorModel> {
public type: DatasetProfileInternalDmpEntitiesType = DatasetProfileInternalDmpEntitiesType.Datasets;
public multiAutoComplete: boolean = false;
public autoCompleteOptions: FieldDataOptionEditorModel = new FieldDataOptionEditorModel();
public autoCompleteType: number;
//public autoCompleteOptions: FieldDataOptionEditorModel = new FieldDataOptionEditorModel();
buildForm(disabled: boolean = false, skipDisable: Array<String> = []): UntypedFormGroup {
const formGroup = this.formBuilder.group({
label: [{ value: this.label, disabled: (disabled && !skipDisable.includes('DatasetsAutoCompleteFieldDataEditorModel.label')) }],
type: [{ value: this.type, disabled: (disabled && !skipDisable.includes('DatasetsAutoCompleteFieldDataEditorModel.type')) }],
multiAutoComplete: [{ value: this.multiAutoComplete, disabled: (disabled && !skipDisable.includes('DatasetsAutoCompleteFieldDataEditorModel.multiAutoComplete')) }],
autoCompleteType: [{ value: this.autoCompleteType, disabled: (disabled && !skipDisable.includes('DatasetsAutoCompleteFieldDataEditorModel.autoCompleteType')) }]
})
return formGroup;
}
@ -24,7 +21,6 @@ export class DatasetsAutoCompleteFieldDataEditorModel extends FieldDataEditorMod
this.label = item.label;
this.type = item.type;
this.multiAutoComplete = item.multiAutoComplete;
this.autoCompleteType = item.autoCompleteType;
return this;
}
}

View File

@ -7,7 +7,7 @@ import { UntypedFormGroup } from "@angular/forms";
export class DmpsAutoCompleteFieldDataEditorModel extends FieldDataEditorModel<DmpsAutoCompleteFieldDataEditorModel> {
public type: DatasetProfileInternalDmpEntitiesType = DatasetProfileInternalDmpEntitiesType.Dmps;
public multiAutoComplete: boolean = false;
public autoCompleteOptions: FieldDataOptionEditorModel = new FieldDataOptionEditorModel();
//public autoCompleteOptions: FieldDataOptionEditorModel = new FieldDataOptionEditorModel();
buildForm(disabled: boolean = false, skipDisable: Array<String> = []): UntypedFormGroup {
const formGroup = this.formBuilder.group({

View File

@ -5,13 +5,11 @@ import { FieldDataEditorModel } from './field-data-editor-model';
export class FieldDataOptionEditorModel extends FieldDataEditorModel<FieldDataOptionEditorModel> {
public label: string;
public value: string;
public source: string;
buildForm(disabled: boolean = false, skipDisable: Array<String> = []): UntypedFormGroup {
return new UntypedFormBuilder().group({
label: [{ value: this.label, disabled: (disabled && !skipDisable.includes('FieldDataOptionEditorModel.label')) },[Validators.required]],
value: [{ value: this.value, disabled: (disabled && !skipDisable.includes('FieldDataOptionEditorModel.value')) },[Validators.required]],
source: [{ value: this.source, disabled: (disabled && !skipDisable.includes('FieldDataOptionEditorModel.source')) }]
});
}
@ -19,7 +17,6 @@ export class FieldDataOptionEditorModel extends FieldDataEditorModel<FieldDataOp
if (item) {
this.label = item.label;
this.value = item.value;
this.source = item.source;
}
return this;
}

View File

@ -8,7 +8,7 @@ export class ResearchersAutoCompleteFieldDataEditorModel extends FieldDataEditor
public type: DatasetProfileInternalDmpEntitiesType = DatasetProfileInternalDmpEntitiesType.Researchers;
public multiAutoComplete: boolean = false;
public autoCompleteOptions: FieldDataOptionEditorModel = new FieldDataOptionEditorModel();
//public autoCompleteOptions: FieldDataOptionEditorModel = new FieldDataOptionEditorModel();
buildForm(disabled: boolean = false, skipDisable: Array<String> = []): UntypedFormGroup {
const formGroup = this.formBuilder.group({

View File

@ -4,16 +4,19 @@ import { ResearchersFieldData } from '../../../../../core/model/dataset-profile-
export class ResearchersDataEditorModel extends FieldDataEditorModel<ResearchersDataEditorModel> {
public label: string;
public multiAutoComplete: boolean = false;
buildForm(disabled: boolean = false, skipDisable: Array<String> = []): UntypedFormGroup {
const formGroup = this.formBuilder.group({
label: [{ value: this.label, disabled: (disabled && !skipDisable.includes('ResearchersDataEditorModel.label')) }]
label: [{ value: this.label, disabled: (disabled && !skipDisable.includes('ResearchersDataEditorModel.label')) }],
multiAutoComplete: [{ value: this.multiAutoComplete, disabled: (disabled && !skipDisable.includes('ResearchersAutoCompleteFieldDataEditorModel.multiAutoComplete')) }]
});
return formGroup;
}
fromModel(item: ResearchersFieldData): ResearchersDataEditorModel {
this.label = item.label;
this.multiAutoComplete = item.multiAutoComplete;
return this;
}
}

View File

@ -18,16 +18,16 @@ const routes: Routes = [
{
path: 'new',
canActivate: [AuthGuard],
component: DmpBlueprintEditorComponent,
canDeactivate: [PendingChangesGuard],
data: {
authContext: {
permissions: [AppPermission.EditDmpBlueprint]
},
...BreadcrumbService.generateRouteDataConfiguration({
title: 'BREADCRUMBS.NEW-DESCRIPTION-TEMPLATE-TYPE'
title: 'BREADCRUMBS.NEW-DMP-BLUEPRINT'
})
},
component: DmpBlueprintEditorComponent,
canDeactivate: [PendingChangesGuard],
}
},
{
path: 'clone/:cloneid',
@ -39,7 +39,7 @@ const routes: Routes = [
},
data: {
...BreadcrumbService.generateRouteDataConfiguration({
title: 'BREADCRUMBS.EDIT-DESCRIPTION-TEMPLATE-TYPE'
title: 'BREADCRUMBS.EDIT-DMP-BLUEPRINT'
}),
authContext: {
permissions: [AppPermission.EditDmpBlueprint]
@ -57,7 +57,7 @@ const routes: Routes = [
},
data: {
...BreadcrumbService.generateRouteDataConfiguration({
title: 'BREADCRUMBS.EDIT-DESCRIPTION-TEMPLATE-TYPE'
title: 'BREADCRUMBS.EDIT-DMP-BLUEPRINT'
}),
authContext: {
permissions: [AppPermission.EditDmpBlueprint]

View File

@ -46,7 +46,7 @@
<h4 class="col-12">{{'DMP-BLUEPRINT-EDITOR.FIELDS.SECTIONS' | translate}}</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 mb-3" cdkDrag [cdkDragDisabled]="viewOnly">
<div *ngFor="let section of formGroup.get('definition').get('sections').controls; let sectionIndex=index;" class="row mb-3" cdkDrag [cdkDragDisabled]="formGroup.disabled">
<div class="col-12">
<mat-card>
<mat-card-header>
@ -55,8 +55,11 @@
<mat-card-title>{{'DMP-BLUEPRINT-EDITOR.FIELDS.SECTION-PREFIX' | translate}} {{sectionIndex + 1}}</mat-card-title>
</div>
<div class="col-auto d-flex"><mat-icon cdkDragHandle style="cursor: move; color: #129d99;">drag_indicator</mat-icon></div>
<div [hidden]="viewOnly" class="col-auto d-flex" (click)="removeSection(sectionIndex)" [disabled]="viewOnly">
<mat-icon class="action-list-icon" matTooltip="{{'DMP-BLUEPRINT-EDITOR.ACTIONS.REMOVE-SECTION' | translate}}">delete</mat-icon>
<div class="col-auto d-flex">
<button mat-icon-button class="action-list-icon" matTooltip="{{'DMP-BLUEPRINT-EDITOR.ACTIONS.REMOVE-SECTION' | translate}}" (click)="removeSection(sectionIndex)" [disabled]="formGroup.disabled">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
</mat-card-header>
@ -81,7 +84,7 @@
<div class="col-6">
<mat-form-field class="w-100">
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.SYSTEM-FIELDS' | translate}}</mat-label>
<mat-select multiple [disabled]="viewOnly" [(ngModel)]="selectedSystemFields" [ngModelOptions]="{standalone: true}">
<mat-select multiple [(ngModel)]="selectedSystemFields" [ngModelOptions]="{standalone: true}">
<mat-option *ngFor="let systemFieldType of dmpBlueprintSystemFieldTypeEnum" [disabled]="systemFieldDisabled(systemFieldType)" [value]="systemFieldType">{{enumUtils.toDmpBlueprintSystemFieldTypeString(systemFieldType)}}</mat-option>
</mat-select>
<!-- <mat-error *ngIf="fieldsArray(sectionIndex).hasError('required')">
@ -89,12 +92,12 @@
</mat-form-field>
</div>
<div class="col-auto">
<button mat-button class="action-btn" type="button" (click)="addExtraField(sectionIndex)" [disabled]="viewOnly">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.ADD-EXTRA-FIELD' | translate}}</button>
<button mat-button class="action-btn" type="button" (click)="addExtraField(sectionIndex)" [disabled]="formGroup.disabled">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.ADD-EXTRA-FIELD' | translate}}</button>
</div>
<div cdkDropList class="col-12" (cdkDropListDropped)="dropFields($event, sectionIndex)">
<div *ngFor="let field of section.get('fields').controls; let fieldIndex=index;" cdkDrag class="row align-items-center" [cdkDragDisabled]="viewOnly">
<div *ngFor="let field of section.get('fields').controls; let fieldIndex=index;" cdkDrag class="row align-items-center" [cdkDragDisabled]="formGroup.disabled">
<div class="col-auto">
<span style="font-size: 15px;">{{fieldIndex + 1}}</span>
@ -140,18 +143,19 @@
<input matInput type="text" name="description" [formControl]="field.get('description')">
</mat-form-field>
</div>
<div class="centered-row-item col-auto">
<mat-checkbox [disabled]="field.get('systemFieldType')?.value === dmpBlueprintSystemFieldType.TEXT || field.get('systemFieldType')?.value === dmpBlueprintSystemFieldType.HTML_TEXT" [formControl]="field.get('required')">{{'DMP-BLUEPRINT-EDITOR.FIELDS.FIELD-REQUIRED' | translate}}</mat-checkbox>
<div class="col-auto">
<mat-checkbox [disabled]="field.get('systemFieldType')?.value === dmpBlueprintSystemFieldType.TEXT || field.get('systemFieldType')?.value === dmpBlueprintSystemFieldType.HTML_TEXT" [formControl]="field.get('required')"><span>{{'DMP-BLUEPRINT-EDITOR.FIELDS.FIELD-REQUIRED' | translate}}</span></mat-checkbox>
</div>
<div *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.SYSTEM" [hidden]="viewOnly" class="field-delete col-auto" (click)="removeSystemField(sectionIndex, fieldIndex)">
<mat-icon class="field-delete-icon">delete</mat-icon>
<span class="field-delete-text">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.REMOVE-SYSTEM-FIELD' | translate}}</span>
<div *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.SYSTEM" [hidden]="viewOnly" class="col-auto">
<button mat-icon-button matTooltip="{{'DMP-BLUEPRINT-EDITOR.ACTIONS.REMOVE-SYSTEM-FIELD' | translate}}" (click)="removeSystemField(sectionIndex, fieldIndex)" [disabled]="formGroup.disabled">
<mat-icon>delete</mat-icon>
</button>
</div>
<div *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.EXTRA" [hidden]="viewOnly" class="field-delete col-auto" (click)="removeExtraField(sectionIndex, fieldIndex)">
<mat-icon class="field-delete-icon">delete</mat-icon>
<span class="field-delete-text">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.REMOVE-EXTRA-FIELD' | translate}}</span>
<div *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.EXTRA" [hidden]="viewOnly" class="col-auto">
<button mat-icon-button matTooltip="{{'DMP-BLUEPRINT-EDITOR.ACTIONS.REMOVE-EXTRA-FIELD' | translate}}" (click)="removeExtraField(sectionIndex, fieldIndex)" [disabled]="formGroup.disabled">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
</div>
</div>
@ -172,7 +176,7 @@
<div class="col-12">
<mat-form-field class="w-100">
<mat-label>{{'DMP-BLUEPRINT-EDITOR.FIELDS.DESCRIPTION-TEMPLATES' | translate}}</mat-label>
<app-multiple-auto-complete [disabled]="viewOnly" [hidePlaceholder]="true" required='false' [configuration]="blueprintsAutoCompleteConfiguration" (optionRemoved)="onRemoveDescritionTemplate($event, sectionIndex)" (optionSelected)="onSelectDescritionTemplate($event, sectionIndex)">
<app-multiple-auto-complete [disabled]="formGroup.disabled" [hidePlaceholder]="true" required='false' [configuration]="blueprintsAutoCompleteConfiguration" (optionRemoved)="onRemoveDescritionTemplate($event, sectionIndex)" (optionSelected)="onSelectDescritionTemplate($event, sectionIndex)">
</app-multiple-auto-complete>
</mat-form-field>
</div>
@ -213,7 +217,7 @@
<div class="col-12">
<div class="row">
<div class="col-auto">
<button mat-button class="action-btn" type="button" (click)="addSection()" [disabled]="viewOnly">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.ADD-SECTION' | translate}}</button>
<button mat-button class="action-btn" type="button" (click)="addSection()" [disabled]="formGroup.disabled">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.ADD-SECTION' | translate}}</button>
</div>
</div>
</div>
@ -223,8 +227,8 @@
<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">
<div class="col-auto">
<button mat-button class="action-btn" [disabled]="formGroup.disabled" type="submit">
{{'DMP-BLUEPRINT-EDITOR.ACTIONS.SAVE' | translate}}
</button>
</div>

View File

@ -3,11 +3,6 @@
margin-left: 1em;
margin-right: 3em;
.centered-row-item {
align-items: center;
display: flex;
}
.remove {
background-color: white;
color: black;

View File

@ -141,6 +141,9 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.authService.hasPermission(AppPermission.EditDmpBlueprint));
this.selectedSystemFields = this.selectedSystemFieldDisabled();
this.dmpBlueprintEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
if (this.editorModel.status == DmpBlueprintStatus.Finalized) {
this.formGroup.disable();
}
}
refreshData(): void {
@ -250,7 +253,7 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
// for (let section in (this.formGroup.get('definition').get('sections')as FormArray)?.controls) {
// if (i != sectionIndex) {
// for (let f of this.fieldsArray(i).controls) {
// if ((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField) {
// if ((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == DmpBlueprintSectionFieldCategory.SYSTEM) && f.get('type').value == systemField) {
// return true;
// }
// }
@ -406,7 +409,7 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
// for (let i = 0; i < sections; i++) {
// let systemFieldsInSection = new Array();
// this.fieldsArray(i).controls.forEach((field) => {
// if ((field.get('category').value == FieldCategory.SYSTEM || field.get('category').value == 'SYSTEM')) {
// if ((field.get('category').value == FieldCategory.SYSTEM || field.get('category').value == DmpBlueprintSectionFieldCategory.SYSTEM)) {
// systemFieldsInSection.push(this.fieldList.find(f => f.type == field.get('type').value).type);
// }
// })
@ -611,12 +614,12 @@ export class DmpBlueprintEditorComponent extends BaseEditor<DmpBlueprintEditorMo
hasTitle(): boolean {
const dmpBlueprint: DmpBlueprintPersist = this.formGroup.value;
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === DmpBlueprintSectionFieldCategory.SYSTEM || field.category as unknown === 'SYSTEM') && field.systemFieldType === DmpBlueprintSystemFieldType.TEXT));
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === DmpBlueprintSectionFieldCategory.SYSTEM || field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM) && field.systemFieldType === DmpBlueprintSystemFieldType.TEXT));
}
hasDescription(): boolean {
const dmpBlueprint: DmpBlueprintPersist = this.formGroup.value;
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === DmpBlueprintSectionFieldCategory.SYSTEM || field.category as unknown === 'SYSTEM') && field.systemFieldType === DmpBlueprintSystemFieldType.HTML_TEXT));
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === DmpBlueprintSectionFieldCategory.SYSTEM || field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM) && field.systemFieldType === DmpBlueprintSystemFieldType.HTML_TEXT));
}
hasDescriptionTemplates(): boolean {

View File

@ -217,7 +217,7 @@ export class FieldInSectionEditorModel implements FieldInSectionPersist {
public label: string;
public placeholder: string;
public description: string;
public required: boolean;
public required: boolean = false;
public ordinal: number;
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();

View File

@ -55,6 +55,12 @@ export class DmpBlueprintEditorResolver extends BaseEditorResolver {
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));
const id = route.paramMap.get('id');
const cloneid = route.paramMap.get('cloneid');
if (id != null) {
return this.dmpBlueprintService.getSingle(Guid.parse(id), fields).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed));
} else if (cloneid != null) {
return this.dmpBlueprintService.clone(Guid.parse(cloneid), fields).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed));
}
}
}

View File

@ -90,13 +90,13 @@
<mat-icon>more_horiz</mat-icon>
</button>
<mat-menu #actionsMenu="matMenu">
<button mat-menu-item [routerLink]="['/dmp-blueprint/' + row.id]">
<button mat-menu-item [routerLink]="['./' + row.id]">
<mat-icon>edit</mat-icon>{{'DMP-BLUEPRINT-LISTING.ACTIONS.EDIT' | translate}}
</button>
<button mat-menu-item [routerLink]="['/dmp-blueprint/clone/' + row.id]">
<button mat-menu-item [routerLink]="['./clone/' + row.id]">
<mat-icon>content_copy</mat-icon>{{'DMP-BLUEPRINT-LISTING.ACTIONS.CLONE' | translate}}
</button>
<button mat-menu-item (click)="export(row.id)" [routerLink]="['/dmp-blueprint/' + row.id]">
<button mat-menu-item (click)="export(row.id)" [routerLink]="['./' + row.id]">
<mat-icon>download</mat-icon>{{'DMP-BLUEPRINT-LISTING.ACTIONS.DOWNLOAD-XML' | translate}}
</button>
<button mat-menu-item (click)="delete(row.id)">

View File

@ -4,6 +4,7 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angu
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { Role } from '@app/core/common/enum/role';
@ -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.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.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.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.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.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
hasProject = true;
}
}

View File

@ -4,6 +4,7 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angu
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
@ -358,7 +359,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.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
hasGrant = true;
}
}
@ -372,7 +373,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.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
hasFunder = true;
}
}
@ -386,7 +387,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.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
hasProject = true;
}
}

View File

@ -4,6 +4,7 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angu
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
@ -310,7 +311,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.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
hasGrant = true;
}
}
@ -324,7 +325,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.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
hasFunder = true;
}
}
@ -338,7 +339,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.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
hasProject = true;
}
}

View File

@ -32,6 +32,7 @@ import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection, FieldInSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Guid } from '@common/types/guid';
import { nameof } from 'ts-simple-nameof';
import { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category';
@Component({
@ -176,7 +177,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.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
hasGrant = true;
}
}
@ -190,7 +191,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.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
hasFunder = true;
}
}
@ -204,7 +205,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.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
hasProject = true;
}
}

View File

@ -134,6 +134,7 @@
<div class="col-auto form" id="editor-form" *ngIf="this.step !== 0">
<div *ngIf="selectedDmpBlueprintDefinition">
{{formGroup.value | json}}
<div *ngFor="let section of selectedDmpBlueprintDefinition.sections; let i=index">
<div class="section-info" [hidden]="this.step !== (i + 1)">
<div class="col-12 intro">
@ -148,7 +149,7 @@
<div class="input-form">
<div *ngIf="field.category === dmpBlueprintSectionFieldCategory.SYSTEM">
<div *ngIf="field.systemFieldType == dmpBlueprintSystemFieldType.TEXT">
<mat-form-field>
<mat-form-field class="w-100">
<input matInput placeholder="{{'DMP-EDITOR.FIELDS.NAME' | translate}}" type="text" name="label" [formControl]="formGroup.get('label')" required>
<mat-error *ngIf="formGroup.get('label').hasError('backendError')">
{{formGroup.get('label').getError('backendError').message}}</mat-error>
@ -161,7 +162,7 @@
</rich-text-editor-component>
</div>
<div *ngIf="field.systemFieldType == dmpBlueprintSystemFieldType.RESEARCHERS">
<mat-form-field>
<mat-form-field class="w-100">
<mat-label>{{'DMP-EDITOR.PLACEHOLDER.RESEARCHERS' | translate}}</mat-label>
<app-multiple-auto-complete [formControl]="formGroup.get('researchers')" [configuration]="researchersAutoCompleteConfiguration">
</app-multiple-auto-complete>
@ -179,7 +180,7 @@
</div>
</div>
<div *ngIf="field.systemFieldType == dmpBlueprintSystemFieldType.ORGANIZATIONS">
<mat-form-field>
<mat-form-field class="w-100">
<mat-label>{{'DMP-EDITOR.PLACEHOLDER.ORGANIZATION' | translate}}</mat-label>
<app-multiple-auto-complete [formControl]="formGroup.get('organisations')" [configuration]="organisationsAutoCompleteConfiguration">
</app-multiple-auto-complete>
@ -196,7 +197,7 @@
</div>
</div>
<div *ngIf="field.systemFieldType == dmpBlueprintSystemFieldType.LANGUAGE">
<mat-form-field>
<mat-form-field class="w-100">
<mat-select [formControl]="formGroup.get('extraProperties').get('language')" placeholder="{{'DMP-EDITOR.FIELDS.LANGUAGE' | translate}}" required>
<mat-option *ngFor="let lang of getLanguageInfos()" [value]="lang.code">
{{ lang.name }}
@ -210,7 +211,7 @@
</div>
<div *ngIf="field.systemFieldType == dmpBlueprintSystemFieldType.CONTACT">
<div class="contact-form">
<mat-form-field>
<mat-form-field class="w-100">
<mat-select [formControl]="formGroup.get('extraProperties').get('contact')" placeholder="{{'DMP-EDITOR.FIELDS.CONTACT' | translate}}">
<mat-option *ngFor="let vis of getAssociates()" [value]="vis.id">
{{vis.name | translate}}
@ -233,7 +234,7 @@
<funding-info [formGroup]="formGroup" [grantformGroup]="formGroup.get('grant')" [projectFormGroup]="formGroup.get('project')" [funderFormGroup]="formGroup.get('funder')" [isFinalized]="isFinalized" [isNew]="isNew" [isUserOwner]="isUserOwner" [isRequired]="field.required" [type]="3" (onFormChanged)="formChanged()"></funding-info>
</div>
<div *ngIf="field.systemFieldType == dmpBlueprintSystemFieldType.LICENSE">
<mat-form-field>
<mat-form-field class="w-100">
<app-single-auto-complete [formControl]="formGroup.get('extraProperties').get('license')" placeholder="{{'DMP-EDITOR.FIELDS.LICENSE' | translate}}" [configuration]="licenseAutoCompleteConfiguration">
</app-single-auto-complete>
<mat-error *ngIf="formGroup.get('extraProperties').get('license').hasError('backendError')">
@ -243,7 +244,7 @@
</mat-form-field>
</div>
<div *ngIf="field.systemFieldType == dmpBlueprintSystemFieldType.ACCESS_RIGHTS">
<mat-form-field>
<mat-form-field class="w-100">
<mat-select [formControl]="formGroup.get('extraProperties').get('visible')" placeholder="{{'DMP-EDITOR.FIELDS.VISIBILITY' | translate}}">
<mat-option *ngFor="let vis of visibles" [value]="vis.value">
{{vis.name | translate}}
@ -256,7 +257,7 @@
</mat-form-field>
</div>
<!-- <div *ngIf="field.systemFieldType == 'DESCRIPTION_TEMPLATES'">
<mat-form-field>
<mat-form-field class="w-100">
<mat-label>{{'DMP-EDITOR.FIELDS.SELECT-TEMPLATE' | translate}}</mat-label>
<app-multiple-auto-complete placeholder="{{'DMP-EDITOR.FIELDS.SELECT-TEMPLATE' | translate}}" [hidePlaceholder]="true" required='true' [formControl]="formGroup.get('profiles')" [configuration]="profilesAutoCompleteConfiguration" (optionRemoved)="onRemoveTemplate($event)" (optionActionClicked)="onPreviewTemplate($event)" (optionSelected)="onOptionSelected()">
</app-multiple-auto-complete>
@ -275,7 +276,7 @@
</div>
<div *ngIf="field.category === dmpBlueprintSectionFieldCategory.EXTRA">
<div *ngIf="field.dataType === dmpBlueprintExtraFieldDataType.TEXT">
<mat-form-field>
<mat-form-field class="w-100">
<input matInput placeholder="{{field.placeholder}}" type="text" name="value" [formControl]="formGroup.get('extraFields').get(getExtraFieldIndex(field.id)).get('value')" [required]="field.required">
</mat-form-field>
</div>
@ -292,12 +293,12 @@
</ng-container>
</div>
<div *ngIf="field.dataType === dmpBlueprintExtraFieldDataType.DATE">
<mat-form-field>
<mat-form-field class="w-100">
<input matInput placeholder="{{field.placeholder}}" type="date" name="value" [formControl]="formGroup.get('extraFields').get(getExtraFieldIndex(field.id)).get('value')" [required]="field.required">
</mat-form-field>
</div>
<div *ngIf="field.dataType === dmpBlueprintExtraFieldDataType.NUMBER">
<mat-form-field>
<mat-form-field class="w-100">
<input matInput placeholder="{{field.placeholder}}" type="number" name="value" [formControl]="formGroup.get('extraFields').get(getExtraFieldIndex(field.id)).get('value')" [required]="field.required">
</mat-form-field>
</div>
@ -312,7 +313,7 @@
<div class="col-12">
<div class="input-form">
<div class="heading">Description templates</div>
<mat-form-field>
<mat-form-field class="w-100">
<mat-label>{{'DMP-EDITOR.FIELDS.SELECT-TEMPLATE' | translate}}</mat-label>
<app-multiple-auto-complete placeholder="{{'DMP-EDITOR.FIELDS.SELECT-TEMPLATE' | translate}}" [hidePlaceholder]="true" required='true' [value]="sectionTemplates[section.ordinal - 1]" [configuration]="profilesAutoCompleteConfiguration" (optionRemoved)="onRemoveTemplate($event, i)" (optionActionClicked)="onPreviewTemplate($event, i)" (optionSelected)="onOptionSelected($event, i)">
</app-multiple-auto-complete>
@ -332,7 +333,7 @@
<!-- <div class="heading">Description templates</div>
<div class="hint">Available templates:</div>
<div *ngFor="let template of section.descriptionTemplates; let k=index">
<mat-form-field>
<mat-form-field class="w-100">
<input matInput placeholder="{{template.label}}" type="text" name="label" [disabled]="true">
</mat-form-field>
</div>

View File

@ -57,6 +57,9 @@ 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 { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category';
import { ReferenceService } from '@app/core/services/reference/reference.service';
import { ReferenceType } from '@app/core/common/enum/reference-type';
import { SourceType } from '@app/core/common/enum/source-type';
interface Visible {
value: boolean;
@ -119,13 +122,21 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im
{ value: false, name: 'DMP-EDITOR.VISIBILITY.RESTRICTED' }
]
licenseAutoCompleteConfiguration: SingleAutoCompleteConfiguration = {
filterFn: this.licenseSearch.bind(this),
initialItems: (excludedItems: any[]) => this.licenseSearch('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
licenseAutoCompleteConfiguration = this.referenceService.getSingleAutocompleteConfiguration([ReferenceType.Licenses]);
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'],
titleFn: (item) => item['name']
titleFn: (item) => item['name'],
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'))
};
researchersAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
filterFn: this.filterResearchers.bind(this),
initialItems: (excludedItems: any[]) => this.filterResearchers('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
displayFn: (item) => item['name'],
titleFn: (item) => item['name'],
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'))
};
profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
@ -154,7 +165,8 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im
private formService: FormService,
private dialog: MatDialog,
private lockService: LockService,
private matomoService: MatomoService
private matomoService: MatomoService,
private referenceService: ReferenceService
) {
super();
}
@ -900,7 +912,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im
private buildExtraFields(): void {
const extraFields = new Array<UntypedFormGroup>();
this.selectedDmpBlueprintDefinition.sections.forEach(section => section.fields.forEach(field => {
if (field.category as unknown == 'EXTRA') {
if (field.category as unknown == DmpBlueprintSectionFieldCategory.EXTRA) {
let extraField = new DmpExtraFieldEditorModel();
extraField.id = field.id.toString();
if (!isNullOrUndefined(this.dmp.extraFields)) {
@ -929,7 +941,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.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
hasGrant = true;
}
}
@ -943,7 +955,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.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
hasFunder = true;
}
}
@ -957,7 +969,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.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
hasProject = true;
}
}
@ -1008,22 +1020,6 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im
}
// dmpBlueprintAutoCompleteConfiguration: SingleAutoCompleteConfiguration = {
// filterFn: this.dmpBlueprintSearch.bind(this),
// initialItems: (extraData) => this.dmpBlueprintSearch(''),
// displayFn: (item) => item['label'],
// titleFn: (item) => item['label']
// };
// dmpBlueprintSearch(query: string) {
// let fields: Array<string> = new Array();
// var request = new DataTableRequest<DmpBlueprintCriteria>(0, 20, { fields: fields });
// request.criteria = new DmpBlueprintCriteria();
// request.criteria.like = query;
// request.criteria.status = DmpBlueprintStatus.Finalized;
// return this.dmpBlueprintService.getPagedBlueprint(request).pipe(map(x => x.data));
// }
getLanguageInfos(): LanguageInfo[] {
return this.languageInfoService.getLanguageInfoValues();
}
@ -1040,20 +1036,7 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im
return associates;
}
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'],
titleFn: (item) => item['name'],
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'))
};
researchersAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = {
filterFn: this.filterResearchers.bind(this),
initialItems: (excludedItems: any[]) => this.filterResearchers('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
displayFn: (item) => item['name'],
titleFn: (item) => item['name'],
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
filterResearchers(value: string): Observable<ExternalSourceItemModel[]> {
@ -1127,14 +1110,6 @@ export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent im
return (!this.isFinalized && this.isUserOwner) || this.isClone;
}
licenseSearch(query: string): Observable<ExternalSourceItemModel[]> {
const request = new RequestItem<LicenseCriteria>();
request.criteria = new LicenseCriteria();
request.criteria.like = query;
request.criteria.type = '';
return this.externalSourcesService.searchLicense(request);
}
allAvailableProfiles(event: MouseEvent) {
event.stopPropagation();
const dialogRef = this.dialog.open(AvailableProfilesComponent, {

View File

@ -4,6 +4,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
import { Role } from '@app/core/common/enum/role';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection, FieldInSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
@ -230,7 +231,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.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
hasGrant = true;
}
}
@ -244,7 +245,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.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
hasFunder = true;
}
}
@ -258,7 +259,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.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
hasProject = true;
}
}

View File

@ -22,6 +22,7 @@ import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog
// import {BreadcrumbItem} from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
import { Location } from '@angular/common';
import { UntypedFormGroup } from '@angular/forms';
import { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category';
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
import { Role } from "@app/core/common/enum/role";
import { DepositConfigurationModel } from '@app/core/model/deposit/deposit-configuration';
@ -265,7 +266,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.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
hasGrant = true;
}
}
@ -279,7 +280,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.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
hasFunder = true;
}
}
@ -293,7 +294,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.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
hasProject = true;
}
}

View File

@ -1,22 +1,29 @@
<div class="form-container">
<div class="row d-flex justify-content-between m-0">
<a class="logo"><img class="logo" src="../../../assets/images/new-dmp-logo.png" onerror="this.style.display='none'"></a>
<div class="container form-container">
<div class="row d-flex justify-content-between align-items-center m-0">
<div class="col-auto"><a class="logo"><img class="logo" src="../../../assets/images/new-dmp-logo.png" onerror="this.style.display='none'"></a></div>
<div class="col-auto ml-auto close-btn" (click)="close()">
<mat-icon class="close-icon">close</mat-icon>
</div>
</div>
<div class="row content">
<h1 mat-dialog-title class="title">{{'NAV-BAR.START-NEW-DMP' | translate}}</h1>
<div class="col-12">
<h1 mat-dialog-title class="title p-0">{{'NAV-BAR.START-NEW-DMP' | translate}}</h1>
</div>
<div class="col-12">
<p class="text">{{'NAV-BAR.START-NEW-DMP-TXT' | translate}}</p>
<div class="actions">
<div class="import-file col-auto">
</div>
<div class="col-12">
<div class="row d-flex justify-content-between align-items-center">
<div class="col-auto">
<button type="button" class="normal-btn upload-btn d-flex flex-row align-items-center" (click)="uploadFile($event)">
<mat-icon class="pr-2">file_upload</mat-icon>
{{ 'NAV-BAR.IMPORT-FROM-FILE' | translate }}
</button>
</div>
<p class="m-0">{{ 'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.FIRST-STEP.OR' | translate }}</p>
<div class="start-wizard col-auto">
<div class="col-auto pl-0 pr-0">
<p class="">{{ 'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.FIRST-STEP.OR' | translate }}</p>
</div>
<div class="col-auto">
<button type="button" class="normal-btn font-weight-bold d-flex flex-row align-items-center" (click)="startWizard()">
<mat-icon>chevron_right</mat-icon>
{{ 'NAV-BAR.START-WIZARD' | translate }}
@ -24,8 +31,11 @@
</div>
</div>
</div>
<div class="row pt-4">
<mat-icon class="col-auto material-icons-outlined warn">info</mat-icon>
</div>
<div class="row m-0 pt-4">
<div class="col-auto">
<mat-icon class="material-icons-outlined warn">info</mat-icon>
</div>
<span class="col">
<b>{{'GENERAL.START-NEW-DMP-DIALOG.IMPORT' | translate }}</b> {{'GENERAL.START-NEW-DMP-DIALOG.FUNCTION-SUPPORTS' | translate }}
<b>{{'GENERAL.START-NEW-DMP-DIALOG.JSON-FILES' | translate }}</b> {{'GENERAL.START-NEW-DMP-DIALOG.PRODUCED' | translate }}

View File

@ -4,6 +4,7 @@ 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 { DmpBlueprintSectionFieldCategory } from '@app/core/common/enum/dmp-blueprint-section-field-category';
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';
@ -20,7 +21,6 @@ import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
import { BaseComponent } from '@common/base/base.component';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { TranslateService } from '@ngx-translate/core';
import { Observable, of as observableOf } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
@Component({
@ -94,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.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) {
hasGrant = true;
}
}
@ -108,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.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) {
hasFunder = true;
}
}
@ -122,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.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
if (field.category as unknown === DmpBlueprintSectionFieldCategory.SYSTEM && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) {
hasProject = true;
}
}

View File

@ -5,8 +5,6 @@
@import '../node_modules/@swimlane/ngx-datatable/themes/material.scss';
@import '../node_modules/@swimlane/ngx-datatable/assets/icons.css';
@import "~bootstrap/dist/css/bootstrap.css";
//Material-Bootstrap configuration
@import "assets/scss/bootstrap-material";