add "DmpSectionIndex" column to descriptions in order to know in which section of a dmp the description belongs, add "data" column in DmpDatasetProfile table, data stores in which sections a description template is saved

This commit is contained in:
Bernaldo Mihasi 2023-09-11 08:57:09 +03:00
parent 6073c4cd85
commit 4219d90039
29 changed files with 535 additions and 212 deletions

View File

@ -3,6 +3,7 @@ package eu.eudat.data.dao.entities;
import eu.eudat.data.dao.DatabaseAccessLayer;
import eu.eudat.data.dao.criteria.DatasetProfileCriteria;
import eu.eudat.data.entities.DescriptionTemplate;
import eu.eudat.data.entities.DescriptionTemplateType;
import eu.eudat.queryable.QueryableList;
import java.util.List;
@ -18,6 +19,6 @@ public interface DatasetProfileDao extends DatabaseAccessLayer<DescriptionTempla
List<DescriptionTemplate> getAllIds();
Long countWithType(UUID id);
Long countWithType(DescriptionTemplateType type);
}

View File

@ -128,7 +128,7 @@ public class DatasetProfileDaoImpl extends DatabaseAccess<DescriptionTemplate> i
}
@Override
public Long countWithType(UUID id) {
return this.getDatabaseService().getQueryable(DescriptionTemplate.class).where((builder, root) -> builder.equal(root.get("type"), id)).count();
public Long countWithType(DescriptionTemplateType type) {
return this.getDatabaseService().getQueryable(DescriptionTemplate.class).where((builder, root) -> builder.equal(root.get("type"), type)).count();
}
}

View File

@ -113,11 +113,7 @@ public class DMP implements DataEntity<DMP, UUID> {
@Column(name = "\"AssociatedDmps\"", columnDefinition = "xml", nullable = true)
private String associatedDmps;*/
@OneToMany(fetch = FetchType.LAZY)
@JoinTable(name = "\"DMPDatasetProfile\"",
joinColumns = {@JoinColumn(name = "\"dmp\"", referencedColumnName = "\"ID\"")},
inverseJoinColumns = {@JoinColumn(name = "\"datasetprofile\"", referencedColumnName = "\"ID\"")}
)
private Set<DescriptionTemplate> associatedDmps;
private Set<DMPDatasetProfile> associatedDmps;
@ManyToOne(fetch = FetchType.LAZY)
@ -274,10 +270,10 @@ public class DMP implements DataEntity<DMP, UUID> {
this.grant = grant;
}
public Set<DescriptionTemplate> getAssociatedDmps() {
public Set<DMPDatasetProfile> getAssociatedDmps() {
return associatedDmps;
}
public void setAssociatedDmps(Set<DescriptionTemplate> associatedDmps) {
public void setAssociatedDmps(Set<DMPDatasetProfile> associatedDmps) {
this.associatedDmps = associatedDmps;
}

View File

@ -0,0 +1,77 @@
package eu.eudat.data.entities;
import eu.eudat.queryable.queryableentity.DataEntity;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;
import javax.persistence.*;
import java.util.List;
import java.util.UUID;
@Entity
@Table(name = "\"DMPDatasetProfile\"")
public class DMPDatasetProfile implements DataEntity<DMPDatasetProfile, UUID> {
@Id
@GeneratedValue
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
private UUID id;
@ManyToOne
@JoinColumn(name = "\"dmp\"")
private DMP dmp;
@ManyToOne
@JoinColumn(name = "\"datasetprofile\"")
private DescriptionTemplate datasetprofile;
@Column(name = "\"data\"")
private String data;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public DMP getDmp() {
return dmp;
}
public void setDmp(DMP dmp) {
this.dmp = dmp;
}
public DescriptionTemplate getDatasetprofile() {
return datasetprofile;
}
public void setDatasetprofile(DescriptionTemplate datasetprofile) {
this.datasetprofile = datasetprofile;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
@Override
public void update(DMPDatasetProfile entity) {
this.dmp = entity.getDmp();
this.datasetprofile = entity.getDatasetprofile();
this.data = entity.getData();
}
@Override
public UUID getKeys() {
return this.id;
}
@Override
public DMPDatasetProfile buildFromTuple(List<Tuple> tuple, List<String> fields, String base) {
this.id = UUID.fromString((String) tuple.get(0).get(base.isEmpty() ? base + "." + "id" : "id"));
return this;
}
}

View File

@ -100,6 +100,9 @@ public class Dataset implements DataEntity<Dataset, UUID> {
@JoinColumn(name = "\"DMP\"", nullable = false)
private DMP dmp;
@Column(name = "\"DmpSectionIndex\"")
private Integer dmpSectionIndex;
@Column(name = "\"Uri\"")
private String uri;
@ -232,6 +235,12 @@ public class Dataset implements DataEntity<Dataset, UUID> {
this.dmp = dmp;
}
public Integer getDmpSectionIndex() {
return dmpSectionIndex;
}
public void setDmpSectionIndex(Integer dmpSectionIndex) {
this.dmpSectionIndex = dmpSectionIndex;
}
public String getUri() {
return uri;
@ -328,6 +337,7 @@ public class Dataset implements DataEntity<Dataset, UUID> {
this.setRegistries(entity.getRegistries());
this.setDmp(entity.getDmp());
this.setDmpSectionIndex(entity.getDmpSectionIndex());
this.setStatus(entity.getStatus());
this.setProfile(entity.getProfile());
this.setModified(new Date());

View File

@ -79,12 +79,8 @@ public class DescriptionTemplate implements DataEntity<DescriptionTemplate,UUID>
@Column(name = "\"Version\"", nullable = false)
private Short version;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "\"DMPDatasetProfile\"",
joinColumns = {@JoinColumn(name = "\"datasetprofile\"", referencedColumnName = "\"ID\"")},
inverseJoinColumns = {@JoinColumn(name = "\"dmp\"", referencedColumnName = "\"ID\"")}
)
private List<DMP> dmps;
@OneToMany(fetch = FetchType.LAZY)
private Set<DMP> dmps;
@Column(name = "\"Language\"", nullable = false)
private String language;

View File

@ -5,6 +5,7 @@ import eu.eudat.configurations.dynamicgrant.DynamicGrantConfiguration;
import eu.eudat.configurations.dynamicgrant.entities.Property;
import eu.eudat.data.dao.criteria.*;
import eu.eudat.data.dao.entities.*;
import eu.eudat.data.entities.DescriptionTemplate;
import eu.eudat.data.entities.Organisation;
import eu.eudat.data.entities.Researcher;
import eu.eudat.data.entities.*;
@ -1755,7 +1756,8 @@ public class DataManagementPlanManager {
Element profiles = xmlDoc.createElement("profiles");
// Get DatasetProfiles from DMP to add to XML.
for (DescriptionTemplate descriptionTemplate : dmp.getAssociatedDmps()) {
for (DMPDatasetProfile dmpDescriptionProfile : dmp.getAssociatedDmps()) {
DescriptionTemplate descriptionTemplate = dmpDescriptionProfile.getDatasetprofile();
Element profile = xmlDoc.createElement("profile");
Element profileId = xmlDoc.createElement("profileId");
profileId.setTextContent(descriptionTemplate.getId().toString());

View File

@ -26,6 +26,7 @@ public class DatasetWizardModel implements DataModel<Dataset, DatasetWizardModel
private short status;
private Date created;
private DataManagementPlan dmp;
private Integer dmpSectionIndex;
private PagedDatasetProfile datasetProfileDefinition;
private List<Registry> registries;
private List<Service> services;
@ -92,6 +93,13 @@ public class DatasetWizardModel implements DataModel<Dataset, DatasetWizardModel
this.dmp = dmp;
}
public Integer getDmpSectionIndex() {
return dmpSectionIndex;
}
public void setDmpSectionIndex(Integer dmpSectionIndex) {
this.dmpSectionIndex = dmpSectionIndex;
}
public PagedDatasetProfile getDatasetProfileDefinition() {
return datasetProfileDefinition;
}
@ -179,6 +187,7 @@ public class DatasetWizardModel implements DataModel<Dataset, DatasetWizardModel
this.services = entity.getServices() != null ? entity.getServices().stream().map(item -> new Service().fromDataModel(item.getService())).collect(Collectors.toList()) : new ArrayList<>();
this.created = entity.getCreated();
this.dmp = new DataManagementPlan().fromDataModelNoDatasets(entity.getDmp());
this.dmpSectionIndex = entity.getDmpSectionIndex();
this.externalDatasets = entity.getDatasetExternalDatasets() != null ? entity.getDatasetExternalDatasets().stream().map(item -> {
ExternalDatasetListingModel externalDatasetListingModel = new ExternalDatasetListingModel().fromDataModel(item.getExternalDataset());
if (item.getData() != null) {
@ -202,6 +211,7 @@ public class DatasetWizardModel implements DataModel<Dataset, DatasetWizardModel
this.profile = new DatasetProfileOverviewModel();
this.profile = this.profile.fromDataModel(entity.getProfile());
this.uri = entity.getUri();
this.dmpSectionIndex = entity.getDmpSectionIndex();
this.registries = entity.getRegistries() != null ? entity.getRegistries().stream().map(item -> new Registry().fromDataModel(item)).collect(Collectors.toList()) : new ArrayList<>();
this.dataRepositories = entity.getDatasetDataRepositories() != null ? entity.getDatasetDataRepositories().stream().map(item -> {
DataRepository dataRepository = new DataRepository().fromDataModel(item.getDataRepository());
@ -241,6 +251,7 @@ public class DatasetWizardModel implements DataModel<Dataset, DatasetWizardModel
DMP dmp = new DMP();
dmp.setId(this.dmp.getId());
entity.setDmp(dmp);
entity.setDmpSectionIndex(this.dmpSectionIndex);
entity.setDescription(this.description);
entity.setCreated(this.created != null ? this.created : new Date());
entity.setModified(new Date());

View File

@ -5,12 +5,14 @@ import eu.eudat.logic.utilities.interfaces.XmlSerializable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.util.Map;
import java.util.UUID;
public class AssociatedProfile implements XmlSerializable<AssociatedProfile> {
private UUID id;
private String label;
private Map<String, Object> data;
public UUID getId() {
return id;
@ -28,6 +30,14 @@ public class AssociatedProfile implements XmlSerializable<AssociatedProfile> {
this.label = label;
}
public Map<String, Object> getData() {
return data;
}
public void setData(Map<String, Object> data) {
this.data = data;
}
@Override
public Element toXml(Document doc) {
Element profile = doc.createElement("profile");

View File

@ -1,5 +1,7 @@
package eu.eudat.models.data.dmp;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.entities.*;
import eu.eudat.logic.utilities.builders.XmlBuilder;
import eu.eudat.models.DataModel;
@ -258,8 +260,14 @@ public class DataManagementPlan implements DataModel<DMP, DataManagementPlan> {
if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) {
this.profiles = new LinkedList<>();
for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) {
AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate);
for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) {
AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile());
try {
associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference<Map<String, Object>>() {}));
}
catch (Exception e) {
associatedProfile.setData(null);
}
this.profiles.add(associatedProfile);
}
}
@ -320,11 +328,16 @@ public class DataManagementPlan implements DataModel<DMP, DataManagementPlan> {
dataManagementPlanEntity.setProject(this.project.toDataModel());
}
if (this.profiles != null) {
Set<DescriptionTemplate> descriptionTemplates = new HashSet<>();
Set<DMPDatasetProfile> dmpDatasetProfiles = new HashSet<>();
for (AssociatedProfile profile : this.profiles) {
descriptionTemplates.add(profile.toData());
DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile();
dmpDatasetProfile.setId(UUID.randomUUID());
dmpDatasetProfile.setDmp(dataManagementPlanEntity);
dmpDatasetProfile.setDatasetprofile(profile.toData());
dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData()));
dmpDatasetProfiles.add(dmpDatasetProfile);
}
dataManagementPlanEntity.setAssociatedDmps(descriptionTemplates);
dataManagementPlanEntity.setAssociatedDmps(dmpDatasetProfiles);
}
dataManagementPlanEntity.setProperties(this.properties != null ? JSONObject.toJSONString(this.properties) : null);
dataManagementPlanEntity.setGroupId(this.groupId != null ? this.groupId : UUID.randomUUID());
@ -365,8 +378,14 @@ public class DataManagementPlan implements DataModel<DMP, DataManagementPlan> {
if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) {
this.profiles = new LinkedList<>();
for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) {
AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate);
for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) {
AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile());
try {
associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference<Map<String, Object>>() {}));
}
catch (Exception e) {
associatedProfile.setData(null);
}
this.profiles.add(associatedProfile);
}
}

View File

@ -1,5 +1,7 @@
package eu.eudat.models.data.dmp;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.entities.*;
import eu.eudat.logic.utilities.builders.XmlBuilder;
import eu.eudat.models.DataModel;
@ -249,8 +251,14 @@ public class DataManagementPlanEditorModel implements DataModel<DMP, DataManagem
if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) {
this.profiles = new LinkedList<>();
for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) {
AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate);
for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) {
AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile());
try {
associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference<Map<String, Object>>() {}));
}
catch (Exception e) {
associatedProfile.setData(null);
}
this.profiles.add(associatedProfile);
}
}
@ -358,11 +366,16 @@ public class DataManagementPlanEditorModel implements DataModel<DMP, DataManagem
}
dataManagementPlanEntity.setDescription(this.description);
if (this.profiles != null) {
Set<DescriptionTemplate> descriptionTemplates = new HashSet<>();
Set<DMPDatasetProfile> dmpDatasetProfiles = new HashSet<>();
for (AssociatedProfile profile : this.profiles) {
descriptionTemplates.add(profile.toData());
DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile();
dmpDatasetProfile.setId(UUID.randomUUID());
dmpDatasetProfile.setDmp(dataManagementPlanEntity);
dmpDatasetProfile.setDatasetprofile(profile.toData());
dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData()));
dmpDatasetProfiles.add(dmpDatasetProfile);
}
dataManagementPlanEntity.setAssociatedDmps(descriptionTemplates);
dataManagementPlanEntity.setAssociatedDmps(dmpDatasetProfiles);
}
dataManagementPlanEntity.setProperties(this.properties != null ? JSONObject.toJSONString(this.properties) : null);
dataManagementPlanEntity.setGroupId(this.groupId != null ? this.groupId : UUID.randomUUID());

View File

@ -1,5 +1,6 @@
package eu.eudat.models.data.dmp;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.entities.*;
import eu.eudat.models.DataModel;
import eu.eudat.models.data.dataset.Dataset;
@ -260,8 +261,18 @@ public class DataManagementPlanNewVersionModel implements DataModel<DMP, DataMan
}
entity.setExtraProperties(this.extraProperties != null ? JSONObject.toJSONString(this.extraProperties) : null);
if (this.profiles != null)
entity.setAssociatedDmps(this.profiles.stream().map(x -> x.toData()).collect(Collectors.toSet()));
if (this.profiles != null) {
Set<DMPDatasetProfile> dmpDatasetProfiles = new HashSet<>();
for (AssociatedProfile profile : this.profiles) {
DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile();
dmpDatasetProfile.setId(UUID.randomUUID());
dmpDatasetProfile.setDmp(entity);
dmpDatasetProfile.setDatasetprofile(profile.toData());
dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData()));
dmpDatasetProfiles.add(dmpDatasetProfile);
}
entity.setAssociatedDmps(dmpDatasetProfiles);
}
return entity;
}

View File

@ -1,6 +1,9 @@
package eu.eudat.models.data.listingmodels;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.entities.DMP;
import eu.eudat.data.entities.DMPDatasetProfile;
import eu.eudat.data.entities.Dataset;
import eu.eudat.data.entities.DescriptionTemplate;
import eu.eudat.models.DataModel;
@ -11,10 +14,7 @@ import eu.eudat.models.data.dmp.Researcher;
import eu.eudat.models.data.doi.Doi;
import eu.eudat.models.data.grant.GrantOverviewModel;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.stream.Collectors;
public class DataManagementPlanOverviewModel implements DataModel<DMP, DataManagementPlanOverviewModel> {
@ -205,8 +205,14 @@ public class DataManagementPlanOverviewModel implements DataModel<DMP, DataManag
if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) {
this.associatedProfiles = new LinkedList<>();
for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) {
AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate);
for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) {
AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile());
try {
associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference<Map<String, Object>>() {}));
}
catch (Exception e) {
associatedProfile.setData(null);
}
this.associatedProfiles.add(associatedProfile);
}
}

View File

@ -5,11 +5,13 @@ import eu.eudat.logic.utilities.interfaces.XmlSerializable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.util.Map;
import java.util.UUID;
public class AssociatedProfilePublicModel implements XmlSerializable<AssociatedProfilePublicModel> {
private UUID id;
private String label;
private Map<String, Object> data;
public UUID getId() {
return id;
@ -27,6 +29,14 @@ public class AssociatedProfilePublicModel implements XmlSerializable<AssociatedP
this.label = label;
}
public Map<String, Object> getData() {
return data;
}
public void setData(Map<String, Object> data) {
this.data = data;
}
@Override
public Element toXml(Document doc) {
Element profile = doc.createElement("profile");

View File

@ -1,10 +1,14 @@
package eu.eudat.publicapi.models.overviewmodels;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.entities.DMP;
import eu.eudat.data.entities.DMPDatasetProfile;
import eu.eudat.data.entities.Dataset;
import eu.eudat.data.entities.DescriptionTemplate;
import eu.eudat.logic.utilities.builders.XmlBuilder;
import eu.eudat.models.DataModel;
import eu.eudat.models.data.dmp.AssociatedProfile;
import eu.eudat.models.data.user.composite.PagedDatasetProfile;
import eu.eudat.publicapi.models.associatedprofile.AssociatedProfilePublicModel;
import eu.eudat.publicapi.models.doi.DoiPublicModel;
@ -193,8 +197,14 @@ public class DataManagementPlanPublicModel implements DataModel<DMP, DataManagem
if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) {
this.associatedProfiles = new LinkedList<>();
for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) {
AssociatedProfilePublicModel associatedProfile = new AssociatedProfilePublicModel().fromData(descriptionTemplate);
for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) {
AssociatedProfilePublicModel associatedProfile = new AssociatedProfilePublicModel().fromData(dmpDescriptionProfile.getDatasetprofile());
try {
associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference<Map<String, Object>>() {}));
}
catch (Exception e) {
associatedProfile.setData(null);
}
this.associatedProfiles.add(associatedProfile);
}
}

View File

@ -129,7 +129,8 @@ COMMENT ON COLUMN public."DMP"."AssociatedDmps" IS 'More data about the DMP as d
CREATE TABLE public."DMPDatasetProfile" (
"ID" uuid DEFAULT public.uuid_generate_v4() NOT NULL,
dmp uuid NOT NULL,
datasetprofile uuid NOT NULL
datasetprofile uuid NOT NULL,
"data" text
);
@ -235,6 +236,7 @@ CREATE TABLE public."Dataset" (
"ID" uuid DEFAULT public.uuid_generate_v4() NOT NULL,
"Label" character varying(250) NOT NULL,
"DMP" uuid,
"DmpSectionIndex" integer,
"Uri" character varying(250),
"Properties" text,
"Profile" uuid,

View File

@ -0,0 +1,15 @@
DO $$DECLARE
this_version CONSTANT varchar := '00.00.014';
BEGIN
PERFORM * FROM "DBVersion" WHERE version = this_version;
IF FOUND THEN RETURN; END IF;
ALTER TABLE public."Dataset"
ADD COLUMN "DmpSectionIndex" integer;
ALTER TABLE public."DMPDatasetProfile"
ADD COLUMN "data" text;
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.015', '2023-09-01 12:00:00.000000+02', now(), 'Add column DmpSectionIndex to Dataset table and data to DMPDatasetProfile.');
END$$;

View File

@ -14,6 +14,7 @@ export interface DatasetWizardModel {
description?: String;
status?: number;
dmp?: DmpModel;
dmpSectionIndex?: number;
datasetProfileDefinition?: DatasetProfileDefinitionModel;
registries?: RegistryModel[];
services?: ServiceModel[];

View File

@ -0,0 +1,28 @@
import { FormGroup, FormBuilder } from "@angular/forms";
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";
export class DmpDatasetProfileSectionsFormModel {
public dmpSectionIndex: number[] = [];
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
fromModel(item: any): DmpDatasetProfileSectionsFormModel {
this.dmpSectionIndex = item.dmpSectionIndex;
return this;
}
buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup {
if (context == null) { context = this.createValidationContext(); }
const formGroup = new FormBuilder().group({
language: [{ value: this.dmpSectionIndex, disabled: disabled }, context.getValidation('dmpSectionIndex').validators],
});
return formGroup;
}
createValidationContext(): ValidationContext {
const baseContext: ValidationContext = new ValidationContext();
baseContext.validation.push({ key: 'dmpSectionIndex', validators: [BackendErrorValidator(this.validationErrorModel, 'dmpSectionIndex')] });
return baseContext;
}
}

View File

@ -0,0 +1,7 @@
import { DmpDatasetProfileSectionsFormModel } from "./dmp-dataset-profile-sections-form.model";
export interface DmpDatasetProfile {
id: string;
label: string;
data: DmpDatasetProfileSectionsFormModel;
}

View File

@ -1,17 +1,15 @@
import { Status } from "../../common/enum/status";
import { DmpProfile, DmpProfileDefinition } from "../dmp-profile/dmp-profile";
import { DmpProfileDefinition } from "../dmp-profile/dmp-profile";
import { OrganizationModel } from "../organisation/organization";
import { GrantListingModel } from "../grant/grant-listing";
import { ResearcherModel } from "../researcher/researcher";
import { UserModel } from "../user/user";
import { DmpDynamicField } from "./dmp-dynamic-field";
import { UserInfoListingModel } from "../user/user-info-listing";
import { DatasetModel } from "../dataset/dataset";
import { ProjectModel } from "../project/project";
import { FunderModel } from "../funder/funder";
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { ExtraPropertiesFormModel } from '@app/ui/dmp/editor/general-tab/extra-properties-form.model';
import { DatasetWizardModel } from '../dataset/dataset-wizard';
import { DmpDatasetProfile } from "./dmp-dataset-profile/dmp-dataset-profile";
export interface DmpModel {
id: string;
@ -27,7 +25,7 @@ export interface DmpModel {
funder: FunderModel;
datasets: DatasetWizardModel[];
datasetsToBeFinalized: string[];
profiles: DmpProfile[];
profiles: DmpDatasetProfile[];
organisations: OrganizationModel[];
researchers: ResearcherModel[];
associatedUsers: UserModel[];

View File

@ -26,6 +26,7 @@ export class DatasetWizardEditorModel {
public tags: ExternalTagEditorModel[] = [];
public externalDatasets: ExternalDatasetEditorModel[] = [];
public dmp: DmpModel;
public dmpSectionIndex: number;
public datasetProfileDefinition: DatasetDescriptionFormEditorModel;
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
public isProfileLatestVersion: Boolean;
@ -43,6 +44,7 @@ export class DatasetWizardEditorModel {
if (item.dataRepositories) { this.dataRepositories = item.dataRepositories.map(x => new ExternalDataRepositoryEditorModel().fromModel(x)); }
if (item.externalDatasets) { this.externalDatasets = item.externalDatasets.map(x => new ExternalDatasetEditorModel().fromModel(x)); }
this.dmp = item.dmp;
this.dmpSectionIndex = item.dmpSectionIndex;
if (item.datasetProfileDefinition) { this.datasetProfileDefinition = new DatasetDescriptionFormEditorModel().fromModel(item.datasetProfileDefinition); }
if (item.tags) { this.tags = item.tags.map(x => new ExternalTagEditorModel().fromModel(x)); }
this.isProfileLatestVersion = item.isProfileLatestVersion;
@ -60,6 +62,7 @@ export class DatasetWizardEditorModel {
status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators],
description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators],
dmp: [{ value: this.dmp, disabled: disabled }, context.getValidation('dmp').validators],
dmpSectionIndex: [{ value: this.dmpSectionIndex, disabled: disabled }, context.getValidation('dmpSectionIndex').validators],
//externalDatasets: [{ value: this.externalDatasets, disabled: disabled }, context.getValidation('externalDatasets').validators],
tags: [{ value: this.tags, disabled: disabled }, context.getValidation('tags').validators],
//registries: [{ value: this.registries, disabled: disabled }, context.getValidation('registries').validators],
@ -143,6 +146,7 @@ export class DatasetWizardEditorModel {
baseContext.validation.push({ key: 'dataRepositories', validators: [BackendErrorValidator(this.validationErrorModel, 'dataRepositories')] });
baseContext.validation.push({ key: 'externalDatasets', validators: [BackendErrorValidator(this.validationErrorModel, 'externalDatasets')] });
baseContext.validation.push({ key: 'dmp', validators: [BackendErrorValidator(this.validationErrorModel, 'dmp')] });
baseContext.validation.push({ key: 'dmpSectionIndex', validators: [BackendErrorValidator(this.validationErrorModel, 'dmpSectionIndex')] });
baseContext.validation.push({ key: 'datasetProfileDefinition', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] });
baseContext.validation.push({ key: 'tags', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] });
baseContext.validation.push({ key: 'modified', validators: []});

View File

@ -95,6 +95,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme
finalize: boolean = false;
itemId: string;
dmpId: string;
dmpSectionIndex: number;
newDmpId: string;
publicId: string;
profileUpdateId: string;
@ -171,6 +172,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme
const data: any = this.route.snapshot.data;
this.itemId = params['id'];
this.dmpId = params['dmpId'];
this.dmpSectionIndex = params['dmpSectionIndex'];
this.newDmpId = queryParams['newDmpId'];
this.publicId = params['publicId'];
this.profileUpdateId = params['updateId'];
@ -266,6 +268,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme
this.datasetWizardModel = new DatasetWizardEditorModel();
setTimeout(() => {
this.datasetWizardModel.dmp = data;
this.datasetWizardModel.dmpSectionIndex = this.dmpSectionIndex;
this.formGroup = this.datasetWizardModel.buildForm();
this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue()));
this.editMode = this.datasetWizardModel.status === DatasetStatus.Draft;
@ -283,6 +286,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme
if(result) {
this.datasetWizardModel = this.datasetWizardModel.fromModel(result);
this.datasetWizardModel.dmp = data;
this.datasetWizardModel.dmpSectionIndex = this.dmpSectionIndex;
this.formGroup = this.datasetWizardModel.buildForm();
this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue()));
this.formGroup.get('dmp').disable();

View File

@ -8,7 +8,7 @@ import { DatasetOverviewComponent } from './overview/dataset-overview.component'
const routes: Routes = [
{
path: 'new/:dmpId',
path: 'new/:dmpId/:dmpSectionIndex',
component: DatasetWizardComponent,
canActivate: [AuthGuard],
data: {

View File

@ -34,18 +34,27 @@
</div>
</div>
<div class="row">
<div class="col-auto dmp-stepper">
<div class="col-auto dmp-stepper" *ngIf="this.step != 0">
<div class="stepper-title">DMP Blueprint</div>
<div class="stepper-options">
<ol class="stepper-list" start="0">
<li (click)="changeStep(0)" [ngClass]="{'active': this.step === 0}">Select Blueprint</li>
<ol class="stepper-list" start="1">
<!-- <li (click)="changeStep(0)" [ngClass]="{'active': this.step === 0}">Select Blueprint</li> -->
<div *ngIf="selectedDmpBlueprintDefinition && this.step !== 0">
<li (click)="changeStep(i + 1)" *ngFor="let section of selectedDmpBlueprintDefinition.sections; let i=index" [ngClass]="{'active': this.step === (i + 1)}">{{section.label}}</li>
<div *ngFor="let section of selectedDmpBlueprintDefinition.sections; let i=index">
<li (click)="changeStep(i + 1)" [ngClass]="{'active': this.step === (i + 1)}">{{section.label}}</li>
<ul *ngIf="hasProfile()" class="add-dataset-option">
<li>
<a class="add-dataset-action" [routerLink]="['/datasets/new/' + dmp.id]">
<mat-icon>add</mat-icon>{{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}
</a>
</li>
</ul>
</div>
</div>
</ol>
</div>
<div class="stepper-actions" *ngIf="this.step !== 0">
<div mat-raised-button type="button" class="col-auto previous stepper-btn mr-2 ml-auto" [ngClass]="{'previous-disabled': this.step === 0}" (click)="previousStep()">
<div mat-raised-button type="button" class="col-auto previous stepper-btn mr-2 ml-auto" [ngClass]="{'previous-disabled': this.step === 1}" (click)="previousStep()">
<span class="material-icons">chevron_left</span>
<div>{{'DMP-EDITOR.STEPPER.PREVIOUS' | translate}}</div>
</div>
@ -54,16 +63,16 @@
<span class="material-icons">chevron_right</span>
</div>
<!-- <div *ngIf="this.step >= 3 && hasProfile() && !isFinalized" mat-raised-button type="button" class="col-auto stepper-btn add-dataset-btn ml-auto" (click)="addDataset()" target="_blank"> -->
<button [disabled]="saving" *ngIf="this.step >= this.maxStep && !isFinalized" mat-raised-button type="button" class="col-auto stepper-btn add-dataset-btn ml-auto" (click)="addDataset()" target="_blank">
<!-- <button [disabled]="saving" *ngIf="this.step >= this.maxStep && !isFinalized" mat-raised-button type="button" class="col-auto stepper-btn add-dataset-btn ml-auto" (click)="addDataset()" target="_blank"> -->
<!-- <mat-icon>add</mat-icon> -->
{{'DMP-EDITOR.ACTIONS.SAVE' | translate}} & {{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}
</button>
<!-- {{'DMP-EDITOR.ACTIONS.SAVE' | translate}} & {{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}
</button> -->
</div>
<div class="col-auto pr-0" *ngIf="this.step !== 0">
<app-form-progress-indication class="col-12" *ngIf="formGroup && !formGroup.disabled && !lockStatus" [formGroup]="formGroup" [isDmpEditor]="true"></app-form-progress-indication>
</div>
</div>
<div class="col-auto form" id="editor-form">
<div class="col-auto formForStep0" id="editor-form" *ngIf="this.step ===0">
<div class="col-12 blueprint-section" [hidden]="this.step !== 0">
<div class="input-form">
<div class="heading2">0.1 Title of DMP *</div>
@ -106,177 +115,210 @@
</div>
</div>
</div>
</div>
<div class="col-auto form" id="editor-form" *ngIf="this.step !==0">
<div *ngIf="selectedDmpBlueprintDefinition">
<div *ngFor="let section of selectedDmpBlueprintDefinition.sections; let i=index">
<div class="section-info" [hidden]="this.step !== (i + 1)">
<div class="col-12 intro">
{{section.description}}
</div>
<div class="col-12 card">
<div class="col-12 card" *ngIf="section.fields.length > 0">
<div class="row">
<div class="col-12">
<div *ngFor="let field of section.systemFields; let j=index">
<div *ngFor="let field of section.fields; let j=index">
<div class="heading">{{i + 1}}.{{j + 1}} {{field.label}}<span *ngIf="field.required">*</span></div>
<div *ngIf="field.description != null && field.description.length > 0" class="hint">{{field.description}}</div>
<div class="input-form">
<div *ngIf="field.type == 'TEXT'">
<mat-form-field>
<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>
<mat-error *ngIf="formGroup.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> -->
</mat-form-field>
</div>
<div *ngIf="field.type == 'HTML_TEXT'">
<rich-text-editor-component [parentFormGroup]="formGroup" [controlName]="'description'"
[placeholder]="'DMP-EDITOR.PLACEHOLDER.DESCRIPTION'">
</rich-text-editor-component>
</div>
<div *ngIf="field.type == 'RESEARCHERS'">
<mat-form-field>
<mat-label>{{'DMP-EDITOR.PLACEHOLDER.RESEARCHERS' | translate}}</mat-label>
<app-multiple-auto-complete [formControl]="formGroup.get('researchers')" [configuration]="researchersAutoCompleteConfiguration">
</app-multiple-auto-complete>
<mat-error *ngIf="formGroup.get('researchers').hasError('backendError')">
{{formGroup.get('researchers').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('researchers').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<!-- <button matSuffix class="input-btn" [disabled]="formGroup.get('researchers').disabled" type="button" (click)="addResearcher($event)">
<mat-icon class="icon-btn">add_circle</mat-icon>
</button> -->
</mat-form-field>
<div class="mb-4">
<span *ngIf="!formGroup.get('researchers').disabled" class="not-found">{{'DMP-EDITOR.FUNDING-INFO.FIND' | translate}}</span>
<span *ngIf="!formGroup.get('researchers').disabled" class="insert-manually" (click)="addResearcher($event)">{{'DMP-EDITOR.ACTIONS.INSERT-MANUALLY' | translate}}</span>
</div>
</div>
<div *ngIf="field.type == 'ORGANIZATIONS'">
<mat-form-field>
<mat-label>{{'DMP-EDITOR.PLACEHOLDER.ORGANIZATION' | translate}}</mat-label>
<app-multiple-auto-complete [formControl]="formGroup.get('organisations')" [configuration]="organisationsAutoCompleteConfiguration">
</app-multiple-auto-complete>
<mat-error *ngIf="formGroup.get('organisations').hasError('backendError')">
{{formGroup.get('organisations').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('organisations').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<!-- <button *ngIf="showOrganizationCreator()" matSuffix class="input-btn" [disabled]="cantAddOrganizations()" type="button" (click)="addOrganization($event)">
<mat-icon class="icon-btn">add_circle</mat-icon>
</button> -->
</mat-form-field>
<div *ngIf="showOrganizationCreator()" class="mb-4">
<span *ngIf="!cantAddOrganizations()" class="not-found">{{'DMP-EDITOR.FUNDING-INFO.FIND' | translate}}</span>
<span *ngIf="!cantAddOrganizations()" class="insert-manually" (click)="addOrganization($event)">{{'DMP-EDITOR.ACTIONS.INSERT-MANUALLY' | translate}}</span>
</div>
</div>
<div *ngIf="field.type == 'LANGUAGE'">
<mat-form-field>
<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 }}
</mat-option>
</mat-select>
<mat-error *ngIf="formGroup.get('extraProperties').get('language').hasError('backendError')">
{{formGroup.get('extraProperties').get('language').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('extraProperties').get('language').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div *ngIf="field.type == 'CONTACT'">
<div class="contact-form">
<div *ngIf="field.category === 'SYSTEM'">
<div *ngIf="field.type == 0">
<mat-form-field>
<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}}
<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>
<mat-error *ngIf="formGroup.get('label').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> -->
</mat-form-field>
</div>
<div *ngIf="field.type == 1">
<rich-text-editor-component [parentFormGroup]="formGroup" [controlName]="'description'"
[placeholder]="'DMP-EDITOR.PLACEHOLDER.DESCRIPTION'">
</rich-text-editor-component>
</div>
<div *ngIf="field.type == 2">
<mat-form-field>
<mat-label>{{'DMP-EDITOR.PLACEHOLDER.RESEARCHERS' | translate}}</mat-label>
<app-multiple-auto-complete [formControl]="formGroup.get('researchers')" [configuration]="researchersAutoCompleteConfiguration">
</app-multiple-auto-complete>
<mat-error *ngIf="formGroup.get('researchers').hasError('backendError')">
{{formGroup.get('researchers').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('researchers').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<!-- <button matSuffix class="input-btn" [disabled]="formGroup.get('researchers').disabled" type="button" (click)="addResearcher($event)">
<mat-icon class="icon-btn">add_circle</mat-icon>
</button> -->
</mat-form-field>
<div class="mb-4">
<span *ngIf="!formGroup.get('researchers').disabled" class="not-found">{{'DMP-EDITOR.FUNDING-INFO.FIND' | translate}}</span>
<span *ngIf="!formGroup.get('researchers').disabled" class="insert-manually" (click)="addResearcher($event)">{{'DMP-EDITOR.ACTIONS.INSERT-MANUALLY' | translate}}</span>
</div>
</div>
<div *ngIf="field.type == 3">
<mat-form-field>
<mat-label>{{'DMP-EDITOR.PLACEHOLDER.ORGANIZATION' | translate}}</mat-label>
<app-multiple-auto-complete [formControl]="formGroup.get('organisations')" [configuration]="organisationsAutoCompleteConfiguration">
</app-multiple-auto-complete>
<mat-error *ngIf="formGroup.get('organisations').hasError('backendError')">
{{formGroup.get('organisations').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('organisations').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<!-- <button *ngIf="showOrganizationCreator()" matSuffix class="input-btn" [disabled]="cantAddOrganizations()" type="button" (click)="addOrganization($event)">
<mat-icon class="icon-btn">add_circle</mat-icon>
</button> -->
</mat-form-field>
<div *ngIf="showOrganizationCreator()" class="mb-4">
<span *ngIf="!cantAddOrganizations()" class="not-found">{{'DMP-EDITOR.FUNDING-INFO.FIND' | translate}}</span>
<span *ngIf="!cantAddOrganizations()" class="insert-manually" (click)="addOrganization($event)">{{'DMP-EDITOR.ACTIONS.INSERT-MANUALLY' | translate}}</span>
</div>
</div>
<div *ngIf="field.type == 4">
<mat-form-field>
<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 }}
</mat-option>
</mat-select>
<mat-error *ngIf="formGroup.get('extraProperties').get('contact').hasError('backendError')">
{{formGroup.get('extraProperties').get('contact').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('extraProperties').get('contact').hasError('required')">
<mat-error *ngIf="formGroup.get('extraProperties').get('language').hasError('backendError')">
{{formGroup.get('extraProperties').get('language').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('extraProperties').get('language').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div *ngIf="field.type == 5">
<div class="contact-form">
<mat-form-field>
<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}}
</mat-option>
</mat-select>
<mat-error *ngIf="formGroup.get('extraProperties').get('contact').hasError('backendError')">
{{formGroup.get('extraProperties').get('contact').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('extraProperties').get('contact').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</div>
<div *ngIf="field.type == 6">
<funding-info [formGroup]="formGroup" [grantformGroup]="formGroup.get('grant')" [projectFormGroup]="formGroup.get('project')" [funderFormGroup]="formGroup.get('funder')" [isFinalized]="false" [isNew]="true" [isUserOwner]="true" [type]="1" (onFormChanged)="formChanged()"></funding-info>
</div>
<div *ngIf="field.type == 7">
<funding-info [formGroup]="formGroup" [grantformGroup]="formGroup.get('grant')" [projectFormGroup]="formGroup.get('project')" [funderFormGroup]="formGroup.get('funder')" [isFinalized]="false" [isNew]="true" [isUserOwner]="true" [type]="2" (onFormChanged)="formChanged()"></funding-info>
</div>
<div *ngIf="field.type == 8">
<funding-info [formGroup]="formGroup" [grantformGroup]="formGroup.get('grant')" [projectFormGroup]="formGroup.get('project')" [funderFormGroup]="formGroup.get('funder')" [isFinalized]="false" [isNew]="true" [isUserOwner]="true" [type]="3" (onFormChanged)="formChanged()"></funding-info>
</div>
<div *ngIf="field.type == 9">
<mat-form-field>
<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')">
{{formGroup.get('extraProperties').get('license').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('extraProperties').get('license').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div *ngIf="field.type == 10">
<mat-form-field>
<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}}
</mat-option>
</mat-select>
<mat-error *ngIf="formGroup.get('extraProperties').get('visible').hasError('backendError')">
{{formGroup.get('extraProperties').get('visible').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('extraProperties').get('visible').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<!-- <div *ngIf="field.type == 'DESCRIPTION_TEMPLATES'">
<mat-form-field>
<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>
<mat-error *ngIf="formGroup.get('profiles').hasError('backendError')">
{{formGroup.get('profiles').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('profiles').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<button matSuffix class="input-btn" [disabled]="formGroup.get('profiles').disabled" (click)="allAvailableProfiles($event)">
<mat-icon class="icon-btn">view_list</mat-icon>
</button>
</mat-form-field>
<div class="col pl-0 pt-2 pb-3 d-flex">
<span class="not-found">{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.SECOND-STEP.FIELDS.HELP' | translate}}</span>
</div>
</div> -->
</div>
<div *ngIf="field.type == 'FUNDER'">
<funding-info [formGroup]="formGroup" [grantformGroup]="formGroup.get('grant')" [projectFormGroup]="formGroup.get('project')" [funderFormGroup]="formGroup.get('funder')" [isFinalized]="false" [isNew]="true" [isUserOwner]="true" [type]="1" (onFormChanged)="formChanged()"></funding-info>
</div>
<div *ngIf="field.type == 'GRANT'">
<funding-info [formGroup]="formGroup" [grantformGroup]="formGroup.get('grant')" [projectFormGroup]="formGroup.get('project')" [funderFormGroup]="formGroup.get('funder')" [isFinalized]="false" [isNew]="true" [isUserOwner]="true" [type]="2" (onFormChanged)="formChanged()"></funding-info>
</div>
<div *ngIf="field.type == 'PROJECT'">
<funding-info [formGroup]="formGroup" [grantformGroup]="formGroup.get('grant')" [projectFormGroup]="formGroup.get('project')" [funderFormGroup]="formGroup.get('funder')" [isFinalized]="false" [isNew]="true" [isUserOwner]="true" [type]="3" (onFormChanged)="formChanged()"></funding-info>
</div>
<div *ngIf="field.type == 'LICENSE'">
<mat-form-field>
<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')">
{{formGroup.get('extraProperties').get('license').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('extraProperties').get('license').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div *ngIf="field.type == 'ACCESS_RIGHTS'">
<mat-form-field>
<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}}
</mat-option>
</mat-select>
<mat-error *ngIf="formGroup.get('extraProperties').get('visible').hasError('backendError')">
{{formGroup.get('extraProperties').get('visible').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('extraProperties').get('visible').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div *ngIf="field.type == 'DESCRIPTION_TEMPLATES'">
<mat-form-field>
<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>
<mat-error *ngIf="formGroup.get('profiles').hasError('backendError')">
{{formGroup.get('profiles').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('profiles').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<button matSuffix class="input-btn" [disabled]="formGroup.get('profiles').disabled" (click)="allAvailableProfiles($event)">
<mat-icon class="icon-btn">view_list</mat-icon>
</button>
</mat-form-field>
<div class="col pl-0 pt-2 pb-3 d-flex">
<span class="not-found">{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.SECOND-STEP.FIELDS.HELP' | translate}}</span>
<div *ngIf="field.category === 'EXTRA'">
<div *ngIf="field.type == 'TEXT'">
<mat-form-field>
<input matInput placeholder="field.placeholder" type="text" name="label" [formControl]="label" [required]="field.required">
</mat-form-field>
</div>
<div *ngIf="field.type == 'RICH_TEXT'">
<mat-form-field>
<!-- <rich-text-editor-component [parentFormGroup]="formGroup" [controlName]="'label'"
[placeholder]="field.placeholder">
</rich-text-editor-component> -->
</mat-form-field>
</div>
<div *ngIf="field.type == 'DATE'">
<mat-form-field>
<input matInput placeholder="field.placeholder" type="date" name="label" [formControl]="label" [required]="field.required">
</mat-form-field>
</div>
<div *ngIf="field.type == 'NUMBER'">
<mat-form-field>
<input matInput placeholder="field.placeholder" type="number" name="label" [formControl]="label" [required]="field.required">
</mat-form-field>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-12 card" *ngIf="section.hasTemplates">
<div class="row">
<div class="col-12">
<div *ngFor="let extraField of section.extraFields; let k=index">
<div class="heading">{{i + 1}}.{{k + 1}} {{extraField.label}}<span *ngIf="extraField.required">*</span></div>
<div *ngIf="extraField.description != null && extraField.description.length > 0" class="hint">{{extraField.description}}</div>
<div class="input-form">
<div *ngIf="extraField.type == 'TEXT'">
<mat-form-field>
<input matInput placeholder="extraField.placeholder" type="text" name="label" [formControl]="label" [required]="extraField.required">
</mat-form-field>
</div>
<div *ngIf="extraField.type == 'RICH_TEXT'">
<mat-form-field>
<!-- <rich-text-editor-component [parentFormGroup]="formGroup" [controlName]="'label'"
[placeholder]="extraField.placeholder">
</rich-text-editor-component> -->
</mat-form-field>
</div>
<div *ngIf="extraField.type == 'DATE'">
<mat-form-field>
<input matInput placeholder="extraField.placeholder" type="date" name="label" [formControl]="label" [required]="extraField.required">
</mat-form-field>
</div>
<div *ngIf="extraField.type == 'NUMBER'">
<mat-form-field>
<input matInput placeholder="extraField.placeholder" type="number" name="label" [formControl]="label" [required]="extraField.required">
</mat-form-field>
</div>
<div class="input-form">
<div class="heading">Description templates</div>
<mat-form-field>
<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)" (optionActionClicked)="onPreviewTemplate($event)" (optionSelected)="onOptionSelected()">
</app-multiple-auto-complete>
<mat-error *ngIf="formGroup.get('profiles').hasError('backendError')">
{{formGroup.get('profiles').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('profiles').hasError('required')">
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<!-- <button matSuffix class="input-btn" [disabled]="formGroup.get('profiles').disabled" (click)="allAvailableProfiles($event)">
<mat-icon class="icon-btn">view_list</mat-icon>
</button> -->
</mat-form-field>
<div class="col pl-0 pt-0 pb-0 d-flex">
<span class="not-found-template">{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.SECOND-STEP.FIELDS.HELP' | translate}}</span>
</div>
</div>
<!-- <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>
<input matInput placeholder="{{template.label}}" type="text" name="label" [disabled]="true">
</mat-form-field>
</div>
<button [disabled]="saving" mat-raised-button type="button" class="stepper-btn add-dataset-btn mb-4" (click)="addDataset(i)" target="_blank">
{{'DMP-EDITOR.ACTIONS.SAVE' | translate}} & {{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}
</button> -->
</div>
</div>
</div>

View File

@ -192,6 +192,10 @@ mat-icon.size-16 {
text-align: left;
font-size: 13.8px;
}
.add-dataset-option {
list-style-type: none;
}
.add-dataset-action {
display: flex;
@ -241,6 +245,13 @@ mat-icon.size-16 {
height: calc(100vh - 218px);
}
.formForStep0 {
position: relative;
width: 100%;
overflow-y: auto;
height: calc(100vh - 218px);
}
.action-btn {
border-radius: 30px;
background-color: var(--secondary-color);
@ -348,6 +359,13 @@ a:hover {
padding: 0rem 0.5rem 0rem 0rem;
}
.not-found-template {
font-size: 0.875rem;
font-weight: 400;
padding: 0rem 0.5rem 0rem 0rem;
color: #212121;
}
.disabled-toggle {
font-size: 1rem;
font-weight: 400;

View File

@ -45,6 +45,8 @@ import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog
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';
interface Visible {
value: boolean;
@ -73,6 +75,7 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit
isCreateNewFunder = false;
dmp: DmpEditorModel;
dmpSectionIndex: number = 0;
formGroup: FormGroup = null;
formGroupRawValue: any;
@ -90,6 +93,8 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit
selectedDmpBlueprintDefinition: DmpBlueprintDefinition = null;
sectionTemplates: Array<Array<DatasetProfileModel>> = new Array<Array<DatasetProfileModel>>();
private associates: UserModel[] = [];
visibles: Visible[] = [
@ -161,7 +166,7 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit
}
try{
const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[];
const profiles = this.formGroup.get('profiles').value as DmpDatasetProfile[];
profiles.sort((a,b)=>a.label.localeCompare(b.label));
}catch{
console.info('Could not sort profiles');
@ -243,7 +248,11 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit
document.getElementById('editor-form').scrollTop = 0;
}
addDataset() {
hasProfile(): boolean {
return this.formGroup.get('profiles') && this.formGroup.get('profiles').value && this.formGroup.get('profiles').value.length > 0;
}
addDataset(dmpSectionIndex: number) {
this.saving = true;
if(!this._isDMPDescriptionValid()){
@ -256,7 +265,7 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit
// const showDialog = this.hasProfile() && this.isNew;
this.dmpSectionIndex = dmpSectionIndex;
this.onSubmit(true, false);
// this.formSubmit(true, false);
@ -328,7 +337,7 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
// this.router.navigate(['datasets/new/' + id]);
this.addDataset();
this.addDataset(this.dmpSectionIndex);
} else {
dmp.id != null ? this.router.navigate(['/plans', 'edit', dmp.id]) : this.router.navigate(['/plans']);
}
@ -404,7 +413,7 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
if (isNew) {
this.router.navigate(['/datasets', 'new', id]);
this.router.navigate(['/datasets', 'new', id, this.dmpSectionIndex]);
} else {
this.router.navigate(['/datasets', 'edit', id]);
}
@ -412,7 +421,7 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit
});
}else{
if (isNew) {
this.router.navigate(['/datasets', 'new', id]);
this.router.navigate(['/datasets', 'new', id, this.dmpSectionIndex]);
} else {
this.router.navigate(['/datasets', 'edit', id]);
}
@ -563,6 +572,30 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit
.subscribe(Option => {
if (Option instanceof Object) {
this.selectedDmpBlueprintDefinition = Option.definition;
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 => {
section.descriptionTemplates.forEach(template => {
this.sectionTemplates[section.ordinal - 1].push({id: template.descriptionTemplateId, label: template.label, description: ""})
let data: DmpDatasetProfileSectionsFormModel= new DmpDatasetProfileSectionsFormModel();
data.dmpSectionIndex.push(section.ordinal - 1);
let profile: DmpDatasetProfile = {
id: template.descriptionTemplateId,
label: template.label,
data: data
};
let found: DmpDatasetProfile = templates.find(dmpDatasetProfile => dmpDatasetProfile.id == profile.id);
if (found === undefined) {
templates.push(profile);
}
else {
found.data.dmpSectionIndex.push(section.ordinal - 1);
}
});
});
this.formGroup.get('profiles').setValue(templates);
}
else {
this.selectedDmpBlueprintDefinition = null;

View File

@ -2,8 +2,7 @@ import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { DmpProfileFieldDataType } from '@app/core/common/enum/dmp-profile-field-type';
import { DmpProfileType } from '@app/core/common/enum/dmp-profile-type';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DatasetModel } from '@app/core/model/dataset/dataset';
import { DmpProfile, DmpProfileDefinition } from '@app/core/model/dmp-profile/dmp-profile';
import { DmpProfileDefinition } from '@app/core/model/dmp-profile/dmp-profile';
import { DmpProfileField } from '@app/core/model/dmp-profile/dmp-profile-field';
import { DmpModel } from '@app/core/model/dmp/dmp';
import { DmpDynamicField } from '@app/core/model/dmp/dmp-dynamic-field';
@ -23,8 +22,7 @@ import { ValidationContext } from '@common/forms/validation/validation-context';
import { ExtraPropertiesFormModel } from './general-tab/extra-properties-form.model';
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
import { DatasetWizardEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model';
import { DatasetsAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/datasets-autocomplete-field-data-editor-mode';
import { DatasetWizardModel } from '@app/core/model/dataset/dataset-wizard';
import { DmpDatasetProfile } from "@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile";
export class DmpEditorModel {
public id: string;
@ -41,7 +39,7 @@ export class DmpEditorModel {
public funder: FunderFormModel;
public organisations: OrganizationModel[] = [];
public researchers: ResearcherModel[] = [];
public profiles: DmpProfile[] = [];
public profiles: DmpDatasetProfile[] = [];
public datasets: DatasetWizardEditorModel[] = [];
// public datasets: DatasetModel[] = [];
public datasetsToBeFinalized: string[] = [];

View File

@ -17,6 +17,7 @@ import { ValidationContext } from '@common/forms/validation/validation-context';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties-form.model';
import { UserInfoListingModel } from '@app/core/model/user/user-info-listing';
import { DmpDatasetProfile } from "@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile";
export class DmpWizardEditorModel {
public id: string;
@ -33,7 +34,7 @@ export class DmpWizardEditorModel {
public project: ProjectFormModel;
public organisations: OrganizationModel[] = [];
public researchers: ResearcherModel[] = [];
public profiles: DmpProfile[] = [];
public profiles: DmpDatasetProfile[] = [];
public associatedUsers: UserModel[] = [];
public users: UserInfoListingModel[] = [];
public definition: DmpProfileDefinition;