parent
128b47d9c3
commit
09d6528f8f
|
@ -0,0 +1,6 @@
|
||||||
|
package eu.eudat.data.dao.criteria;
|
||||||
|
|
||||||
|
import eu.eudat.data.entities.DMPProfile;
|
||||||
|
|
||||||
|
public class DataManagementPlanBlueprintCriteria extends Criteria<DMPProfile> {
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.eudat.data.dao.entities;
|
package eu.eudat.data.dao.entities;
|
||||||
|
|
||||||
import eu.eudat.data.dao.DatabaseAccessLayer;
|
import eu.eudat.data.dao.DatabaseAccessLayer;
|
||||||
|
import eu.eudat.data.dao.criteria.DataManagementPlanBlueprintCriteria;
|
||||||
import eu.eudat.data.dao.criteria.DataManagementPlanProfileCriteria;
|
import eu.eudat.data.dao.criteria.DataManagementPlanProfileCriteria;
|
||||||
import eu.eudat.data.entities.DMP;
|
import eu.eudat.data.entities.DMP;
|
||||||
import eu.eudat.data.entities.DMPProfile;
|
import eu.eudat.data.entities.DMPProfile;
|
||||||
|
@ -15,4 +16,6 @@ public interface DMPProfileDao extends DatabaseAccessLayer<DMPProfile, UUID> {
|
||||||
|
|
||||||
QueryableList<DMPProfile> getWithCriteria(DataManagementPlanProfileCriteria criteria);
|
QueryableList<DMPProfile> getWithCriteria(DataManagementPlanProfileCriteria criteria);
|
||||||
|
|
||||||
|
QueryableList<DMPProfile> getWithCriteriaBlueprint(DataManagementPlanBlueprintCriteria criteria);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.eudat.data.dao.entities;
|
package eu.eudat.data.dao.entities;
|
||||||
|
|
||||||
import eu.eudat.data.dao.DatabaseAccess;
|
import eu.eudat.data.dao.DatabaseAccess;
|
||||||
|
import eu.eudat.data.dao.criteria.DataManagementPlanBlueprintCriteria;
|
||||||
import eu.eudat.data.dao.criteria.DataManagementPlanProfileCriteria;
|
import eu.eudat.data.dao.criteria.DataManagementPlanProfileCriteria;
|
||||||
import eu.eudat.data.dao.databaselayer.service.DatabaseService;
|
import eu.eudat.data.dao.databaselayer.service.DatabaseService;
|
||||||
import eu.eudat.data.entities.DMPProfile;
|
import eu.eudat.data.entities.DMPProfile;
|
||||||
|
@ -65,4 +66,13 @@ public class DMPProfileDaoImpl extends DatabaseAccess<DMPProfile> implements DMP
|
||||||
query.where(((builder, root) -> builder.notEqual(root.get("status"), DMPProfile.Status.DELETED.getValue())));
|
query.where(((builder, root) -> builder.notEqual(root.get("status"), DMPProfile.Status.DELETED.getValue())));
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QueryableList<DMPProfile> getWithCriteriaBlueprint(DataManagementPlanBlueprintCriteria criteria){
|
||||||
|
QueryableList<DMPProfile> query = getDatabaseService().getQueryable(DMPProfile.class);
|
||||||
|
if (criteria.getLike() != null && !criteria.getLike().isEmpty())
|
||||||
|
query.where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + criteria.getLike().toUpperCase() + "%"));
|
||||||
|
query.where(((builder, root) -> builder.notEqual(root.get("status"), DMPProfile.Status.DELETED.getValue())));
|
||||||
|
return query;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package eu.eudat.data.query.items.dmpblueprint;
|
||||||
|
|
||||||
|
import eu.eudat.data.dao.criteria.DataManagementPlanBlueprintCriteria;
|
||||||
|
import eu.eudat.data.entities.DMPProfile;
|
||||||
|
import eu.eudat.data.query.PaginationService;
|
||||||
|
import eu.eudat.data.query.definition.TableQuery;
|
||||||
|
import eu.eudat.queryable.QueryableList;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class DataManagementPlanBlueprintTableRequest extends TableQuery<DataManagementPlanBlueprintCriteria, DMPProfile, UUID> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QueryableList<DMPProfile> applyCriteria() {
|
||||||
|
QueryableList<DMPProfile> query = this.getQuery();
|
||||||
|
if (this.getCriteria().getLike() != null && !this.getCriteria().getLike().isEmpty())
|
||||||
|
query.where((builder, root) -> builder.like(root.get("label"), "%" + this.getCriteria().getLike() + "%"));
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QueryableList<DMPProfile> applyPaging(QueryableList<DMPProfile> items) {
|
||||||
|
return PaginationService.applyPaging(items, this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package eu.eudat.controllers;
|
||||||
import eu.eudat.data.dao.criteria.RequestItem;
|
import eu.eudat.data.dao.criteria.RequestItem;
|
||||||
import eu.eudat.data.entities.DMPProfile;
|
import eu.eudat.data.entities.DMPProfile;
|
||||||
import eu.eudat.data.entities.DescriptionTemplate;
|
import eu.eudat.data.entities.DescriptionTemplate;
|
||||||
|
import eu.eudat.data.query.items.dmpblueprint.DataManagementPlanBlueprintTableRequest;
|
||||||
import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest;
|
import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest;
|
||||||
import eu.eudat.logic.managers.DataManagementProfileManager;
|
import eu.eudat.logic.managers.DataManagementProfileManager;
|
||||||
import eu.eudat.logic.security.claims.ClaimedAuthorities;
|
import eu.eudat.logic.security.claims.ClaimedAuthorities;
|
||||||
|
@ -11,6 +12,7 @@ import eu.eudat.models.data.helpermodels.Tuple;
|
||||||
import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem;
|
import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem;
|
||||||
import eu.eudat.models.data.helpers.common.DataTableData;
|
import eu.eudat.models.data.helpers.common.DataTableData;
|
||||||
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
||||||
|
import eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel;
|
||||||
import eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel;
|
import eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel;
|
||||||
import eu.eudat.models.data.security.Principal;
|
import eu.eudat.models.data.security.Principal;
|
||||||
import eu.eudat.types.ApiMessageCode;
|
import eu.eudat.types.ApiMessageCode;
|
||||||
|
@ -52,6 +54,14 @@ public class DMPProfileController extends BaseController {
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DMPProfile>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created"));
|
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DMPProfile>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@RequestMapping(method = RequestMethod.POST, value = {"/blueprint"}, consumes = "application/json", produces = "application/json")
|
||||||
|
public @ResponseBody
|
||||||
|
ResponseEntity<ResponseItem<DMPProfile>> createOrUpdateBlueprint(@RequestBody DataManagementPlanBlueprintListingModel dataManagementPlan, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception {
|
||||||
|
this.dataManagementProfileManager.createOrUpdateBlueprint(dataManagementPlan, principal);
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DMPProfile>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created"));
|
||||||
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = {"/getSingle/{id}"}, produces = "application/json")
|
@RequestMapping(method = RequestMethod.GET, value = {"/getSingle/{id}"}, produces = "application/json")
|
||||||
public @ResponseBody
|
public @ResponseBody
|
||||||
ResponseEntity<ResponseItem<DataManagementPlanProfileListingModel>> getSingle(@PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException {
|
ResponseEntity<ResponseItem<DataManagementPlanProfileListingModel>> getSingle(@PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException {
|
||||||
|
@ -59,6 +69,13 @@ public class DMPProfileController extends BaseController {
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DataManagementPlanProfileListingModel>().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlanProfileListingModel));
|
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DataManagementPlanProfileListingModel>().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlanProfileListingModel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = {"/getSingleBlueprint/{id}"}, produces = "application/json")
|
||||||
|
public @ResponseBody
|
||||||
|
ResponseEntity<ResponseItem<DataManagementPlanBlueprintListingModel>> getSingleBlueprint(@PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException {
|
||||||
|
DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel = this.dataManagementProfileManager.getSingleBlueprint(id, principal);
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DataManagementPlanBlueprintListingModel>().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlanBlueprintListingModel));
|
||||||
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = {"/getPaged"}, consumes = "application/json", produces = "application/json")
|
@RequestMapping(method = RequestMethod.POST, value = {"/getPaged"}, consumes = "application/json", produces = "application/json")
|
||||||
public @ResponseBody
|
public @ResponseBody
|
||||||
ResponseEntity<ResponseItem<DataTableData<DataManagementPlanProfileListingModel>>> getPaged(@Valid @RequestBody DataManagementPlanProfileTableRequest dataManagementPlanProfileTableRequest, Principal principal) throws Exception {
|
ResponseEntity<ResponseItem<DataTableData<DataManagementPlanProfileListingModel>>> getPaged(@Valid @RequestBody DataManagementPlanProfileTableRequest dataManagementPlanProfileTableRequest, Principal principal) throws Exception {
|
||||||
|
@ -66,6 +83,13 @@ public class DMPProfileController extends BaseController {
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DataTableData<DataManagementPlanProfileListingModel>>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable));
|
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DataTableData<DataManagementPlanProfileListingModel>>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.POST, value = {"/getPagedBlueprint"}, consumes = "application/json", produces = "application/json")
|
||||||
|
public @ResponseBody
|
||||||
|
ResponseEntity<ResponseItem<DataTableData<DataManagementPlanBlueprintListingModel>>> getPagedBlueprint(@Valid @RequestBody DataManagementPlanBlueprintTableRequest dataManagementPlanBlueprintTableRequest, Principal principal) throws Exception {
|
||||||
|
DataTableData<DataManagementPlanBlueprintListingModel> dataTable = this.dataManagementProfileManager.getPagedBlueprint(dataManagementPlanBlueprintTableRequest, principal);
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DataTableData<DataManagementPlanBlueprintListingModel>>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable));
|
||||||
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, value = {"/getXml/{id}"}, produces = "application/json")
|
@RequestMapping(method = RequestMethod.GET, value = {"/getXml/{id}"}, produces = "application/json")
|
||||||
public @ResponseBody
|
public @ResponseBody
|
||||||
ResponseEntity getXml( @RequestHeader("Content-Type") String contentType, @PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException, IOException {
|
ResponseEntity getXml( @RequestHeader("Content-Type") String contentType, @PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException, IOException {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.jayway.jsonpath.JsonPath;
|
||||||
import eu.eudat.data.dao.criteria.RequestItem;
|
import eu.eudat.data.dao.criteria.RequestItem;
|
||||||
import eu.eudat.data.dao.entities.DMPProfileDao;
|
import eu.eudat.data.dao.entities.DMPProfileDao;
|
||||||
import eu.eudat.data.entities.DMPProfile;
|
import eu.eudat.data.entities.DMPProfile;
|
||||||
|
import eu.eudat.data.query.items.dmpblueprint.DataManagementPlanBlueprintTableRequest;
|
||||||
import eu.eudat.data.query.items.item.dmpprofile.DataManagementPlanProfileCriteriaRequest;
|
import eu.eudat.data.query.items.item.dmpprofile.DataManagementPlanProfileCriteriaRequest;
|
||||||
import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest;
|
import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest;
|
||||||
import eu.eudat.logic.services.operations.DatabaseRepository;
|
import eu.eudat.logic.services.operations.DatabaseRepository;
|
||||||
|
@ -17,6 +18,7 @@ import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Field;
|
||||||
import eu.eudat.models.data.helpermodels.Tuple;
|
import eu.eudat.models.data.helpermodels.Tuple;
|
||||||
import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem;
|
import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem;
|
||||||
import eu.eudat.models.data.helpers.common.DataTableData;
|
import eu.eudat.models.data.helpers.common.DataTableData;
|
||||||
|
import eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel;
|
||||||
import eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel;
|
import eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel;
|
||||||
import eu.eudat.models.data.security.Principal;
|
import eu.eudat.models.data.security.Principal;
|
||||||
import eu.eudat.queryable.QueryableList;
|
import eu.eudat.queryable.QueryableList;
|
||||||
|
@ -78,6 +80,20 @@ public class DataManagementProfileManager {
|
||||||
return dataTable;
|
return dataTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DataTableData<DataManagementPlanBlueprintListingModel> getPagedBlueprint(DataManagementPlanBlueprintTableRequest dataManagementPlanBlueprintTableRequest, Principal principal) throws Exception {
|
||||||
|
|
||||||
|
QueryableList<DMPProfile> items = apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().getWithCriteriaBlueprint(dataManagementPlanBlueprintTableRequest.getCriteria());
|
||||||
|
QueryableList<DMPProfile> pagedItems = PaginationManager.applyPaging(items, dataManagementPlanBlueprintTableRequest);
|
||||||
|
|
||||||
|
DataTableData<DataManagementPlanBlueprintListingModel> dataTable = new DataTableData<>();
|
||||||
|
|
||||||
|
CompletableFuture itemsFuture = pagedItems
|
||||||
|
.selectAsync(item -> new DataManagementPlanBlueprintListingModel().fromDataModel(item)).whenComplete((resultList, throwable) -> dataTable.setData(resultList));
|
||||||
|
CompletableFuture countFuture = items.countAsync().whenComplete((count, throwable) -> dataTable.setTotalCount(count));
|
||||||
|
CompletableFuture.allOf(itemsFuture, countFuture).join();
|
||||||
|
return dataTable;
|
||||||
|
}
|
||||||
|
|
||||||
public DataManagementPlanProfileListingModel getSingle(String id, Principal principal) throws InstantiationException, IllegalAccessException {
|
public DataManagementPlanProfileListingModel getSingle(String id, Principal principal) throws InstantiationException, IllegalAccessException {
|
||||||
DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id));
|
DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id));
|
||||||
DataManagementPlanProfileListingModel dataManagementPlanProfileListingModel = new DataManagementPlanProfileListingModel();
|
DataManagementPlanProfileListingModel dataManagementPlanProfileListingModel = new DataManagementPlanProfileListingModel();
|
||||||
|
@ -85,6 +101,13 @@ public class DataManagementProfileManager {
|
||||||
return dataManagementPlanProfileListingModel;
|
return dataManagementPlanProfileListingModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DataManagementPlanBlueprintListingModel getSingleBlueprint(String id, Principal principal) throws InstantiationException, IllegalAccessException {
|
||||||
|
DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id));
|
||||||
|
DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel = new DataManagementPlanBlueprintListingModel();
|
||||||
|
dataManagementPlanBlueprintListingModel.fromDataModel(dmpProfile);
|
||||||
|
return dataManagementPlanBlueprintListingModel;
|
||||||
|
}
|
||||||
|
|
||||||
public List<DataManagementPlanProfileListingModel> getWithCriteria(DataManagementPlanProfileCriteriaRequest dataManagementPlanProfileCriteriaRequest) throws IllegalAccessException, InstantiationException {
|
public List<DataManagementPlanProfileListingModel> getWithCriteria(DataManagementPlanProfileCriteriaRequest dataManagementPlanProfileCriteriaRequest) throws IllegalAccessException, InstantiationException {
|
||||||
QueryableList<DMPProfile> items = databaseRepository.getDmpProfileDao().getWithCriteria(dataManagementPlanProfileCriteriaRequest.getCriteria());
|
QueryableList<DMPProfile> items = databaseRepository.getDmpProfileDao().getWithCriteria(dataManagementPlanProfileCriteriaRequest.getCriteria());
|
||||||
List<DataManagementPlanProfileListingModel> datamanagementPlans = items.select(item -> new DataManagementPlanProfileListingModel().fromDataModel(item));
|
List<DataManagementPlanProfileListingModel> datamanagementPlans = items.select(item -> new DataManagementPlanProfileListingModel().fromDataModel(item));
|
||||||
|
@ -96,6 +119,11 @@ public class DataManagementProfileManager {
|
||||||
apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile);
|
apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void createOrUpdateBlueprint(DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel, Principal principal) throws Exception {
|
||||||
|
DMPProfile dmpProfile = dataManagementPlanBlueprintListingModel.toDataModel();
|
||||||
|
apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile);
|
||||||
|
}
|
||||||
|
|
||||||
public ResponseEntity<byte[]> getDocument(DataManagementPlanProfileListingModel dmpProfile, String label) throws IllegalAccessException, IOException, InstantiationException {
|
public ResponseEntity<byte[]> getDocument(DataManagementPlanProfileListingModel dmpProfile, String label) throws IllegalAccessException, IOException, InstantiationException {
|
||||||
FileEnvelope envelope = getXmlDocument(dmpProfile, label);
|
FileEnvelope envelope = getXmlDocument(dmpProfile, label);
|
||||||
InputStream resource = new FileInputStream(envelope.getFile());
|
InputStream resource = new FileInputStream(envelope.getFile());
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition;
|
||||||
|
|
||||||
|
import eu.eudat.logic.utilities.builders.XmlBuilder;
|
||||||
|
import eu.eudat.logic.utilities.interfaces.XmlSerializable;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DataManagementPlanBlueprint implements XmlSerializable<DataManagementPlanBlueprint> {
|
||||||
|
|
||||||
|
private List<Section> sections;
|
||||||
|
|
||||||
|
public List<Section> getSections() {
|
||||||
|
return sections;
|
||||||
|
}
|
||||||
|
public void setSections(List<Section> sections) {
|
||||||
|
this.sections = sections;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element toXml(Document doc) {
|
||||||
|
Element root = doc.createElement("root");
|
||||||
|
Element sections = doc.createElement("sections");
|
||||||
|
for (Section section : this.sections) {
|
||||||
|
sections.appendChild(section.toXml(doc));
|
||||||
|
}
|
||||||
|
root.appendChild(sections);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataManagementPlanBlueprint fromXml(Element item) {
|
||||||
|
this.sections = new LinkedList<>();
|
||||||
|
Element sections = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "sections");
|
||||||
|
if (sections != null) {
|
||||||
|
NodeList sectionElements = sections.getChildNodes();
|
||||||
|
for (int temp = 0; temp < sectionElements.getLength(); temp++) {
|
||||||
|
Node sectionElement = sectionElements.item(temp);
|
||||||
|
if (sectionElement.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
|
this.sections.add(new Section().fromXml((Element) sectionElement));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition;
|
||||||
|
|
||||||
|
import eu.eudat.logic.utilities.interfaces.XmlSerializable;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class DescriptionTemplate implements XmlSerializable<DescriptionTemplate> {
|
||||||
|
|
||||||
|
private UUID id;
|
||||||
|
private UUID descriptionTemplateId;
|
||||||
|
private String label;
|
||||||
|
private Integer minMultiplicity;
|
||||||
|
private Integer maxMultiplicity;
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getDescriptionTemplateId() {
|
||||||
|
return descriptionTemplateId;
|
||||||
|
}
|
||||||
|
public void setDescriptionTemplateId(UUID descriptionTemplateId) {
|
||||||
|
this.descriptionTemplateId = descriptionTemplateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getMinMultiplicity() {
|
||||||
|
return minMultiplicity;
|
||||||
|
}
|
||||||
|
public void setMinMultiplicity(Integer minMultiplicity) {
|
||||||
|
this.minMultiplicity = minMultiplicity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getMaxMultiplicity() {
|
||||||
|
return maxMultiplicity;
|
||||||
|
}
|
||||||
|
public void setMaxMultiplicity(Integer maxMultiplicity) {
|
||||||
|
this.maxMultiplicity = maxMultiplicity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element toXml(Document doc) {
|
||||||
|
Element rootElement = doc.createElement("descriptionTemplate");
|
||||||
|
rootElement.setAttribute("id", this.getId().toString());
|
||||||
|
rootElement.setAttribute("descriptionTemplateId", this.getDescriptionTemplateId().toString());
|
||||||
|
rootElement.setAttribute("label", this.label);
|
||||||
|
rootElement.setAttribute("minMultiplicity", String.valueOf(this.minMultiplicity));
|
||||||
|
rootElement.setAttribute("maxMultiplicity", String.valueOf(this.maxMultiplicity));
|
||||||
|
return rootElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DescriptionTemplate fromXml(Element item) {
|
||||||
|
this.id = UUID.fromString(item.getAttribute("id"));
|
||||||
|
this.descriptionTemplateId = UUID.fromString(item.getAttribute("descriptionTemplateId"));
|
||||||
|
this.label = item.getAttribute("label");
|
||||||
|
this.minMultiplicity = Integer.valueOf(item.getAttribute("minMultiplicity"));
|
||||||
|
this.maxMultiplicity = Integer.valueOf(item.getAttribute("maxMultiplicity"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition;
|
||||||
|
|
||||||
|
import eu.eudat.logic.utilities.interfaces.XmlSerializable;
|
||||||
|
import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.ExtraFieldType;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class ExtraField implements XmlSerializable<ExtraField> {
|
||||||
|
|
||||||
|
private UUID id;
|
||||||
|
private String label;
|
||||||
|
private String description;
|
||||||
|
private String placeholder;
|
||||||
|
private ExtraFieldType type;
|
||||||
|
private Boolean required;
|
||||||
|
private Integer ordinal;
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlaceholder() {
|
||||||
|
return placeholder;
|
||||||
|
}
|
||||||
|
public void setPlaceholder(String placeholder) {
|
||||||
|
this.placeholder = placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtraFieldType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
public void setType(ExtraFieldType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getRequired() {
|
||||||
|
return required;
|
||||||
|
}
|
||||||
|
public void setRequired(Boolean required) {
|
||||||
|
this.required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOrdinal() {
|
||||||
|
return ordinal;
|
||||||
|
}
|
||||||
|
public void setOrdinal(Integer ordinal) {
|
||||||
|
this.ordinal = ordinal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element toXml(Document doc) {
|
||||||
|
Element rootElement = doc.createElement("extraField");
|
||||||
|
rootElement.setAttribute("id", this.getId().toString());
|
||||||
|
rootElement.setAttribute("label", this.label);
|
||||||
|
rootElement.setAttribute("description", this.description);
|
||||||
|
rootElement.setAttribute("placeholder", this.placeholder);
|
||||||
|
rootElement.setAttribute("type", String.valueOf(this.type.getValue()));
|
||||||
|
rootElement.setAttribute("required", String.valueOf(this.required));
|
||||||
|
rootElement.setAttribute("ordinal", String.valueOf(this.ordinal));
|
||||||
|
return rootElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExtraField fromXml(Element item) {
|
||||||
|
this.id = UUID.fromString(item.getAttribute("id"));
|
||||||
|
this.label = item.getAttribute("label");
|
||||||
|
this.description = item.getAttribute("description");
|
||||||
|
this.placeholder = item.getAttribute("placeholder");
|
||||||
|
this.type = ExtraFieldType.fromInteger(Integer.parseInt(item.getAttribute("type")));
|
||||||
|
this.required = Boolean.parseBoolean(item.getAttribute("required"));
|
||||||
|
this.ordinal = Integer.valueOf(item.getAttribute("ordinal"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition;
|
||||||
|
|
||||||
|
import eu.eudat.logic.utilities.builders.XmlBuilder;
|
||||||
|
import eu.eudat.logic.utilities.interfaces.XmlSerializable;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class Section implements XmlSerializable<Section> {
|
||||||
|
|
||||||
|
private UUID id;
|
||||||
|
private String label;
|
||||||
|
private String description;
|
||||||
|
private Integer ordinal;
|
||||||
|
private List<SystemField> systemFields;
|
||||||
|
private List<DescriptionTemplate> descriptionTemplates;
|
||||||
|
private List<ExtraField> extraFields;
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOrdinal() {
|
||||||
|
return ordinal;
|
||||||
|
}
|
||||||
|
public void setOrdinal(Integer ordinal) {
|
||||||
|
this.ordinal = ordinal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SystemField> getSystemFields() {
|
||||||
|
return systemFields;
|
||||||
|
}
|
||||||
|
public void setSystemFields(List<SystemField> systemFields) {
|
||||||
|
this.systemFields = systemFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DescriptionTemplate> getDescriptionTemplates() {
|
||||||
|
return descriptionTemplates;
|
||||||
|
}
|
||||||
|
public void setDescriptionTemplates(List<DescriptionTemplate> descriptionTemplates) {
|
||||||
|
this.descriptionTemplates = descriptionTemplates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ExtraField> getExtraFields() {
|
||||||
|
return extraFields;
|
||||||
|
}
|
||||||
|
public void setExtraFields(List<ExtraField> extraFields) {
|
||||||
|
this.extraFields = extraFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element toXml(Document doc) {
|
||||||
|
Element rootElement = doc.createElement("section");
|
||||||
|
rootElement.setAttribute("id", this.getId().toString());
|
||||||
|
rootElement.setAttribute("label", this.label);
|
||||||
|
rootElement.setAttribute("description", this.description);
|
||||||
|
rootElement.setAttribute("ordinal", String.valueOf(this.ordinal));
|
||||||
|
Element systemFields = doc.createElement("systemFields");
|
||||||
|
for (SystemField systemField : this.systemFields) {
|
||||||
|
systemFields.appendChild(systemField.toXml(doc));
|
||||||
|
}
|
||||||
|
rootElement.appendChild(systemFields);
|
||||||
|
Element descriptionTemplates = doc.createElement("descriptionTemplates");
|
||||||
|
for (DescriptionTemplate descriptionTemplate : this.descriptionTemplates) {
|
||||||
|
descriptionTemplates.appendChild(descriptionTemplate.toXml(doc));
|
||||||
|
}
|
||||||
|
rootElement.appendChild(descriptionTemplates);
|
||||||
|
Element extraFields = doc.createElement("extraFields");
|
||||||
|
for (ExtraField extraField : this.extraFields) {
|
||||||
|
extraFields.appendChild(extraField.toXml(doc));
|
||||||
|
}
|
||||||
|
rootElement.appendChild(extraFields);
|
||||||
|
|
||||||
|
return rootElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Section fromXml(Element item) {
|
||||||
|
this.id = UUID.fromString(item.getAttribute("id"));
|
||||||
|
this.label = item.getAttribute("label");
|
||||||
|
this.description = item.getAttribute("description");
|
||||||
|
this.ordinal = Integer.valueOf(item.getAttribute("ordinal"));
|
||||||
|
this.systemFields = new LinkedList<>();
|
||||||
|
Element systemFields = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "systemFields");
|
||||||
|
if (systemFields != null) {
|
||||||
|
NodeList systemFieldElements = systemFields.getChildNodes();
|
||||||
|
for (int temp = 0; temp < systemFieldElements.getLength(); temp++) {
|
||||||
|
Node systemFieldElement = systemFieldElements.item(temp);
|
||||||
|
if (systemFieldElement.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
|
this.systemFields.add(new SystemField().fromXml((Element) systemFieldElement));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.descriptionTemplates = new LinkedList<>();
|
||||||
|
Element descriptionTemplates = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "descriptionTemplates");
|
||||||
|
if (descriptionTemplates != null) {
|
||||||
|
NodeList descriptionTemplateElements = descriptionTemplates.getChildNodes();
|
||||||
|
for (int temp = 0; temp < descriptionTemplateElements.getLength(); temp++) {
|
||||||
|
Node descriptionTemplateElement = descriptionTemplateElements.item(temp);
|
||||||
|
if (descriptionTemplateElement.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
|
this.descriptionTemplates.add(new DescriptionTemplate().fromXml((Element) descriptionTemplateElement));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.extraFields = new LinkedList<>();
|
||||||
|
Element extraFields = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "extraFields");
|
||||||
|
if (extraFields != null) {
|
||||||
|
NodeList extraFieldElements = extraFields.getChildNodes();
|
||||||
|
for (int temp = 0; temp < extraFieldElements.getLength(); temp++) {
|
||||||
|
Node extraFieldElement = extraFieldElements.item(temp);
|
||||||
|
if (extraFieldElement.getNodeType() == Node.ELEMENT_NODE) {
|
||||||
|
this.extraFields.add(new ExtraField().fromXml((Element) extraFieldElement));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition;
|
||||||
|
|
||||||
|
import eu.eudat.logic.utilities.interfaces.XmlSerializable;
|
||||||
|
import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.SystemFieldType;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class SystemField implements XmlSerializable<SystemField> {
|
||||||
|
|
||||||
|
private UUID id;
|
||||||
|
private SystemFieldType type;
|
||||||
|
private String label;
|
||||||
|
private String placeholder;
|
||||||
|
private String description;
|
||||||
|
private boolean required;
|
||||||
|
private Integer ordinal;
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SystemFieldType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
public void setType(SystemFieldType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlaceholder() {
|
||||||
|
return placeholder;
|
||||||
|
}
|
||||||
|
public void setPlaceholder(String placeholder) {
|
||||||
|
this.placeholder = placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRequired() {
|
||||||
|
return required;
|
||||||
|
}
|
||||||
|
public void setRequired(boolean required) {
|
||||||
|
this.required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getOrdinal() {
|
||||||
|
return ordinal;
|
||||||
|
}
|
||||||
|
public void setOrdinal(Integer ordinal) {
|
||||||
|
this.ordinal = ordinal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element toXml(Document doc) {
|
||||||
|
Element rootElement = doc.createElement("systemField");
|
||||||
|
rootElement.setAttribute("id", this.getId().toString());
|
||||||
|
rootElement.setAttribute("type", String.valueOf(this.type.getType()));
|
||||||
|
rootElement.setAttribute("label", this.label);
|
||||||
|
rootElement.setAttribute("placeholder", this.placeholder);
|
||||||
|
rootElement.setAttribute("description", this.description);
|
||||||
|
rootElement.setAttribute("required", String.valueOf(this.required));
|
||||||
|
rootElement.setAttribute("ordinal", String.valueOf(this.ordinal));
|
||||||
|
return rootElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SystemField fromXml(Element item) {
|
||||||
|
this.id = UUID.fromString(item.getAttribute("id"));
|
||||||
|
this.type = SystemFieldType.fromInteger(Integer.parseInt(item.getAttribute("type")));
|
||||||
|
this.label = item.getAttribute("label");
|
||||||
|
this.placeholder = item.getAttribute("placeholder");
|
||||||
|
this.description = item.getAttribute("description");
|
||||||
|
this.required = Boolean.parseBoolean(item.getAttribute("required"));
|
||||||
|
this.ordinal = Integer.valueOf(item.getAttribute("ordinal"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types;
|
||||||
|
|
||||||
|
public enum ExtraFieldType {
|
||||||
|
TEXT(0), RICH_TEXT(1), DATE(2), NUMBER(3);
|
||||||
|
|
||||||
|
private Integer value;
|
||||||
|
|
||||||
|
private ExtraFieldType(Integer value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ExtraFieldType fromInteger(Integer value) {
|
||||||
|
switch (value) {
|
||||||
|
case 0:
|
||||||
|
return TEXT;
|
||||||
|
case 1:
|
||||||
|
return RICH_TEXT;
|
||||||
|
case 2:
|
||||||
|
return DATE;
|
||||||
|
case 3:
|
||||||
|
return NUMBER;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unsupported ExtraFieldType Type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types;
|
||||||
|
|
||||||
|
public enum SystemFieldType {
|
||||||
|
|
||||||
|
TEXT(0),
|
||||||
|
HTML_TEXT(1),
|
||||||
|
RESEARCHERS(2),
|
||||||
|
ORGANIZATIONS(3),
|
||||||
|
LANGUAGE(4),
|
||||||
|
CONTACT(5),
|
||||||
|
FUNDER(6),
|
||||||
|
GRANT(7),
|
||||||
|
PROJECT(8),
|
||||||
|
LICENSE(9),
|
||||||
|
ACCESS_RIGHTS(10),
|
||||||
|
DESCRIPTION_TEMPLATES(11);
|
||||||
|
|
||||||
|
private int type;
|
||||||
|
|
||||||
|
SystemFieldType(int type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SystemFieldType fromInteger(int type) {
|
||||||
|
switch (type) {
|
||||||
|
case 0:
|
||||||
|
return TEXT;
|
||||||
|
case 1:
|
||||||
|
return HTML_TEXT;
|
||||||
|
case 2:
|
||||||
|
return RESEARCHERS;
|
||||||
|
case 3:
|
||||||
|
return ORGANIZATIONS;
|
||||||
|
case 4:
|
||||||
|
return LANGUAGE;
|
||||||
|
case 5:
|
||||||
|
return CONTACT;
|
||||||
|
case 6:
|
||||||
|
return FUNDER;
|
||||||
|
case 7:
|
||||||
|
return GRANT;
|
||||||
|
case 8:
|
||||||
|
return PROJECT;
|
||||||
|
case 9:
|
||||||
|
return LICENSE;
|
||||||
|
case 10:
|
||||||
|
return ACCESS_RIGHTS;
|
||||||
|
case 11:
|
||||||
|
return DESCRIPTION_TEMPLATES;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unsupported System Field Type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
package eu.eudat.models.data.listingmodels;
|
||||||
|
|
||||||
|
import eu.eudat.data.entities.DMPProfile;
|
||||||
|
import eu.eudat.logic.utilities.builders.XmlBuilder;
|
||||||
|
import eu.eudat.models.DataModel;
|
||||||
|
import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanBlueprint;
|
||||||
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class DataManagementPlanBlueprintListingModel implements DataModel<DMPProfile, DataManagementPlanBlueprintListingModel> {
|
||||||
|
|
||||||
|
private UUID id;
|
||||||
|
private String label;
|
||||||
|
private DataManagementPlanBlueprint definition;
|
||||||
|
private int status;
|
||||||
|
private Date created = null;
|
||||||
|
private Date modified = new Date();
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataManagementPlanBlueprint getDefinition() {
|
||||||
|
return definition;
|
||||||
|
}
|
||||||
|
public void setDefinition(DataManagementPlanBlueprint definition) {
|
||||||
|
this.definition = definition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
public void setStatus(int status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
public void setCreated(Date created) {
|
||||||
|
this.created = created;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getModified() {
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
public void setModified(Date modified) {
|
||||||
|
this.modified = modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataManagementPlanBlueprintListingModel fromDataModel(DMPProfile entity) {
|
||||||
|
this.id = entity.getId();
|
||||||
|
this.created = entity.getCreated();
|
||||||
|
this.definition = new DataManagementPlanBlueprint().fromXml(XmlBuilder.fromXml(entity.getDefinition()).getDocumentElement());
|
||||||
|
this.modified = entity.getModified();
|
||||||
|
this.label = entity.getLabel();
|
||||||
|
this.status = entity.getStatus();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DMPProfile toDataModel() throws Exception {
|
||||||
|
Document document = XmlBuilder.getDocument();
|
||||||
|
document.appendChild(this.definition.toXml(document));
|
||||||
|
DMPProfile dmpProfile = new DMPProfile();
|
||||||
|
dmpProfile.setCreated(this.created == null ? new Date() : this.created);
|
||||||
|
dmpProfile.setDefinition(XmlBuilder.generateXml(document));
|
||||||
|
dmpProfile.setId(this.id);
|
||||||
|
dmpProfile.setLabel(this.label);
|
||||||
|
dmpProfile.setStatus(this.status);
|
||||||
|
dmpProfile.setModified(this.modified == null ? new Date() : this.modified);
|
||||||
|
return dmpProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHint() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { DmpBlueprintDefinition } from "./dmp-blueprint";
|
||||||
|
|
||||||
|
export interface DmpBlueprintListing {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
definition: DmpBlueprintDefinition;
|
||||||
|
status: number;
|
||||||
|
created: Date;
|
||||||
|
modified: Date;
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
export interface DmpBlueprint {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
definition: DmpBlueprintDefinition;
|
||||||
|
status: number;
|
||||||
|
created: Date;
|
||||||
|
modified: Date;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DmpBlueprintDefinition {
|
||||||
|
sections: SectionDmpBlueprint[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SectionDmpBlueprint {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
description: string;
|
||||||
|
ordinal: number;
|
||||||
|
systemFields: SystemFieldInSection[];
|
||||||
|
descriptionTemplates?: DescriptionTemplatesInSection[];
|
||||||
|
extraFields?: ExtraFieldInSection[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SystemFieldInSection {
|
||||||
|
id: string;
|
||||||
|
type: SystemFieldType;
|
||||||
|
label: string;
|
||||||
|
placeholder: string;
|
||||||
|
description: string;
|
||||||
|
required: boolean;
|
||||||
|
ordinal: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SystemFieldType {
|
||||||
|
TEXT = 0,
|
||||||
|
HTML_TEXT = 1,
|
||||||
|
RESEARCHERS= 2,
|
||||||
|
ORGANIZATIONS = 3,
|
||||||
|
LANGUAGE = 4,
|
||||||
|
CONTACT = 5,
|
||||||
|
FUNDER = 6,
|
||||||
|
GRANT = 7,
|
||||||
|
PROJECT = 8,
|
||||||
|
LICENSE = 9,
|
||||||
|
ACCESS_RIGHTS = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DescriptionTemplatesInSection {
|
||||||
|
id: string;
|
||||||
|
descriptionTemplateId: string;
|
||||||
|
label: string;
|
||||||
|
minMultiplicity: number;
|
||||||
|
maxMultiplicity: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExtraFieldInSection {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
description: string;
|
||||||
|
placeholder: string;
|
||||||
|
type: ExtraFieldType;
|
||||||
|
required: boolean;
|
||||||
|
ordinal: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ExtraFieldType {
|
||||||
|
TEXT = 0,
|
||||||
|
RICH_TEXT = 1,
|
||||||
|
DATE = 2,
|
||||||
|
NUMBER = 3
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { BaseCriteria } from "../base-criteria";
|
||||||
|
|
||||||
|
export class DmpBlueprintCriteria extends BaseCriteria {
|
||||||
|
|
||||||
|
}
|
|
@ -14,6 +14,9 @@ import { BaseHttpParams } from '../../../../common/http/base-http-params';
|
||||||
import { InterceptorType } from '../../../../common/http/interceptors/interceptor-type';
|
import { InterceptorType } from '../../../../common/http/interceptors/interceptor-type';
|
||||||
import { DmpProfileExternalAutocompleteCriteria } from '../../query/dmp/dmp-profile-external-autocomplete-criteria';
|
import { DmpProfileExternalAutocompleteCriteria } from '../../query/dmp/dmp-profile-external-autocomplete-criteria';
|
||||||
import { ConfigurationService } from '../configuration/configuration.service';
|
import { ConfigurationService } from '../configuration/configuration.service';
|
||||||
|
import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria';
|
||||||
|
import { DmpBlueprintListing } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing';
|
||||||
|
import { DmpBlueprint } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DmpProfileService {
|
export class DmpProfileService {
|
||||||
|
@ -29,14 +32,26 @@ export class DmpProfileService {
|
||||||
return this.http.post<DataTableData<DmpProfileListing>>(this.actionUrl + 'getPaged', dataTableRequest, { headers: this.headers });
|
return this.http.post<DataTableData<DmpProfileListing>>(this.actionUrl + 'getPaged', dataTableRequest, { headers: this.headers });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPagedBlueprint(dataTableRequest: DataTableRequest<DmpBlueprintCriteria>): Observable<DataTableData<DmpBlueprintListing>> {
|
||||||
|
return this.http.post<DataTableData<DmpBlueprintListing>>(this.actionUrl + 'getPagedBlueprint', dataTableRequest, { headers: this.headers });
|
||||||
|
}
|
||||||
|
|
||||||
getSingle(id: String): Observable<DmpProfile> {
|
getSingle(id: String): Observable<DmpProfile> {
|
||||||
return this.http.get<DmpProfile>(this.actionUrl + 'getSingle/' + id, { headers: this.headers });
|
return this.http.get<DmpProfile>(this.actionUrl + 'getSingle/' + id, { headers: this.headers });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSingleBlueprint(id: String): Observable<DmpBlueprintListing> {
|
||||||
|
return this.http.get<DmpBlueprintListing>(this.actionUrl + 'getSingleBlueprint/' + id, { headers: this.headers });
|
||||||
|
}
|
||||||
|
|
||||||
createDmp(dataManagementPlanModel: DmpProfile): Observable<DmpProfile> {
|
createDmp(dataManagementPlanModel: DmpProfile): Observable<DmpProfile> {
|
||||||
return this.http.post<DmpProfile>(this.actionUrl, dataManagementPlanModel, { headers: this.headers });
|
return this.http.post<DmpProfile>(this.actionUrl, dataManagementPlanModel, { headers: this.headers });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createBlueprint(dmpBlueprint: DmpBlueprint): Observable<DmpProfile> {
|
||||||
|
return this.http.post<DmpProfile>(this.actionUrl + 'blueprint', dmpBlueprint, { headers: this.headers });
|
||||||
|
}
|
||||||
|
|
||||||
public downloadXML(id: string): Observable<HttpResponse<Blob>> {
|
public downloadXML(id: string): Observable<HttpResponse<Blob>> {
|
||||||
let headerXml: HttpHeaders = this.headers.set('Content-Type', 'application/xml')
|
let headerXml: HttpHeaders = this.headers.set('Content-Type', 'application/xml')
|
||||||
return this.httpClient.get(this.actionUrl + 'getXml/' + id, { responseType: 'blob', observe: 'response', headers: headerXml });
|
return this.httpClient.get(this.actionUrl + 'getXml/' + id, { responseType: 'blob', observe: 'response', headers: headerXml });
|
||||||
|
|
|
@ -7,8 +7,8 @@ import { AdminAuthGuard } from '@app/core/admin-auth-guard.service';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: '', component: DmpProfileListingComponent, canActivate: [AdminAuthGuard] },
|
{ path: '', component: DmpProfileListingComponent, canActivate: [AdminAuthGuard] },
|
||||||
{ path: 'new', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-PROFILE-NEW' } },
|
{ path: 'new', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-NEW' } },
|
||||||
{ path: ':id', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-PROFILE-EDIT' } },
|
{ path: ':id', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-EDIT' } },
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
import { FormBuilder, FormGroup } from "@angular/forms";
|
||||||
|
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, ExtraFieldInSection, ExtraFieldType, SectionDmpBlueprint, SystemFieldInSection, SystemFieldType } from "@app/core/model/dmp/dmp-blueprint/dmp-blueprint";
|
||||||
|
|
||||||
|
export class DmpBlueprintEditor {
|
||||||
|
public id: string;
|
||||||
|
public label: string;
|
||||||
|
public definition: DmpBlueprintDefinitionEditor = new DmpBlueprintDefinitionEditor();
|
||||||
|
public status: number;
|
||||||
|
public created: Date;
|
||||||
|
public modified: Date;
|
||||||
|
|
||||||
|
fromModel(item: DmpBlueprint): DmpBlueprintEditor {
|
||||||
|
this.id = item.id;
|
||||||
|
this.label = item.label;
|
||||||
|
this.definition = new DmpBlueprintDefinitionEditor().fromModel(item.definition);
|
||||||
|
this.status = item.status;
|
||||||
|
this.created = item.created;
|
||||||
|
this.modified = item.modified;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildForm(): FormGroup {
|
||||||
|
const formGroup = new FormBuilder().group({
|
||||||
|
id: [this.id],
|
||||||
|
label: [this.label],
|
||||||
|
status: [this.status],
|
||||||
|
created: [this.created],
|
||||||
|
modified: [this.modified]
|
||||||
|
});
|
||||||
|
formGroup.addControl('definition', this.definition.buildForm());
|
||||||
|
return formGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DmpBlueprintDefinitionEditor {
|
||||||
|
|
||||||
|
public sections: SectionDmpBlueprintEditor[] = new Array<SectionDmpBlueprintEditor>();
|
||||||
|
|
||||||
|
fromModel(item: DmpBlueprintDefinition): DmpBlueprintDefinitionEditor {
|
||||||
|
if (item.sections) { item.sections.map(x => this.sections.push(new SectionDmpBlueprintEditor().fromModel(x))); }
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildForm(): FormGroup {
|
||||||
|
const formBuilder = new FormBuilder();
|
||||||
|
const formGroup = formBuilder.group({});
|
||||||
|
const sectionsFormArray = new Array<FormGroup>();
|
||||||
|
this.sections.forEach(item => {
|
||||||
|
const form: FormGroup = item.buildForm();
|
||||||
|
sectionsFormArray.push(form);
|
||||||
|
});
|
||||||
|
formGroup.addControl('sections', formBuilder.array(sectionsFormArray));
|
||||||
|
return formGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SectionDmpBlueprintEditor {
|
||||||
|
public id: string;
|
||||||
|
public label: string;
|
||||||
|
public description: string;
|
||||||
|
public ordinal: number;
|
||||||
|
public systemFields: SystemFieldInSectionEditor[] = new Array<SystemFieldInSectionEditor>();
|
||||||
|
public descriptionTemplates: DescriptionTemplatesInSectionEditor[] = new Array<DescriptionTemplatesInSectionEditor>();
|
||||||
|
|
||||||
|
fromModel(item: SectionDmpBlueprint): SectionDmpBlueprintEditor {
|
||||||
|
this.id = item.id;
|
||||||
|
this.label = item.label;
|
||||||
|
this.description = item.description;
|
||||||
|
this.ordinal = item.ordinal;
|
||||||
|
if (item.systemFields) { item.systemFields.map(x => this.systemFields.push(new SystemFieldInSectionEditor().fromModel(x))); }
|
||||||
|
if (item.descriptionTemplates) { item.descriptionTemplates.map(x => this.descriptionTemplates.push(new DescriptionTemplatesInSectionEditor().fromModel(x))); }
|
||||||
|
debugger;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildForm(): FormGroup {
|
||||||
|
const formGroup = new FormBuilder().group({
|
||||||
|
id: [this.id],
|
||||||
|
label: [this.label],
|
||||||
|
description: [this.description],
|
||||||
|
ordinal: [this.ordinal]
|
||||||
|
});
|
||||||
|
const formBuilder = new FormBuilder();
|
||||||
|
const systemFieldsFormArray = new Array<FormGroup>();
|
||||||
|
this.systemFields.forEach(item => {
|
||||||
|
const form: FormGroup = item.buildForm();
|
||||||
|
systemFieldsFormArray.push(form);
|
||||||
|
});
|
||||||
|
formGroup.addControl('systemFields', formBuilder.array(systemFieldsFormArray));
|
||||||
|
const descriptionTemplatesFormArray = new Array<FormGroup>();
|
||||||
|
this.descriptionTemplates.forEach(item => {
|
||||||
|
const form: FormGroup = item.buildForm();
|
||||||
|
descriptionTemplatesFormArray.push(form);
|
||||||
|
});
|
||||||
|
formGroup.addControl('descriptionTemplates', formBuilder.array(descriptionTemplatesFormArray));
|
||||||
|
return formGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SystemFieldInSectionEditor {
|
||||||
|
public id: string;
|
||||||
|
public type: SystemFieldType;
|
||||||
|
public placeholder: string;
|
||||||
|
public description: string;
|
||||||
|
public required: boolean;
|
||||||
|
public ordinal: number;
|
||||||
|
|
||||||
|
fromModel(item: SystemFieldInSection): SystemFieldInSectionEditor {
|
||||||
|
this.id = item.id;
|
||||||
|
this.type = item.type;
|
||||||
|
this.placeholder = item.placeholder;
|
||||||
|
this.description = item.description;
|
||||||
|
this.required = item.required;
|
||||||
|
this.ordinal = item.ordinal;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildForm(): FormGroup {
|
||||||
|
const formGroup = new FormBuilder().group({
|
||||||
|
id: [this.id],
|
||||||
|
type: [this.type],
|
||||||
|
placeholder: [this.placeholder],
|
||||||
|
description: [this.description],
|
||||||
|
required: [this.required],
|
||||||
|
ordinal: [this.ordinal]
|
||||||
|
});
|
||||||
|
return formGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DescriptionTemplatesInSectionEditor {
|
||||||
|
public id: string;
|
||||||
|
public descriptionTemplateId: string;
|
||||||
|
public label: string;
|
||||||
|
public minMultiplicity: number;
|
||||||
|
public maxMultiplicity: number;
|
||||||
|
|
||||||
|
fromModel(item: DescriptionTemplatesInSection): DescriptionTemplatesInSectionEditor {
|
||||||
|
this.id = item.id;
|
||||||
|
this.descriptionTemplateId = item.descriptionTemplateId;
|
||||||
|
this.label = item.label;
|
||||||
|
this.minMultiplicity = item.minMultiplicity;
|
||||||
|
this.maxMultiplicity = item.maxMultiplicity;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildForm(): FormGroup {
|
||||||
|
const formGroup = new FormBuilder().group({
|
||||||
|
id: [this.id],
|
||||||
|
descriptionTemplateId: [this.descriptionTemplateId],
|
||||||
|
label: [this.label],
|
||||||
|
minMultiplicity: [this.minMultiplicity],
|
||||||
|
maxMultiplicity: [this.maxMultiplicity]
|
||||||
|
});
|
||||||
|
return formGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ExtraFieldsInSectionEditor {
|
||||||
|
public id: string;
|
||||||
|
public label: string;
|
||||||
|
public description: string;
|
||||||
|
public placeholder: string;
|
||||||
|
public type: ExtraFieldType;
|
||||||
|
public required: boolean;
|
||||||
|
public ordinal: number;
|
||||||
|
|
||||||
|
fromModel(item: ExtraFieldInSection): ExtraFieldsInSectionEditor {
|
||||||
|
this.id = item.id;
|
||||||
|
this.label = item.label;
|
||||||
|
this.description = item.description;
|
||||||
|
this.placeholder = item.placeholder;
|
||||||
|
this.type = item.type;
|
||||||
|
this.required = item.required;
|
||||||
|
this.ordinal = item.ordinal;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildForm(): FormGroup {
|
||||||
|
const formGroup = new FormBuilder().group({
|
||||||
|
id: [this.id],
|
||||||
|
label: [this.label],
|
||||||
|
description: [this.description],
|
||||||
|
placeholder: [this.placeholder],
|
||||||
|
type: [this.type],
|
||||||
|
required: [this.required],
|
||||||
|
ordinal: [this.ordinal]
|
||||||
|
});
|
||||||
|
return formGroup;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,10 +18,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="formGroup.get('status').value!=1" class="col-auto">
|
<div *ngIf="formGroup.get('status').value!=1" class="col-auto">
|
||||||
<button mat-button class="finalize-btn" (click)="finalize()"
|
<button mat-button class="finalize-btn" (click)="finalize()"
|
||||||
[disabled]="!formGroup.valid" type="button">{{'DMP-PROFILE-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
|
[disabled]="true" type="button">{{'DMP-PROFILE-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form *ngIf="formGroup" (ngSubmit)="formSubmit()" [formGroup]="formGroup">
|
<form *ngIf="dmpBlueprintsFormGroup" (ngSubmit)="onSubmitTest()" [formGroup]="dmpBlueprintsFormGroup">
|
||||||
<mat-card style="padding: 2em;">
|
<mat-card style="padding: 2em;">
|
||||||
<!-- <mat-card-header>
|
<!-- <mat-card-header>
|
||||||
<mat-card-title *ngIf="isNew">
|
<mat-card-title *ngIf="isNew">
|
||||||
|
@ -36,14 +36,224 @@
|
||||||
<mat-form-field class="col-lg-6" appearance="legacy">
|
<mat-form-field class="col-lg-6" appearance="legacy">
|
||||||
<input matInput placeholder="{{'DMP-PROFILE-EDITOR.FIELDS.LABEL' | translate}}" type="text" name="label" formControlName="label"
|
<input matInput placeholder="{{'DMP-PROFILE-EDITOR.FIELDS.LABEL' | translate}}" type="text" name="label" formControlName="label"
|
||||||
required>
|
required>
|
||||||
<mat-error *ngIf="formGroup.get('label').hasError('backendError')">
|
<mat-error *ngIf="dmpBlueprintsFormGroup.get('label').hasError('required')">
|
||||||
{{formGroup.get('label').getError('backendError').message}}</mat-error>
|
|
||||||
<mat-error *ngIf="formGroup.get('label').hasError('required')">
|
|
||||||
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<h4 class="col-12">{{'DMP-PROFILE-EDITOR.FIELDS.TITLE' | translate}}</h4>
|
<h4 class="col-12">Sections</h4>
|
||||||
|
|
||||||
|
<ng-container formArrayName="sections">
|
||||||
|
<div *ngFor="let section of sectionsArray().controls; let sectionIndex=index;" class="section-input" style="width: 100%;">
|
||||||
|
<ng-container [formGroupName]="sectionIndex">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
<mat-card class="col-11" style="width: 100%;">
|
||||||
|
<mat-card-header>
|
||||||
|
<mat-card-title>Section {{sectionIndex + 1}}</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Section name</mat-label>
|
||||||
|
<input matInput type="text" name="label" formControlName="label" required>
|
||||||
|
<mat-error *ngIf="section.get('label').hasError('required')">
|
||||||
|
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Section description</mat-label>
|
||||||
|
<input matInput type="text" name="description" formControlName="description" required>
|
||||||
|
<mat-error *ngIf="section.get('description').hasError('required')">
|
||||||
|
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>System fields</mat-label>
|
||||||
|
<mat-select multiple>
|
||||||
|
<mat-option *ngFor="let f of fieldList" [disabled]="systemFieldDisabled(f.type, sectionIndex)" [value]="f.type" (click)="selectedFieldType(f.label, f.type, sectionIndex)">{{f.label}}</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<mat-error *ngIf="systemFieldsArray(sectionIndex).hasError('required')">
|
||||||
|
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ng-container formArrayName="systemFields">
|
||||||
|
<div *ngFor="let systemField of systemFieldsArray(sectionIndex).controls; let systemFieldIndex=index;">
|
||||||
|
<ng-container [formGroupName]="systemFieldIndex">
|
||||||
|
<div class="col-12" *ngIf="systemFieldsArray(sectionIndex).length > 0">
|
||||||
|
<!-- <div *ngFor="let systemField of systemFieldsArray(sectionIndex).value; let i=index;" class="section-input" style="width: 100%;"> -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-3">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>System Field</mat-label>
|
||||||
|
<input matInput disabled value="{{transfromEnumToString(systemField.get('type').value)}}" type="text" name="name">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Label</mat-label>
|
||||||
|
<input matInput type="text" name="label" formControlName="label">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Placeholder</mat-label>
|
||||||
|
<input matInput type="text" name="placeholder" formControlName="placeholder">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Description</mat-label>
|
||||||
|
<input matInput type="text" name="description" formControlName="description">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="col-3">
|
||||||
|
<mat-checkbox style="margin-top: 4%;" formControlName="required">Required</mat-checkbox>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
<!-- </div> -->
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container formArrayName="extraFields">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row" *ngFor="let extraField of extraFieldsArray(sectionIndex).controls; let extraFieldIndex=index;">
|
||||||
|
<ng-container [formGroupName]="extraFieldIndex">
|
||||||
|
<mat-form-field class="col-3">
|
||||||
|
<mat-label>Label</mat-label>
|
||||||
|
<input matInput type="text" name="label" formControlName="label" required>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="col-3">
|
||||||
|
<mat-label>Description</mat-label>
|
||||||
|
<input matInput type="text" name="description" formControlName="description">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="col-3">
|
||||||
|
<mat-label>Type</mat-label>
|
||||||
|
<mat-select placeholder="Type" formControlName="type" required>
|
||||||
|
<mat-option *ngFor="let extraFieldType of getExtraFieldTypes()" [value]="extraFieldType">
|
||||||
|
{{getExtraFieldTypeValue(extraFieldType)}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
<div class="centered-row-item col-1">
|
||||||
|
<mat-checkbox formControlName="required">
|
||||||
|
Required
|
||||||
|
</mat-checkbox>
|
||||||
|
</div>
|
||||||
|
<div class="extra-field-delete col-1" (click)="removeExtraField(sectionIndex, extraFieldIndex)">
|
||||||
|
<mat-icon class="extra-field-delete-icon">delete</mat-icon>
|
||||||
|
<span class="extra-field-delete-text">{{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto">
|
||||||
|
<button mat-button class="action-btn" type="button" (click)="addExtraField(sectionIndex)">Add extra field</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<!-- <mat-form-field>
|
||||||
|
<mat-label>Description Templates</mat-label>
|
||||||
|
<mat-select (selectionChange)="addDescriptionTemplate($event, sectionIndex)" multiple>
|
||||||
|
<mat-option *ngFor="let descTemplate of descriptionsList">{{descTemplate}}</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field> -->
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Description Templates</mat-label>
|
||||||
|
<app-multiple-auto-complete placeholder="Description Templates2" [hidePlaceholder]="true" required='false' [formControl]="section.get('descriptionTemplates')" [configuration]="profilesAutoCompleteConfiguration" (optionRemoved)="onRemoveTemplate($event, sectionIndex)" (optionActionClicked)="onPreviewTemplate($event, sectionIndex)" (optionSelected)="onOptionSelected(sectionIndex)">
|
||||||
|
</app-multiple-auto-complete>
|
||||||
|
<!-- <button matSuffix class="input-btn" (click)="allAvailableProfiles($event)">
|
||||||
|
<mat-icon class="icon-btn">view_list</mat-icon>
|
||||||
|
</button> -->
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <ng-container formArrayName="descriptionTemplates">
|
||||||
|
<div *ngFor="let descriptionTemplate of descriptionTemplatesArray(sectionIndex).controls; let j=index;" class="section-input" style="width: 100%;">
|
||||||
|
<ng-container [formGroupName]="j">
|
||||||
|
<div class="col-12" *ngIf="descriptionTemplatesArray(sectionIndex).length > 0">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Label</mat-label>
|
||||||
|
<input matInput type="text" name="name" formControlName="label">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Min Multiplicity</mat-label>
|
||||||
|
<input matInput type="number" name="minMultiplicity" formControlName="minMultiplicity">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="col-3">
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Max Multiplicity</mat-label>
|
||||||
|
<input matInput type="number" name="maxMultiplicity" formControlName="maxMultiplicity">
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</ng-container> -->
|
||||||
|
</mat-card>
|
||||||
|
<div class="col-1">
|
||||||
|
<div class="row">
|
||||||
|
<!-- <div class="col-auto dlt-section-btn">
|
||||||
|
<button mat-button class="action-btn" type="button" click="removeSection(sectionIndex)">Delete</button>
|
||||||
|
</div> -->
|
||||||
|
<div class="action-list-item col-auto dlt-section-btn" (click)="removeSection(sectionIndex)">
|
||||||
|
<mat-icon class="action-list-icon">delete</mat-icon>
|
||||||
|
<span class="action-list-text">{{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
<!-- <div class="arrows mt-2">
|
||||||
|
<ul class="list-unstyled list-inline d-flex align-items-center">
|
||||||
|
<li *ngIf="canGoUp(i)" class="text-muted">
|
||||||
|
<mat-icon style="cursor: pointer;" [matTooltip]="'DATASET-PROFILE-EDITOR.ACTIONS.FIELD.MOVE-UP' | translate">keyboard_arrow_up</mat-icon>
|
||||||
|
</li>
|
||||||
|
<li *ngIf="canGoDown(i)" class="text-muted">
|
||||||
|
<mat-icon style="cursor: pointer;" [matTooltip]="'DATASET-PROFILE-EDITOR.ACTIONS.FIELD.MOVE-DOWN' | translate">keyboard_arrow_down</mat-icon>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto">
|
||||||
|
<button mat-button class="action-btn" type="button" (click)="addSection()">Add section</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div class="col-12">
|
||||||
<div class="row" *ngFor="let fieldFormGroup of formGroup.get('definition').get('fields')['controls'];let i=index">
|
<div class="row" *ngFor="let fieldFormGroup of formGroup.get('definition').get('fields')['controls'];let i=index">
|
||||||
<div class="col-10">
|
<div class="col-10">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -118,7 +328,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-4">
|
<div class="row mt-4">
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
|
@ -139,7 +349,7 @@
|
||||||
</div> -->
|
</div> -->
|
||||||
|
|
||||||
<div class="col-auto" *ngIf="!viewOnly">
|
<div class="col-auto" *ngIf="!viewOnly">
|
||||||
<button mat-button class="action-btn" type="submit" [disabled]="!formGroup.valid">
|
<button mat-button class="action-btn" type="submit" [disabled]="!dmpBlueprintsFormGroup.valid">
|
||||||
{{'DMP-PROFILE-EDITOR.ACTIONS.SAVE' | translate}}
|
{{'DMP-PROFILE-EDITOR.ACTIONS.SAVE' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -61,3 +61,61 @@
|
||||||
border: 0px;
|
border: 0px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dlt-section-btn {
|
||||||
|
margin: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
-ms-transform: translateY(-50%);
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-input {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-input .arrows {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-list-item{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.action-list-icon{
|
||||||
|
font-size: 1.2em;
|
||||||
|
// padding-right: 1em;
|
||||||
|
width: 14px;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
margin-left: -.09em;
|
||||||
|
height: auto;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-list-text{
|
||||||
|
font-size: 1em;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.extra-field-delete{
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.extra-field-delete-icon{
|
||||||
|
font-size: 1.2em;
|
||||||
|
width: 14px;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.extra-field-delete-text{
|
||||||
|
font-size: 1em;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
import { AfterViewInit, Component } from '@angular/core';
|
import { AfterViewInit, Component } from '@angular/core';
|
||||||
import { FormArray, FormGroup } from '@angular/forms';
|
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||||
import { DmpProfileFieldDataType } from '@app/core/common/enum/dmp-profile-field-type';
|
import { DmpProfileFieldDataType } from '@app/core/common/enum/dmp-profile-field-type';
|
||||||
import { DmpProfileStatus } from '@app/core/common/enum/dmp-profile-status';
|
import { DmpProfileStatus } from '@app/core/common/enum/dmp-profile-status';
|
||||||
|
@ -25,6 +25,17 @@ import { HttpClient } from '@angular/common/http';
|
||||||
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||||
|
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
|
||||||
|
import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile';
|
||||||
|
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
|
||||||
|
import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria';
|
||||||
|
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||||
|
import { AvailableProfilesComponent } from '@app/ui/dmp/editor/available-profiles/available-profiles.component';
|
||||||
|
import { DatasetPreviewDialogComponent } from '@app/ui/dmp/dataset-preview/dataset-preview-dialog.component';
|
||||||
|
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
|
||||||
|
import { DmpBlueprint, DmpBlueprintDefinition, ExtraFieldType, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint';
|
||||||
|
import { DmpBlueprintEditor } from './dmp-blueprint-editor.model';
|
||||||
|
import { Guid } from '@common/types/guid';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -37,19 +48,41 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
||||||
isNew = true;
|
isNew = true;
|
||||||
viewOnly = false;
|
viewOnly = false;
|
||||||
dmpProfileModel: DmpProfileEditorModel;
|
dmpProfileModel: DmpProfileEditorModel;
|
||||||
|
dmpBlueprintModel: DmpBlueprintEditor;
|
||||||
formGroup: FormGroup = null;
|
formGroup: FormGroup = null;
|
||||||
host: string;
|
host: string;
|
||||||
dmpProfileId: string;
|
dmpProfileId: string;
|
||||||
breadCrumbs: Observable<BreadcrumbItem[]>;
|
breadCrumbs: Observable<BreadcrumbItem[]>;
|
||||||
|
|
||||||
|
dmpBlueprintsFormGroup: FormGroup = null;
|
||||||
|
|
||||||
|
profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
|
||||||
|
|
||||||
|
fieldList = [
|
||||||
|
{label: 'Title', type: SystemFieldType.TEXT},
|
||||||
|
{label: 'Description', type: SystemFieldType.HTML_TEXT},
|
||||||
|
{label: 'Researchers', type: SystemFieldType.RESEARCHERS},
|
||||||
|
{label: 'Organizations', type: SystemFieldType.ORGANIZATIONS},
|
||||||
|
{label: 'Language', type: SystemFieldType.LANGUAGE},
|
||||||
|
{label: 'Contact', type: SystemFieldType.CONTACT},
|
||||||
|
{label: 'Funder', type: SystemFieldType.FUNDER},
|
||||||
|
{label: 'Grant', type: SystemFieldType.GRANT},
|
||||||
|
{label: 'Project', type: SystemFieldType.PROJECT},
|
||||||
|
{label: 'License', type: SystemFieldType.LICENSE},
|
||||||
|
{label: 'Access Rights', type: SystemFieldType.ACCESS_RIGHTS}
|
||||||
|
];
|
||||||
|
selectedSystemFields: string[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private dmpProfileService: DmpProfileService,
|
private dmpProfileService: DmpProfileService,
|
||||||
|
private _service: DmpService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private language: TranslateService,
|
private language: TranslateService,
|
||||||
private enumUtils: EnumUtils,
|
private enumUtils: EnumUtils,
|
||||||
private uiNotificationService: UiNotificationService,
|
private uiNotificationService: UiNotificationService,
|
||||||
private formService: FormService,
|
private formService: FormService,
|
||||||
|
private fb: FormBuilder,
|
||||||
private configurationService: ConfigurationService,
|
private configurationService: ConfigurationService,
|
||||||
private httpClient: HttpClient,
|
private httpClient: HttpClient,
|
||||||
private matomoService: MatomoService,
|
private matomoService: MatomoService,
|
||||||
|
@ -61,6 +94,16 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
this.matomoService.trackPageView('Admin: DMP Profile Edit');
|
this.matomoService.trackPageView('Admin: DMP Profile Edit');
|
||||||
|
|
||||||
|
this.profilesAutoCompleteConfiguration = {
|
||||||
|
filterFn: this.filterProfiles.bind(this),
|
||||||
|
initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||||
|
displayFn: (item) => item['label'],
|
||||||
|
titleFn: (item) => item['label'],
|
||||||
|
subtitleFn: (item) => item['description'],
|
||||||
|
popupItemActionIcon: 'visibility'
|
||||||
|
};
|
||||||
|
|
||||||
this.route.params
|
this.route.params
|
||||||
.pipe(takeUntil(this._destroyed))
|
.pipe(takeUntil(this._destroyed))
|
||||||
.subscribe((params: Params) => {
|
.subscribe((params: Params) => {
|
||||||
|
@ -85,9 +128,11 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.dmpProfileModel = new DmpProfileEditorModel();
|
this.dmpProfileModel = new DmpProfileEditorModel();
|
||||||
|
this.dmpBlueprintModel = new DmpBlueprintEditor();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.formGroup = this.dmpProfileModel.buildForm();
|
// this.formGroup = this.dmpProfileModel.buildForm();
|
||||||
this.addField();
|
// this.addField();
|
||||||
|
this.formGroup = this.dmpBlueprintModel.buildForm();
|
||||||
});
|
});
|
||||||
this.breadCrumbs = observableOf([{
|
this.breadCrumbs = observableOf([{
|
||||||
parentComponentName: 'DmpProfileListingComponent',
|
parentComponentName: 'DmpProfileListingComponent',
|
||||||
|
@ -96,6 +141,282 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
||||||
}]);
|
}]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.initDmpBlueptintForm();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
filterProfiles(value: string): Observable<DatasetProfileModel[]> {
|
||||||
|
const request = new DataTableRequest<DatasetProfileCriteria>(null, null, { fields: ['+label'] });
|
||||||
|
const criteria = new DatasetProfileCriteria();
|
||||||
|
criteria.like = value;
|
||||||
|
request.criteria = criteria;
|
||||||
|
return this._service.searchDMPProfiles(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
initDmpBlueptintForm(): void {
|
||||||
|
this.dmpBlueprintsFormGroup = this.fb.group({
|
||||||
|
label: this.fb.control(''),
|
||||||
|
sections: this.fb.array([])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sectionsArray(): FormArray {
|
||||||
|
return this.dmpBlueprintsFormGroup.get('sections') as FormArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
initSection(ordinal: number): FormGroup {
|
||||||
|
return this.fb.group({
|
||||||
|
id: this.fb.control(Guid.create().toString()),
|
||||||
|
label: this.fb.control(''),
|
||||||
|
description: this.fb.control(''),
|
||||||
|
ordinal: this.fb.control(ordinal),
|
||||||
|
systemFields: this.fb.array([]),
|
||||||
|
descriptionTemplates: this.fb.control(''),
|
||||||
|
// this.fb.array([this.initDescriptionTemplate()]),
|
||||||
|
extraFields: this.fb.array([])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addSection(): void {
|
||||||
|
this.sectionsArray().push(this.initSection(this.sectionsArray().length));
|
||||||
|
}
|
||||||
|
|
||||||
|
removeSection(sectionIndex: number): void {
|
||||||
|
this.sectionsArray().removeAt(sectionIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
systemFieldsArray(sectionIndex: number): FormArray {
|
||||||
|
return this.sectionsArray().at(sectionIndex).get('systemFields') as FormArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
initSystemField(systemField?: SystemFieldType): FormGroup {
|
||||||
|
return this.fb.group({
|
||||||
|
id: this.fb.control(Guid.create().toString()),
|
||||||
|
type: this.fb.control(systemField),
|
||||||
|
label: this.fb.control(''),
|
||||||
|
placeholder: this.fb.control(''),
|
||||||
|
description: this.fb.control(''),
|
||||||
|
required: this.fb.control(true),
|
||||||
|
ordinal: this.fb.control('')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addSystemField(sectionIndex: number, systemField?: SystemFieldType): void {
|
||||||
|
this.systemFieldsArray(sectionIndex).push(this.initSystemField(systemField));
|
||||||
|
}
|
||||||
|
|
||||||
|
transfromEnumToString(type: SystemFieldType): string{
|
||||||
|
return this.fieldList.find(f => f.type == type).label;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedFieldType(systemField: string, type: SystemFieldType, sectionIndex: number): void {
|
||||||
|
let index = this.selectedSystemFields.indexOf(systemField);
|
||||||
|
if (index == -1) {
|
||||||
|
this.selectedSystemFields.push(systemField);
|
||||||
|
this.addSystemField(sectionIndex, type);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.selectedSystemFields.splice(index, 1);
|
||||||
|
this.removeSystemField(sectionIndex, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
systemFieldDisabled(systemField: SystemFieldType, sectionIndex: number) {
|
||||||
|
let i = 0;
|
||||||
|
for (let s in this.sectionsArray().controls) {
|
||||||
|
if (i != sectionIndex) {
|
||||||
|
for (let f of this.systemFieldsArray(i).controls) {
|
||||||
|
if (f.get('type').value == systemField) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeSystemFieldWithIndex(sectionIndex: number, fieldIndex: number): void {
|
||||||
|
this.systemFieldsArray(sectionIndex).removeAt(fieldIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeSystemField(sectionIndex: number, systemField: SystemFieldType): void {
|
||||||
|
let i = 0;
|
||||||
|
for(let sf of this.systemFieldsArray(sectionIndex).controls){
|
||||||
|
if(sf.get('type').value == systemField){
|
||||||
|
this.systemFieldsArray(sectionIndex).removeAt(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionTemplatesArray(sectionIndex: number): FormArray {
|
||||||
|
return this.sectionsArray().at(sectionIndex).get('descriptionTemplates') as FormArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
initDescriptionTemplate(): FormGroup {
|
||||||
|
return this.fb.group({
|
||||||
|
descriptionTemplateId: this.fb.control(''),
|
||||||
|
label: this.fb.control(''),
|
||||||
|
minMultiplicity: this.fb.control(''),
|
||||||
|
maxMultiplicity: this.fb.control('')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addDescriptionTemplate(descriptionTemplate, sectionIndex: number): void {
|
||||||
|
this.descriptionTemplatesArray(sectionIndex).push(this.fb.group({
|
||||||
|
label: this.fb.control(descriptionTemplate.value)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
removeDescriptionTemplate(sectionIndex: number, templateIndex: number): void {
|
||||||
|
this.descriptionTemplatesArray(sectionIndex).removeAt(templateIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
extraFieldsArray(sectionIndex: number): FormArray {
|
||||||
|
return this.sectionsArray().at(sectionIndex).get('extraFields') as FormArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
initExtraField(): FormGroup {
|
||||||
|
return this.fb.group({
|
||||||
|
id: this.fb.control(Guid.create().toString()),
|
||||||
|
label: this.fb.control(''),
|
||||||
|
placeholder: this.fb.control(''),
|
||||||
|
description: this.fb.control(''),
|
||||||
|
type: this.fb.control(''),
|
||||||
|
required: this.fb.control(false),
|
||||||
|
ordinal: this.fb.control('')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addExtraField(sectionIndex: number): void {
|
||||||
|
this.extraFieldsArray(sectionIndex).push(this.initExtraField());
|
||||||
|
}
|
||||||
|
|
||||||
|
removeExtraField(sectionIndex: number, extraFieldIndex: number): void {
|
||||||
|
this.extraFieldsArray(sectionIndex).removeAt(extraFieldIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
getExtraFieldTypes(): Number[] {
|
||||||
|
let keys: string[] = Object.keys(ExtraFieldType);
|
||||||
|
keys = keys.slice(0, keys.length / 2);
|
||||||
|
const values: Number[] = keys.map(Number);
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
getExtraFieldTypeValue(extraFieldType: ExtraFieldType): string {
|
||||||
|
switch (extraFieldType) {
|
||||||
|
case ExtraFieldType.TEXT: return 'Text';
|
||||||
|
case ExtraFieldType.RICH_TEXT: return 'Rich Text';
|
||||||
|
case ExtraFieldType.DATE: return 'Date';
|
||||||
|
case ExtraFieldType.NUMBER: return 'Number';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmitTest(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(event: CdkDragDrop<string[]>) {
|
||||||
|
this.moveItemInFormArray(
|
||||||
|
this.systemFieldsArray(0),
|
||||||
|
event.previousIndex,
|
||||||
|
event.currentIndex
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
moveItemInFormArray(formArray: FormArray, fromIndex: number, toIndex: number): void {
|
||||||
|
const dir = toIndex > fromIndex ? 1 : -1;
|
||||||
|
|
||||||
|
const item = formArray.at(fromIndex);
|
||||||
|
for (let i = fromIndex; i * dir < toIndex * dir; i = i + dir) {
|
||||||
|
const current = formArray.at(i + dir);
|
||||||
|
formArray.setControl(i, current);
|
||||||
|
}
|
||||||
|
formArray.setControl(toIndex, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clearForm(): void{
|
||||||
|
// this.dmpBlueprintsFormGroup.reset();
|
||||||
|
// }
|
||||||
|
|
||||||
|
canGoUp(index: number): boolean {
|
||||||
|
return index > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
canGoDown(index: number): boolean {
|
||||||
|
return index < (this.sectionsArray().length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemoveTemplate(event, sectionIndex: number) {
|
||||||
|
// let found = false;
|
||||||
|
// const profiles = this.descriptionTemplatesArray(sectionIndex).value;//this.formGroup.get('profiles').value;
|
||||||
|
// this.formGroup.get('datasets')['controls'].forEach(element => {
|
||||||
|
// if (element.get('profile').value.id === event.id) {
|
||||||
|
// found = true;
|
||||||
|
// this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-REMOVE-TEMPLATE'), SnackBarNotificationLevel.Success);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// if (found) {
|
||||||
|
// this.formGroup.get('profiles').setValue(profiles);
|
||||||
|
// this.profilesAutoCompleteConfiguration = {
|
||||||
|
// filterFn: this.filterProfiles.bind(this),
|
||||||
|
// initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||||
|
// displayFn: (item) => item['label'],
|
||||||
|
// titleFn: (item) => item['label'],
|
||||||
|
// subtitleFn: (item) => item['description'],
|
||||||
|
// popupItemActionIcon: 'visibility'
|
||||||
|
// };
|
||||||
|
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
onPreviewTemplate(event, sectionIndex: number) {
|
||||||
|
const dialogRef = this.dialog.open(DatasetPreviewDialogComponent, {
|
||||||
|
width: '590px',
|
||||||
|
minHeight: '200px',
|
||||||
|
restoreFocus: false,
|
||||||
|
data: {
|
||||||
|
template: event
|
||||||
|
},
|
||||||
|
panelClass: 'custom-modalbox'
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||||
|
if (result) {
|
||||||
|
let profiles = this.descriptionTemplatesArray(sectionIndex).value;//this.formGroup.get('profiles').value;
|
||||||
|
profiles.push(event);
|
||||||
|
this.descriptionTemplatesArray(sectionIndex).setValue(profiles);//this.formGroup.get('profiles').setValue(profiles);
|
||||||
|
this.profilesAutoCompleteConfiguration = {
|
||||||
|
filterFn: this.filterProfiles.bind(this),
|
||||||
|
initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||||
|
displayFn: (item) => item['label'],
|
||||||
|
titleFn: (item) => item['label'],
|
||||||
|
subtitleFn: (item) => item['description'],
|
||||||
|
popupItemActionIcon: 'visibility'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onOptionSelected(sectionIndex: number){
|
||||||
|
try{
|
||||||
|
const profiles = this.descriptionTemplatesArray(sectionIndex).value as {id:string, label:string}[];//this.formGroup.get('profiles').value as {id:string, label:string}[];
|
||||||
|
const profileCounts: Map<String, number> = new Map<String, number>();
|
||||||
|
profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id): 0 ) + 1));
|
||||||
|
const duplicateProfiles = profiles.filter((value) => {
|
||||||
|
let isOk = profileCounts.get(value.id) > 1;
|
||||||
|
if (isOk) {
|
||||||
|
profileCounts.set(value.id, 0);
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
});
|
||||||
|
duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1));
|
||||||
|
profiles.sort((a,b)=> a.label.localeCompare(b.label));
|
||||||
|
}
|
||||||
|
catch{
|
||||||
|
console.info('Could not sort Dataset Templates')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
formSubmit(): void {
|
formSubmit(): void {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
</button>
|
</button>
|
||||||
<button mat-raised-button class="create-btn ml-md-3" [routerLink]="['/dmp-profiles/new'] ">
|
<button mat-raised-button class="create-btn ml-md-3" [routerLink]="['/dmp-profiles/new'] ">
|
||||||
<span class="button-text">
|
<span class="button-text">
|
||||||
{{'DMP-PROFILE-LISTING.CREATE-DMP-TEMPLATE' | translate}}
|
{{'DMP-PROFILE-LISTING.CREATE-DMP-BLUEPRINT' | translate}}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -71,7 +71,7 @@ export class DmpProfileListingComponent extends BaseComponent implements OnInit
|
||||||
this.criteria.setRefreshCallback(() => this.refresh());
|
this.criteria.setRefreshCallback(() => this.refresh());
|
||||||
this.breadCrumbs = observableOf([{
|
this.breadCrumbs = observableOf([{
|
||||||
parentComponentName: null,
|
parentComponentName: null,
|
||||||
label: this.languageService.instant('NAV-BAR.DMP-TEMPLATES'),
|
label: this.languageService.instant('NAV-BAR.DMP-BLUEPRINTS-CAPS'),
|
||||||
url: '/dmp-profiles'
|
url: '/dmp-profiles'
|
||||||
}]);
|
}]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,271 @@
|
||||||
|
<div class="main-content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="form-container">
|
||||||
|
<!-- DMP Header -->
|
||||||
|
<div [hidden]="false" class="fixed-editor-header">
|
||||||
|
<div class="card editor-header">
|
||||||
|
<div class="col">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto info">
|
||||||
|
<div class="title">{{'DMP-EDITOR.TITLE.EDIT-DMP' | translate}}</div>
|
||||||
|
<!-- <div class="subtitle">{{ formGroup.get('label').value }} <span *ngIf="isDirty()" class="changes">({{'DMP-EDITOR.CHANGES' | translate}})</span></div> -->
|
||||||
|
</div>
|
||||||
|
<div class="ml-auto d-flex flex-row">
|
||||||
|
<!-- <mat-divider *ngIf="formGroup.get('id').value && (isDirty() || isNew || (!isNew && formGroup.enabled && !lockStatus) || lockStatus)"
|
||||||
|
[vertical]="true" class="ml-2 mr-2">
|
||||||
|
</mat-divider> -->
|
||||||
|
<div class="col-auto d-flex align-items-center">
|
||||||
|
<!-- <button [disabled]="saving" *ngIf="isDirty()" type="button" mat-raised-button class="discard-btn mr-3" (click)="discard()">
|
||||||
|
{{'DMP-EDITOR.ACTIONS.DISCARD' | translate}}
|
||||||
|
</button> -->
|
||||||
|
<button [disabled]="saving" *ngIf="isNew" mat-raised-button type="button" (click)="save()" class="save-btn">
|
||||||
|
{{'DMP-EDITOR.ACTIONS.SAVE' | translate}}
|
||||||
|
</button>
|
||||||
|
<!-- <div *ngIf="!isNew && formGroup.enabled && !lockStatus">
|
||||||
|
<button [disabled]="saving" *ngIf="!isFinalized" mat-raised-button (click)="formSubmit()" class="save-btn">
|
||||||
|
{{'DMP-EDITOR.ACTIONS.SAVE' | translate}}
|
||||||
|
</button>
|
||||||
|
</div> -->
|
||||||
|
<!-- <button *ngIf="lockStatus" mat-raised-button disabled class="dataset-save-btn cursor-default" type="button">{{ 'DMP-OVERVIEW.LOCKED' | translate}}</button> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-auto dmp-stepper">
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
|
</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()">
|
||||||
|
<span class="material-icons">chevron_left</span>
|
||||||
|
<div>{{'DMP-EDITOR.STEPPER.PREVIOUS' | translate}}</div>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="this.step < this.maxStep" mat-raised-button type="button" class="col-auto stepper-btn ml-auto" [ngClass]="{ 'next-disabled': this.step === this.maxStep, 'next': this.step < stepsBeforeDatasets, 'dataset-next': this.step >= stepsBeforeDatasets }" (click)="nextStep()">
|
||||||
|
<div>{{'DMP-EDITOR.STEPPER.NEXT' | translate}}</div>
|
||||||
|
<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">
|
||||||
|
<!-- <mat-icon>add</mat-icon> -->
|
||||||
|
{{'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-12 blueprint-section" [hidden]="this.step !== 0">
|
||||||
|
<div class="dmp-blueprint-form">
|
||||||
|
<mat-form-field>
|
||||||
|
<app-single-auto-complete [required]="false" [formControl]="formGroup.get('profile')" placeholder="Select blueprint" [configuration]="dmpBlueprintAutoCompleteConfiguration">
|
||||||
|
</app-single-auto-complete>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-5">
|
||||||
|
<button mat-button class="action-btn" [disabled]="selectedDmpBlueprintDefinition == null" (click)="selectBlueprint()">Next</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-7" *ngIf="formGroup.get('profile').value == null || (formGroup.get('profile').value && formGroup.get('profile').value.id !== '86635178-36a6-484f-9057-a934e4eeecd5')">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
<p>or continue with</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<button mat-button class="action-btn" style="float: right;" (click)="selectDefaultBlueprint()">Default Blueprint</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<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="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div *ngFor="let field of section.systemFields; 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">
|
||||||
|
<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 == '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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,378 @@
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.main-content {
|
||||||
|
padding: 30px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container {
|
||||||
|
height: calc(100vh - 124px);
|
||||||
|
margin-top: 6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-editor-header {
|
||||||
|
// position: fixed;
|
||||||
|
// width: calc(100% - 310px);
|
||||||
|
z-index: 3;
|
||||||
|
background-color: whitesmoke;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-header {
|
||||||
|
height: 64px;
|
||||||
|
background: var(--unnamed-color-var(--primary-color)) 0% 0% no-repeat padding-box;
|
||||||
|
background: var(--primary-color) 0% 0% no-repeat padding-box;
|
||||||
|
box-shadow: 0px 3px 6px #00000029;
|
||||||
|
padding: 0.6rem;
|
||||||
|
margin: 30px 0px 0px 0px;
|
||||||
|
border-radius: 4px;
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
.info {
|
||||||
|
flex: 2;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #ffffff;
|
||||||
|
opacity: 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
text-align: left;
|
||||||
|
color: #ffffff;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 16px;
|
||||||
|
opacity: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-btn, .dmp-export-btn {
|
||||||
|
background: #ffffff 0% 0% no-repeat padding-box !important;
|
||||||
|
border-radius: 30px;
|
||||||
|
opacity: 1;
|
||||||
|
width: 110px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmp-stepper {
|
||||||
|
position: fixed;
|
||||||
|
// height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: calc(100vh - 190px);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-title {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 20px;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
color: #212121;
|
||||||
|
opacity: 0.6;
|
||||||
|
margin: 2.875rem 0rem 2.875rem 0rem;
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-list li {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
color: #212121;
|
||||||
|
padding: 0.3rem 0.1rem;
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: pointer;
|
||||||
|
max-width: 290px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-list li:hover {
|
||||||
|
background-color: #ececec;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-list .active {
|
||||||
|
color: #212121;
|
||||||
|
font-weight: 700;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-list .active-dataset {
|
||||||
|
color: #212121;
|
||||||
|
font-weight: 700;
|
||||||
|
opacity: 1;
|
||||||
|
.label {
|
||||||
|
width: 100%;
|
||||||
|
height: 27px;
|
||||||
|
line-height: 27px;
|
||||||
|
background-color: var(--secondary-color);
|
||||||
|
color: #5d5d5d;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
justify-content: left;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 0.625rem;
|
||||||
|
padding-right: 0.625rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-icon.size-16 {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-top: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-dataset {
|
||||||
|
color: #f16868;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-dataset:hover {
|
||||||
|
color: #f16868;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-actions {
|
||||||
|
display: flex;
|
||||||
|
padding-left: 1rem;
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
// margin-top: 5rem;
|
||||||
|
// flex-grow: 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper-btn {
|
||||||
|
border-radius: 30px;
|
||||||
|
opacity: 1;
|
||||||
|
width: 154px;
|
||||||
|
min-height: 40px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.previous {
|
||||||
|
color: #212121;
|
||||||
|
background: #f5f5f5 0% 0% no-repeat padding-box;
|
||||||
|
box-shadow: 0px 3px 6px #1e202029;
|
||||||
|
border: 2px solid #212121;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-dataset-btn {
|
||||||
|
background: var(--secondary-color) 0% 0% no-repeat padding-box;
|
||||||
|
box-shadow: 0px 3px 6px #1e202029;
|
||||||
|
font-weight: 500;
|
||||||
|
white-space: normal;
|
||||||
|
word-wrap: break-word;
|
||||||
|
line-height: normal;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 13.8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-dataset-action {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.next {
|
||||||
|
background: var(--primary-color) 0% 0% no-repeat padding-box;
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0px 3px 6px #1e202029;
|
||||||
|
font-weight: 400;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataset-next {
|
||||||
|
background: var(--secondary-color) 0% 0% no-repeat padding-box;
|
||||||
|
color: #212121;
|
||||||
|
box-shadow: 0px 3px 6px #1e202029;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.previous-disabled,
|
||||||
|
.add-dataset-btn-disabled {
|
||||||
|
border: 1px solid #b5b5b5;
|
||||||
|
color: #b5b5b5 !important;
|
||||||
|
cursor: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.next-disabled {
|
||||||
|
background: #cbcbcb 0% 0% no-repeat padding-box;
|
||||||
|
box-shadow: 0px 3px 6px #1e202029;
|
||||||
|
color: white;
|
||||||
|
cursor: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
// position: relative;
|
||||||
|
// left: 362px;
|
||||||
|
// width: calc(100% - 366px);
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
left: 362px;
|
||||||
|
width: calc(100% - 366px);
|
||||||
|
overflow-y: auto;
|
||||||
|
height: calc(100vh - 218px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
border-radius: 30px;
|
||||||
|
background-color: var(--secondary-color);
|
||||||
|
border: 1px solid transparent;
|
||||||
|
padding-left: 2em;
|
||||||
|
padding-right: 2em;
|
||||||
|
box-shadow: 0px 3px 6px #1E202029;
|
||||||
|
|
||||||
|
transition-property: background-color, color;
|
||||||
|
transition-duration: 200ms;
|
||||||
|
transition-delay: 50ms;
|
||||||
|
transition-timing-function: ease-in-out;
|
||||||
|
&:disabled{
|
||||||
|
background-color: #CBCBCB;
|
||||||
|
color: #FFF;
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.blueprint-section {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
color: #212121;
|
||||||
|
opacity: 1;
|
||||||
|
margin: 3rem 0rem 3rem 0rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: var(--primary-color-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
height: 100vh !important;
|
||||||
|
margin-top: -80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmp-blueprint-form {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
letter-spacing: 0.15px;
|
||||||
|
color: #7d7d7d;
|
||||||
|
opacity: 1;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-info {
|
||||||
|
.intro {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
color: #212121;
|
||||||
|
opacity: 1;
|
||||||
|
margin: 3rem 0rem 3rem 0rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 18px;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
color: #212121;
|
||||||
|
opacity: 0.81;
|
||||||
|
margin-top: 1.625rem;
|
||||||
|
margin-bottom: 0.625rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
letter-spacing: 0px;
|
||||||
|
color: #212121;
|
||||||
|
opacity: 0.81;
|
||||||
|
margin-bottom: 2.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-form {
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
letter-spacing: 0.15px;
|
||||||
|
color: #7d7d7d;
|
||||||
|
opacity: 1;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.insert-manually {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: var(--primary-color-3);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-found {
|
||||||
|
// cursor: pointer;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 400;
|
||||||
|
padding: 0rem 0.5rem 0rem 0rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled-toggle {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 400;
|
||||||
|
padding: 0rem 0.5rem 0rem 0rem;
|
||||||
|
color: #e0e0e0 !important;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-btn {
|
||||||
|
border: none;
|
||||||
|
color: #aaaaaa;
|
||||||
|
background-color: #ffffff00;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-btn :hover {
|
||||||
|
color: var(--primary-color-3) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::ng-deep .input-form .mat-form-field-appearance-outline .mat-form-field-outline {
|
||||||
|
background: #fafafa !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::ng-deep .input-form .mat-form-field-appearance-outline .mat-form-field-infix {
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 0.6em 0 1em 0 !important;
|
||||||
|
}
|
|
@ -0,0 +1,777 @@
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { AbstractControl, FormArray, FormControl, FormGroup, Validators } from '@angular/forms';
|
||||||
|
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
|
||||||
|
import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint';
|
||||||
|
import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria';
|
||||||
|
import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service';
|
||||||
|
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
||||||
|
import { DmpBlueprintEditor } from '@app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model';
|
||||||
|
import { debounceTime, filter, map, switchMap, takeUntil, tap } from 'rxjs/operators';
|
||||||
|
import { DmpEditorModel } from '../editor/dmp-editor.model';
|
||||||
|
import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties-form.model';
|
||||||
|
import { FunderFormModel } from '../editor/grant-tab/funder-form-model';
|
||||||
|
import { GrantTabModel } from '../editor/grant-tab/grant-tab-model';
|
||||||
|
import { ProjectFormModel } from '../editor/grant-tab/project-form-model';
|
||||||
|
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||||
|
import { BaseComponent } from '@common/base/base.component';
|
||||||
|
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||||
|
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
|
||||||
|
import { LanguageInfoService } from '@app/core/services/culture/language-info-service';
|
||||||
|
import { LanguageInfo } from '@app/core/model/language-info';
|
||||||
|
import { UserModel } from '@app/core/model/user/user';
|
||||||
|
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { ExternalSourceItemModel } from '@app/core/model/external-sources/external-source-item';
|
||||||
|
import { OrganisationService } from '@app/core/services/organisation/organisation.service';
|
||||||
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { AddResearcherComponent } from '../editor/add-researcher/add-researcher.component';
|
||||||
|
import { AddOrganizationComponent } from '../editor/add-organization/add-organization.component';
|
||||||
|
import { RequestItem } from '@app/core/query/request-item';
|
||||||
|
import { LicenseCriteria } from '@app/core/query/license/license-criteria';
|
||||||
|
import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile';
|
||||||
|
import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria';
|
||||||
|
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||||
|
import { AvailableProfilesComponent } from '../editor/available-profiles/available-profiles.component';
|
||||||
|
import { DatasetPreviewDialogComponent } from '../dataset-preview/dataset-preview-dialog.component';
|
||||||
|
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||||
|
import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component';
|
||||||
|
import { DmpStatus } from '@app/core/common/enum/dmp-status';
|
||||||
|
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
|
||||||
|
import { DmpModel } from '@app/core/model/dmp/dmp';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||||
|
import { DmpToDatasetDialogComponent } from '../dmp-to-dataset/dmp-to-dataset-dialog.component';
|
||||||
|
import { UserInfoListingModel } from '@app/core/model/user/user-info-listing';
|
||||||
|
import { FormService } from '@common/forms/form-service';
|
||||||
|
|
||||||
|
interface Visible {
|
||||||
|
value: boolean;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-dmp-editor-blueprint',
|
||||||
|
templateUrl: './dmp-editor-blueprint.component.html',
|
||||||
|
styleUrls: ['./dmp-editor-blueprint.component.scss']
|
||||||
|
})
|
||||||
|
export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit {
|
||||||
|
|
||||||
|
saving = false;
|
||||||
|
|
||||||
|
isNew = true;
|
||||||
|
isUserOwner: boolean = true;
|
||||||
|
isNewVersion = false;
|
||||||
|
isFinalized = false;
|
||||||
|
isClone = false;
|
||||||
|
hasChanges = false;
|
||||||
|
isDiscarded = false;
|
||||||
|
|
||||||
|
isCreateNew = false;
|
||||||
|
isCreateNewProject = false;
|
||||||
|
isCreateNewFunder = false;
|
||||||
|
|
||||||
|
dmp: DmpEditorModel;
|
||||||
|
formGroup: FormGroup = null;
|
||||||
|
formGroupRawValue: any;
|
||||||
|
|
||||||
|
associatedUsers: Array<UserModel>;
|
||||||
|
people: Array<UserInfoListingModel>;
|
||||||
|
|
||||||
|
lockStatus: Boolean = false;
|
||||||
|
|
||||||
|
step: number = 0;
|
||||||
|
stepsBeforeDatasets: number = 4;
|
||||||
|
maxStep: number = 4;
|
||||||
|
|
||||||
|
scrollTop: number;
|
||||||
|
hintErrors: boolean = false;
|
||||||
|
|
||||||
|
selectedDmpBlueprintDefinition: DmpBlueprintDefinition = null;
|
||||||
|
|
||||||
|
private associates: UserModel[] = [];
|
||||||
|
|
||||||
|
visibles: Visible[] = [
|
||||||
|
{ value: true, name: 'DMP-EDITOR.VISIBILITY.PUBLIC' },
|
||||||
|
{ 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))),
|
||||||
|
displayFn: (item) => item['name'],
|
||||||
|
titleFn: (item) => item['name']
|
||||||
|
};
|
||||||
|
|
||||||
|
profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private dmpProfileService: DmpProfileService,
|
||||||
|
private authService: AuthService,
|
||||||
|
private router: Router,
|
||||||
|
private configurationService: ConfigurationService,
|
||||||
|
private languageInfoService: LanguageInfoService,
|
||||||
|
private language: TranslateService,
|
||||||
|
private externalSourcesService: ExternalSourcesService,
|
||||||
|
private organizationService: OrganisationService,
|
||||||
|
private dmpService: DmpService,
|
||||||
|
private uiNotificationService: UiNotificationService,
|
||||||
|
private formService: FormService,
|
||||||
|
private dialog: MatDialog
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.dmp = new DmpEditorModel();
|
||||||
|
this.dmp.grant = new GrantTabModel();
|
||||||
|
this.dmp.project = new ProjectFormModel();
|
||||||
|
this.dmp.funder = new FunderFormModel();
|
||||||
|
this.dmp.extraProperties = new ExtraPropertiesFormModel();
|
||||||
|
this.dmp.extraProperties.visible = false;
|
||||||
|
this.dmp.extraProperties.contact = this.authService.current().id;
|
||||||
|
this.formGroup = this.dmp.buildForm();
|
||||||
|
|
||||||
|
this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue()));
|
||||||
|
|
||||||
|
if (this.formGroup.get('profile')) { this.selectedDmpBlueprintDefinition = this.formGroup.get('profile').value; }
|
||||||
|
this.registerFormEventsForDmpBlueprint();
|
||||||
|
|
||||||
|
if (!this.isUserOwner) {
|
||||||
|
this.formGroup.disable();
|
||||||
|
}
|
||||||
|
if (isNullOrUndefined(this.formGroup.get('extraProperties').get('publicDate').value)) {
|
||||||
|
this.formGroup.get('extraProperties').get('publicDate').patchValue(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
const principal = this.authService.current();
|
||||||
|
let associate: UserModel = {
|
||||||
|
id: principal.id,
|
||||||
|
name: principal.name,
|
||||||
|
appRoles: principal.authorities,
|
||||||
|
email: principal.email
|
||||||
|
};
|
||||||
|
this.associates.push(associate);
|
||||||
|
if (isNullOrUndefined(this.formGroup.get('extraProperties').get('contact').value)) {
|
||||||
|
this.formGroup.get('extraProperties').get('contact').patchValue(associate.id);
|
||||||
|
}
|
||||||
|
if (isNullOrUndefined(this.formGroup.get('extraProperties').get('language').value)) {
|
||||||
|
this.formGroup.get('extraProperties').get('language').patchValue('en');
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[];
|
||||||
|
profiles.sort((a,b)=>a.label.localeCompare(b.label));
|
||||||
|
}catch{
|
||||||
|
console.info('Could not sort profiles');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.profilesAutoCompleteConfiguration = {
|
||||||
|
filterFn: this.filterProfiles.bind(this),
|
||||||
|
initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||||
|
displayFn: (item) => item['label'],
|
||||||
|
titleFn: (item) => item['label'],
|
||||||
|
subtitleFn: (item) => item['description'],
|
||||||
|
popupItemActionIcon: 'visibility'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {
|
||||||
|
this.formSubmit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
formSubmit(addNew?: boolean, showAddDatasetDialog?: boolean): void {
|
||||||
|
this.saving = true;
|
||||||
|
this.formService.touchAllFormFields(this.formGroup);
|
||||||
|
|
||||||
|
if(!this._isDMPDescriptionValid()){
|
||||||
|
const errmess = this._buildDMPDescriptionErrorMessages();
|
||||||
|
this.showValidationErrorsDialog(undefined, errmess);
|
||||||
|
this.hintErrors = true;
|
||||||
|
this.saving = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.onSubmit(addNew, showAddDatasetDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
public formChanged() {
|
||||||
|
if (!this.isDiscarded) {
|
||||||
|
this.hasChanges = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectDefaultBlueprint() {
|
||||||
|
this.dmpProfileService.getSingleBlueprint('86635178-36a6-484f-9057-a934e4eeecd5')
|
||||||
|
.pipe(takeUntil(this._destroyed))
|
||||||
|
.subscribe(result => {
|
||||||
|
this.selectedDmpBlueprintDefinition = result.definition;
|
||||||
|
this.formGroup.get('profile').setValue(result);
|
||||||
|
this.maxStep = this.selectedDmpBlueprintDefinition.sections.length;
|
||||||
|
this.nextStep();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
selectBlueprint() {
|
||||||
|
this.maxStep = this.selectedDmpBlueprintDefinition.sections.length;
|
||||||
|
this.nextStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
nextStep() {
|
||||||
|
this.step = this.step < this.maxStep ? this.step + 1 : this.step;
|
||||||
|
this.resetScroll();
|
||||||
|
// if (this.step >= this.stepsBeforeDatasets) {
|
||||||
|
// this.datasetId = this.datasets.at(this.step - this.stepsBeforeDatasets).get('id').value;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
previousStep() {
|
||||||
|
this.step = this.step !== 0 ? this.step - 1 : this.step;
|
||||||
|
this.resetScroll();
|
||||||
|
// if (this.step >= this.stepsBeforeDatasets) {
|
||||||
|
// this.datasetId = this.datasets.at(this.step - this.stepsBeforeDatasets).get('id').value;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
changeStep(index: number, dataset?: FormControl) {
|
||||||
|
this.step = index;
|
||||||
|
this.resetScroll();
|
||||||
|
// if (dataset) { this.datasetId = dataset.get('id').value };
|
||||||
|
}
|
||||||
|
|
||||||
|
private resetScroll() {
|
||||||
|
document.getElementById('editor-form').scrollTop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
addDataset() {
|
||||||
|
this.saving = true;
|
||||||
|
|
||||||
|
if(!this._isDMPDescriptionValid()){
|
||||||
|
const errmess = this._buildDMPDescriptionErrorMessages();
|
||||||
|
this.showValidationErrorsDialog(undefined, errmess);
|
||||||
|
this.hintErrors = true;
|
||||||
|
this.saving = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// const showDialog = this.hasProfile() && this.isNew;
|
||||||
|
|
||||||
|
this.onSubmit(true, false);
|
||||||
|
// this.formSubmit(true, false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Add dataset to list
|
||||||
|
// if (!this.formGroup.get('datasets')) {
|
||||||
|
// this.formGroup.addControl('datasets', new FormBuilder().array(new Array<FormControl>()));
|
||||||
|
// }
|
||||||
|
// this.formGroup.get('datasets')['controls'].push(new DatasetWizardEditorModel().buildForm());
|
||||||
|
// this.datasets = this.formGroup.get('datasets') as FormArray;
|
||||||
|
// this.step = this.stepsBeforeDatasets + this.formGroup.get('datasets')['controls'].length - 1;
|
||||||
|
// this.maxStep = this.maxStep + this.formGroup.get('datasets')['controls'].length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit(addNew?: boolean, showAddDatasetDialog?: boolean): void {
|
||||||
|
this.scrollTop = document.getElementById('editor-form').scrollTop;
|
||||||
|
// return;
|
||||||
|
this.dmpService.createDmp(this.formGroup.getRawValue())
|
||||||
|
.pipe(takeUntil(this._destroyed))
|
||||||
|
.subscribe(
|
||||||
|
complete => {
|
||||||
|
this.formGroup.get('id').setValue(complete.id);
|
||||||
|
this.formGroup.get('modified').setValue(complete.modified);
|
||||||
|
this.hasChanges = false;
|
||||||
|
if (showAddDatasetDialog) {
|
||||||
|
this.addDatasetOpenDialog(complete);
|
||||||
|
}
|
||||||
|
if (addNew) {
|
||||||
|
this.onCallbackSuccessAddNew(complete);
|
||||||
|
}
|
||||||
|
else { this.onCallbackSuccess(complete) }
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
this.formGroup.get('status').setValue(DmpStatus.Draft);
|
||||||
|
this.onCallbackError(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// this.dmpService.createDmpWithDatasets(this.formGroup.getRawValue())
|
||||||
|
// .pipe(takeUntil(this._destroyed))
|
||||||
|
// .subscribe(
|
||||||
|
// complete => {
|
||||||
|
// if (showAddDatasetDialog) {
|
||||||
|
// this.addDatasetOpenDialog(complete);
|
||||||
|
// }
|
||||||
|
// else if (this.step < this.stepsBeforeDatasets) { this.onCallbackSuccess(complete) }
|
||||||
|
// else { this.onCallbackSuccess(complete, this.datasetId) }
|
||||||
|
// },
|
||||||
|
// error => {
|
||||||
|
// this.formGroup.get('status').setValue(DmpStatus.Draft);
|
||||||
|
// this.onCallbackError(error);
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
|
||||||
|
addDatasetOpenDialog(dmp: DmpModel) {
|
||||||
|
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||||
|
maxWidth: '500px',
|
||||||
|
restoreFocus: false,
|
||||||
|
data: {
|
||||||
|
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ADD-DATASET'),
|
||||||
|
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
||||||
|
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.NO'),
|
||||||
|
isDeleteConfirmation: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||||
|
if (result) {
|
||||||
|
// this.router.navigate(['datasets/new/' + id]);
|
||||||
|
this.addDataset();
|
||||||
|
} else {
|
||||||
|
dmp.id != null ? this.router.navigate(['/plans', 'edit', dmp.id]) : this.router.navigate(['/plans']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onCallbackSuccess(dmp?: DmpModel, datasetId?: string): void {
|
||||||
|
|
||||||
|
// On save keep editor position
|
||||||
|
this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
|
||||||
|
if (dmp) {
|
||||||
|
let dmpEditorModel: DmpEditorModel;
|
||||||
|
dmpEditorModel = new DmpEditorModel();
|
||||||
|
dmpEditorModel.grant = new GrantTabModel();
|
||||||
|
dmpEditorModel.project = new ProjectFormModel();
|
||||||
|
dmpEditorModel.funder = new FunderFormModel();
|
||||||
|
dmpEditorModel.extraProperties = new ExtraPropertiesFormModel();
|
||||||
|
dmpEditorModel.fromModel(dmp);
|
||||||
|
this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue()));
|
||||||
|
this.associatedUsers = dmp.associatedUsers;
|
||||||
|
this.people = dmp.users;
|
||||||
|
|
||||||
|
setTimeout(() => { this.formGroup = null; });
|
||||||
|
setTimeout(() => {
|
||||||
|
this.formGroup = dmpEditorModel.buildForm();
|
||||||
|
this.formGroup.valueChanges.pipe(takeUntil(this._destroyed))
|
||||||
|
.subscribe(x => {
|
||||||
|
this.formChanged();
|
||||||
|
});});
|
||||||
|
setTimeout(() => { document.getElementById('editor-form').scrollTop = this.scrollTop; });
|
||||||
|
this.saving = false;
|
||||||
|
this.isNew = false;
|
||||||
|
} else {
|
||||||
|
this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans']); });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uncomment to not keep editor position on save
|
||||||
|
// if (dmp.id != null) {
|
||||||
|
// datasetId ? this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans', 'edit', dmp.id], { queryParams: { dataset: datasetId } }); }) : this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans', 'edit', dmp.id]); })
|
||||||
|
// } else {
|
||||||
|
// this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans']); });
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
onCallbackError(error: any) {
|
||||||
|
this.uiNotificationService.snackBarNotification(error.error.message, SnackBarNotificationLevel.Error);
|
||||||
|
this.setErrorModel(error.error);
|
||||||
|
this.saving = false;
|
||||||
|
//this.validateAllFormFields(this.formGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setErrorModel(validationErrorModel: ValidationErrorModel) {
|
||||||
|
Object.keys(validationErrorModel).forEach(item => {
|
||||||
|
(<any>this.dmp.validationErrorModel)[item] = (<any>validationErrorModel)[item];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onCallbackSuccessAddNew(dmp?: DmpModel) {
|
||||||
|
// this.editDataset(dmp.id, true, this.isNew && !this.formGroup.get('datasets').value.length);
|
||||||
|
this.editDataset(dmp.id, true, false);
|
||||||
|
this.saving = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
editDataset(id: string, isNew: boolean, showModal:boolean = false) {
|
||||||
|
|
||||||
|
|
||||||
|
if(showModal){
|
||||||
|
const dialogRef = this.dialog.open(DmpToDatasetDialogComponent, {
|
||||||
|
width: '500px',
|
||||||
|
autoFocus: false,
|
||||||
|
restoreFocus: false,
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||||
|
if (result) {
|
||||||
|
if (isNew) {
|
||||||
|
this.router.navigate(['/datasets', 'new', id]);
|
||||||
|
} else {
|
||||||
|
this.router.navigate(['/datasets', 'edit', id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
if (isNew) {
|
||||||
|
this.router.navigate(['/datasets', 'new', id]);
|
||||||
|
} else {
|
||||||
|
this.router.navigate(['/datasets', 'edit', id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//checks if the dpm is valid not taking into account the datasets validity
|
||||||
|
private _isDMPDescriptionValid():boolean{
|
||||||
|
|
||||||
|
const form: FormGroup = this.formGroup;
|
||||||
|
if(form.controls){
|
||||||
|
return Object.keys(form.controls)
|
||||||
|
.map(controlName=>{//get validity of each control
|
||||||
|
if(controlName === 'datasets'){//we dont care if datasets are valid
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !form.get(controlName).invalid;//!! in case the control is disabled, we consider it valid
|
||||||
|
})
|
||||||
|
.reduce((isFormValid,isControlValid)=>{//aggregate validities
|
||||||
|
return isControlValid && isFormValid;
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private showValidationErrorsDialog(projectOnly?: boolean, errmess?: string[]) {
|
||||||
|
|
||||||
|
if(errmess){
|
||||||
|
|
||||||
|
const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, {
|
||||||
|
disableClose: true,
|
||||||
|
autoFocus: false,
|
||||||
|
restoreFocus: false,
|
||||||
|
data: {
|
||||||
|
errorMessages:errmess,
|
||||||
|
projectOnly: projectOnly
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, {
|
||||||
|
disableClose: true,
|
||||||
|
autoFocus: false,
|
||||||
|
restoreFocus: false,
|
||||||
|
data: {
|
||||||
|
formGroup: this.formGroup,
|
||||||
|
projectOnly: projectOnly
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private _buildDMPDescriptionErrorMessages(): string[]{//not including datasets
|
||||||
|
const errmess: string[] = [];
|
||||||
|
Object.keys(this.formGroup.controls).forEach(controlName=>{
|
||||||
|
if(controlName != 'datasets' && this.formGroup.get(controlName).invalid){
|
||||||
|
errmess.push(...this._buildErrorMessagesForAbstractControl(this.formGroup.get(controlName), controlName));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return errmess;
|
||||||
|
}
|
||||||
|
|
||||||
|
// takes as an input an abstract control and gets its error messages[]
|
||||||
|
private _buildErrorMessagesForAbstractControl(aControl: AbstractControl, controlName: string):string[]{
|
||||||
|
const errmess:string[] = [];
|
||||||
|
|
||||||
|
if(aControl.invalid){
|
||||||
|
|
||||||
|
if(aControl.errors){
|
||||||
|
//check if has placeholder
|
||||||
|
if( (<any>aControl).nativeElement !== undefined && (<any>aControl).nativeElement !== null){
|
||||||
|
const placeholder = this._getPlaceHolder(aControl);
|
||||||
|
if(placeholder){
|
||||||
|
controlName = placeholder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const errorMessage = this._getErrorMessage(aControl, controlName);
|
||||||
|
|
||||||
|
errmess.push(...errorMessage);
|
||||||
|
}
|
||||||
|
/*in case the aControl is FormControl then the it should have provided its error messages above.
|
||||||
|
No need to check case of FormControl below*/
|
||||||
|
|
||||||
|
if(aControl instanceof FormGroup){
|
||||||
|
|
||||||
|
const fg = aControl as FormGroup;
|
||||||
|
//check children
|
||||||
|
Object.keys(fg.controls).forEach(controlName=>{
|
||||||
|
errmess.push(...this._buildErrorMessagesForAbstractControl(fg.get(controlName), controlName));
|
||||||
|
});
|
||||||
|
}else if(aControl instanceof FormArray){
|
||||||
|
|
||||||
|
const fa = aControl as FormArray;
|
||||||
|
|
||||||
|
fa.controls.forEach((control,index)=>{
|
||||||
|
errmess.push(... this._buildErrorMessagesForAbstractControl(control, `${controlName} --> ${index+1}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return errmess;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getErrorMessage(formControl: AbstractControl, name: string): string[] {
|
||||||
|
const errors: string[] = [];
|
||||||
|
Object.keys(formControl.errors).forEach(key => {
|
||||||
|
if (key === 'required') { errors.push(this.language.instant(name + ": " + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.REQUIRED'))); }
|
||||||
|
// if (key === 'required') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + this.getPlaceHolder(formControl) + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.REQUIRED')); }
|
||||||
|
else if (key === 'email') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.EMAIL')); }
|
||||||
|
else if (key === 'min') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.MIN-VALUE', { 'min': formControl.getError('min').min })); }
|
||||||
|
else if (key === 'max') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.MAX-VALUE', { 'max': formControl.getError('max').max })); }
|
||||||
|
else { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + formControl.errors[key].message); }
|
||||||
|
});
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getPlaceHolder(formControl: any): string {
|
||||||
|
if (formControl.nativeElement.localName === 'input' || formControl.nativeElement.localName === 'textarea'
|
||||||
|
|| formControl.nativeElement.localName === 'richTextarea') {
|
||||||
|
return formControl.nativeElement.getAttribute('placeholder');
|
||||||
|
} else if (formControl.nativeElement.localName === 'mat-select') {
|
||||||
|
return formControl.nativeElement.getAttribute('placeholder');
|
||||||
|
} else if (formControl.nativeElement.localName === 'app-single-auto-complete') {
|
||||||
|
return (Array.from(formControl.nativeElement.firstChild.children).filter((x: any) => x.localName === 'input')[0] as any).getAttribute('placeholder');
|
||||||
|
} else if (formControl.nativeElement.localName === 'app-multiple-auto-complete') {
|
||||||
|
return (Array.from(formControl.nativeElement.firstChild.firstChild.firstChild.children).filter((x: any) => x.localName === 'input')[0] as any).getAttribute('placeholder');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filterProfiles(value: string): Observable<DatasetProfileModel[]> {
|
||||||
|
const request = new DataTableRequest<DatasetProfileCriteria>(null, null, { fields: ['+label'] });
|
||||||
|
const criteria = new DatasetProfileCriteria();
|
||||||
|
criteria.like = value;
|
||||||
|
request.criteria = criteria;
|
||||||
|
return this.dmpService.searchDMPProfiles(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
registerFormEventsForDmpBlueprint(): void {
|
||||||
|
this.formGroup.get('profile').valueChanges
|
||||||
|
.pipe(
|
||||||
|
takeUntil(this._destroyed))
|
||||||
|
.subscribe(Option => {
|
||||||
|
if (Option instanceof Object) {
|
||||||
|
this.selectedDmpBlueprintDefinition = Option.definition;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.selectedDmpBlueprintDefinition = null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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, 10, { fields: fields });
|
||||||
|
request.criteria = new DmpBlueprintCriteria();
|
||||||
|
return this.dmpProfileService.getPagedBlueprint(request).pipe(map(x => x.data));
|
||||||
|
}
|
||||||
|
|
||||||
|
getLanguageInfos(): LanguageInfo[] {
|
||||||
|
return this.languageInfoService.getLanguageInfoValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
getAssociates(): UserModel[] {
|
||||||
|
let associates: UserModel[];
|
||||||
|
if (this.formGroup.get('associatedUsers').value && this.formGroup.get('associatedUsers').value.length > 0) {
|
||||||
|
associates = [];
|
||||||
|
} else {
|
||||||
|
associates = this.associates;
|
||||||
|
}
|
||||||
|
//associates = (this.formGroup.get('researchers').value as any[]);
|
||||||
|
associates = associates.concat(this.formGroup.get('associatedUsers').value);
|
||||||
|
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[]> {
|
||||||
|
return this.externalSourcesService.searchDMPResearchers({ criteria: { name: value, like: null } });
|
||||||
|
}
|
||||||
|
|
||||||
|
addResearcher(event: MouseEvent) {
|
||||||
|
event.stopPropagation();
|
||||||
|
const dialogRef = this.dialog.open(AddResearcherComponent, {
|
||||||
|
data: this.formGroup.get('researchers')
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||||
|
if (result) {
|
||||||
|
const fullName = result.firstName + " " + result.lastName;
|
||||||
|
const newItem = {
|
||||||
|
label: null,
|
||||||
|
name: fullName,
|
||||||
|
id: null,
|
||||||
|
status: 0,
|
||||||
|
key: "Internal",
|
||||||
|
reference: result.reference
|
||||||
|
};
|
||||||
|
const researchersArray = this.formGroup.get('researchers').value || [];
|
||||||
|
researchersArray.push(newItem);
|
||||||
|
this.formGroup.get('researchers').setValue(researchersArray);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Organizations
|
||||||
|
showOrganizationCreator(): boolean {
|
||||||
|
return this.configurationService.allowOrganizationCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
filterOrganisations(value: string): Observable<ExternalSourceItemModel[]> {
|
||||||
|
return this.organizationService.searchGeneralOrganisations({ criteria: { labelLike: value } });
|
||||||
|
}
|
||||||
|
|
||||||
|
cantAddOrganizations(): boolean {
|
||||||
|
if (!isNullOrUndefined(this.formGroup.get('organizations'))) {
|
||||||
|
return this.formGroup.get('organiztions').disabled;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addOrganization(event: MouseEvent) {
|
||||||
|
event.stopPropagation();
|
||||||
|
const dialogRef = this.dialog.open(AddOrganizationComponent, {
|
||||||
|
data: this.formGroup.get('organisations')
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||||
|
if (result) {
|
||||||
|
const fullName = result.name;
|
||||||
|
const newItem = {
|
||||||
|
label: null,
|
||||||
|
name: fullName,
|
||||||
|
id: null,
|
||||||
|
status: 0,
|
||||||
|
key: "Internal",
|
||||||
|
reference: result.reference
|
||||||
|
};
|
||||||
|
const organizationsArray = this.formGroup.get('organisations').value || [];
|
||||||
|
organizationsArray.push(newItem);
|
||||||
|
this.formGroup.get('organisations').setValue(organizationsArray);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
showToggleButton() {
|
||||||
|
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, {
|
||||||
|
data: {
|
||||||
|
profiles: this.formGroup.get('profiles')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onRemoveTemplate(event) {
|
||||||
|
let found = false;
|
||||||
|
const profiles = this.formGroup.get('profiles').value;
|
||||||
|
this.formGroup.get('datasets')['controls'].forEach(element => {
|
||||||
|
if (element.get('profile').value.id === event.id) {
|
||||||
|
found = true;
|
||||||
|
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-REMOVE-TEMPLATE'), SnackBarNotificationLevel.Success);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (found) {
|
||||||
|
this.formGroup.get('profiles').setValue(profiles);
|
||||||
|
this.profilesAutoCompleteConfiguration = {
|
||||||
|
filterFn: this.filterProfiles.bind(this),
|
||||||
|
initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||||
|
displayFn: (item) => item['label'],
|
||||||
|
titleFn: (item) => item['label'],
|
||||||
|
subtitleFn: (item) => item['description'],
|
||||||
|
popupItemActionIcon: 'visibility'
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPreviewTemplate(event) {
|
||||||
|
const dialogRef = this.dialog.open(DatasetPreviewDialogComponent, {
|
||||||
|
width: '590px',
|
||||||
|
minHeight: '200px',
|
||||||
|
restoreFocus: false,
|
||||||
|
data: {
|
||||||
|
template: event
|
||||||
|
},
|
||||||
|
panelClass: 'custom-modalbox'
|
||||||
|
});
|
||||||
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||||
|
if (result) {
|
||||||
|
let profiles = this.formGroup.get('profiles').value;
|
||||||
|
profiles.push(event);
|
||||||
|
this.formGroup.get('profiles').setValue(profiles);
|
||||||
|
this.profilesAutoCompleteConfiguration = {
|
||||||
|
filterFn: this.filterProfiles.bind(this),
|
||||||
|
initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||||
|
displayFn: (item) => item['label'],
|
||||||
|
titleFn: (item) => item['label'],
|
||||||
|
subtitleFn: (item) => item['description'],
|
||||||
|
popupItemActionIcon: 'visibility'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onOptionSelected(){
|
||||||
|
try{
|
||||||
|
const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[];
|
||||||
|
const profileCounts: Map<String, number> = new Map<String, number>();
|
||||||
|
profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id): 0 ) + 1));
|
||||||
|
const duplicateProfiles = profiles.filter((value) => {
|
||||||
|
let isOk = profileCounts.get(value.id) > 1;
|
||||||
|
if (isOk) {
|
||||||
|
profileCounts.set(value.id, 0);
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
});
|
||||||
|
duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1));
|
||||||
|
profiles.sort((a,b)=> a.label.localeCompare(b.label));
|
||||||
|
}catch{
|
||||||
|
console.info('Could not sort Dataset Templates')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -57,6 +57,7 @@ import {
|
||||||
} from '../misc/dataset-description-form/components/form-progress-indication/form-progress-indication.module';
|
} from '../misc/dataset-description-form/components/form-progress-indication/form-progress-indication.module';
|
||||||
import {DatasetPreviewDialogComponent} from './dataset-preview/dataset-preview-dialog.component';
|
import {DatasetPreviewDialogComponent} from './dataset-preview/dataset-preview-dialog.component';
|
||||||
import {RichTextEditorModule} from "@app/library/rich-text-editor/rich-text-editor.module";
|
import {RichTextEditorModule} from "@app/library/rich-text-editor/rich-text-editor.module";
|
||||||
|
import { DmpEditorBlueprintComponent } from './dmp-editor-blueprint/dmp-editor-blueprint.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -110,7 +111,8 @@ import {RichTextEditorModule} from "@app/library/rich-text-editor/rich-text-edit
|
||||||
FundingInfoComponent,
|
FundingInfoComponent,
|
||||||
DatasetInfoComponent,
|
DatasetInfoComponent,
|
||||||
LicenseInfoComponent,
|
LicenseInfoComponent,
|
||||||
DatasetPreviewDialogComponent
|
DatasetPreviewDialogComponent,
|
||||||
|
DmpEditorBlueprintComponent
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
DmpInvitationDialogComponent,
|
DmpInvitationDialogComponent,
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { DmpOverviewComponent } from './overview/dmp-overview.component';
|
||||||
import { DmpCloneComponent } from './clone/dmp-clone.component';
|
import { DmpCloneComponent } from './clone/dmp-clone.component';
|
||||||
import { AuthGuard } from '@app/core/auth-guard.service';
|
import { AuthGuard } from '@app/core/auth-guard.service';
|
||||||
import { CanDeactivateGuard } from '@app/library/deactivate/can-deactivate.guard';
|
import { CanDeactivateGuard } from '@app/library/deactivate/can-deactivate.guard';
|
||||||
|
import { DmpEditorBlueprintComponent } from './dmp-editor-blueprint/dmp-editor-blueprint.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
|
@ -74,9 +75,19 @@ const routes: Routes = [
|
||||||
// breadcrumbs: 'new'
|
// breadcrumbs: 'new'
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
|
// {
|
||||||
|
// path: 'new',
|
||||||
|
// component: DmpEditorComponent,
|
||||||
|
// canActivate: [AuthGuard],
|
||||||
|
// data: {
|
||||||
|
// breadcrumbs: 'new',
|
||||||
|
// title: 'GENERAL.TITLES.DMP-NEW'
|
||||||
|
// },
|
||||||
|
// canDeactivate:[CanDeactivateGuard]
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
path: 'new',
|
path: 'new',
|
||||||
component: DmpEditorComponent,
|
component: DmpEditorBlueprintComponent,
|
||||||
canActivate: [AuthGuard],
|
canActivate: [AuthGuard],
|
||||||
data: {
|
data: {
|
||||||
breadcrumbs: 'new',
|
breadcrumbs: 'new',
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
<div class="funding-info">
|
<div class="funding-info">
|
||||||
<form *ngIf="grantformGroup" [formGroup]="grantformGroup">
|
<form *ngIf="grantformGroup" [formGroup]="grantformGroup">
|
||||||
<div class="col-12 intro">
|
<!-- <div class="col-12 intro">
|
||||||
{{'DMP-EDITOR.FUNDING-INFO.INTRO' | translate}}
|
{{'DMP-EDITOR.FUNDING-INFO.INTRO' | translate}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 card">
|
<div class="col-12 card"> -->
|
||||||
<!-- Funder Field -->
|
<!-- Funder Field -->
|
||||||
<div class="row">
|
<!-- <div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="heading">2.1 {{'DMP-EDITOR.FIELDS.FUNDING-ORGANIZATIONS' | translate}}*</div>
|
<div class="heading">2.1 {{'DMP-EDITOR.FIELDS.FUNDING-ORGANIZATIONS' | translate}}*</div>
|
||||||
<div class="hint">
|
<div class="hint">
|
||||||
<!-- <div class="pb-1">{{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}</div> -->
|
<div class="pb-1">{{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}</div>
|
||||||
<div class="pb-1">{{'DMP-EDITOR.FIELDS.FUNDER-HINT' | translate}}</div>
|
<div class="pb-1">{{'DMP-EDITOR.FIELDS.FUNDER-HINT' | translate}}</div>
|
||||||
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
|
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
|
||||||
</div>
|
</div> -->
|
||||||
<div class="funder-form">
|
<div class="funder-form" *ngIf="type == 1">
|
||||||
<div *ngIf="!isCreateNewFunder">
|
<div *ngIf="!isCreateNewFunder">
|
||||||
<mat-form-field appearance="outline">
|
<mat-form-field appearance="outline">
|
||||||
<app-single-auto-complete required='true' [formControl]="funderFormGroup.get('existFunder')" placeholder="{{'DMP-EDITOR.FIELDS.FUNDER' | translate}}" [configuration]="funderAutoCompleteConfiguration">
|
<app-single-auto-complete required='true' [formControl]="funderFormGroup.get('existFunder')" placeholder="{{'DMP-EDITOR.FIELDS.FUNDER' | translate}}" [configuration]="funderAutoCompleteConfiguration">
|
||||||
|
@ -38,7 +38,6 @@
|
||||||
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<!-- Toggle Between Add Funder or Use Existing -->
|
<!-- Toggle Between Add Funder or Use Existing -->
|
||||||
<div class="col d-flex">
|
<div class="col d-flex">
|
||||||
<div class="row" *ngIf="showToggleButton()">
|
<div class="row" *ngIf="showToggleButton()">
|
||||||
|
@ -52,17 +51,19 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<!-- </div>
|
||||||
|
</div> -->
|
||||||
<!-- Grant field -->
|
<!-- Grant field -->
|
||||||
<div class="row">
|
<!-- <div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="heading">2.2 {{'DMP-EDITOR.FIELDS.GRANTS' | translate}}*</div>
|
<div class="heading">2.2 {{'DMP-EDITOR.FIELDS.GRANTS' | translate}}*</div>
|
||||||
<div class="hint">
|
<div class="hint">
|
||||||
<!-- <div class="pb-1">{{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}</div> -->
|
<div class="pb-1">{{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}</div>
|
||||||
<div class="pb-1">{{'DMP-EDITOR.FIELDS.GRANTS-HINT' | translate}}</div>
|
<div class="pb-1">{{'DMP-EDITOR.FIELDS.GRANTS-HINT' | translate}}</div>
|
||||||
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
|
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
|
||||||
</div>
|
</div> -->
|
||||||
<div class="grant-form">
|
<div class="grant-form" *ngIf="type == 2">
|
||||||
<div *ngIf="!isCreateNew">
|
<div *ngIf="!isCreateNew">
|
||||||
<mat-form-field appearance="outline">
|
<mat-form-field appearance="outline">
|
||||||
<app-single-auto-complete required='true' [formControl]="grantformGroup.get('existGrant')" placeholder="{{'DMP-EDITOR.FIELDS.GRANT' | translate}}" [configuration]="grantAutoCompleteConfiguration">
|
<app-single-auto-complete required='true' [formControl]="grantformGroup.get('existGrant')" placeholder="{{'DMP-EDITOR.FIELDS.GRANT' | translate}}" [configuration]="grantAutoCompleteConfiguration">
|
||||||
|
@ -107,18 +108,18 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<!-- </div>
|
||||||
</div>
|
</div> -->
|
||||||
<!-- Project field-->
|
<!-- Project field-->
|
||||||
<div class="row">
|
<!-- <div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="heading">2.3 {{'DMP-EDITOR.FIELDS.PROJECT' | translate}}</div>
|
<div class="heading">2.3 {{'DMP-EDITOR.FIELDS.PROJECT' | translate}}</div>
|
||||||
<div class="hint">
|
<div class="hint">
|
||||||
<!-- <div class="pb-1">{{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}</div> -->
|
<div class="pb-1">{{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}</div>
|
||||||
<div class="pb-1">{{'DMP-EDITOR.FIELDS.PROJECT-HINT' | translate}}</div>
|
<div class="pb-1">{{'DMP-EDITOR.FIELDS.PROJECT-HINT' | translate}}</div>
|
||||||
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
|
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
|
||||||
</div>
|
</div> -->
|
||||||
<div class="project-form">
|
<div class="project-form" *ngIf="type == 3">
|
||||||
<div *ngIf="!isCreateNewProject">
|
<div *ngIf="!isCreateNewProject">
|
||||||
<mat-form-field appearance="outline">
|
<mat-form-field appearance="outline">
|
||||||
<app-single-auto-complete [formControl]="projectFormGroup.get('existProject')" placeholder="{{'DMP-EDITOR.FIELDS.PROJECT' | translate}}" [configuration]="projectAutoCompleteConfiguration">
|
<app-single-auto-complete [formControl]="projectFormGroup.get('existProject')" placeholder="{{'DMP-EDITOR.FIELDS.PROJECT' | translate}}" [configuration]="projectAutoCompleteConfiguration">
|
||||||
|
@ -162,9 +163,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<!-- </div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
<!-- </div> -->
|
||||||
</form>
|
</form>
|
||||||
<!-- <button (click)="consoleForm()" type="button">consoleForm</button> -->
|
<!-- <button (click)="consoleForm()" type="button">consoleForm</button> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -28,6 +28,8 @@ export class FundingInfoComponent extends BaseComponent implements OnInit {
|
||||||
@Input() isClone: boolean = false;
|
@Input() isClone: boolean = false;
|
||||||
@Input() isNewVersion: boolean;
|
@Input() isNewVersion: boolean;
|
||||||
|
|
||||||
|
@Input() type: number;
|
||||||
|
|
||||||
@Input() formGroup: FormGroup;
|
@Input() formGroup: FormGroup;
|
||||||
@Input() grantformGroup: FormGroup;
|
@Input() grantformGroup: FormGroup;
|
||||||
@Input() projectFormGroup: FormGroup;
|
@Input() projectFormGroup: FormGroup;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<a mat-button class="buttonNav navbar-button" routerLink="/plans">{{'NAV-BAR.DMPS' | translate}}</a>
|
<a mat-button class="buttonNav navbar-button" routerLink="/plans">{{'NAV-BAR.DMPS' | translate}}</a>
|
||||||
<a mat-button class="buttonNav navbar-button" routerLink="/datasets">{{'NAV-BAR.DATASETS' | translate}}</a>
|
<a mat-button class="buttonNav navbar-button" routerLink="/datasets">{{'NAV-BAR.DATASETS' | translate}}</a>
|
||||||
<a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button" routerLink="/users">{{'NAV-BAR.USERS' | translate}}</a>
|
<a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button" routerLink="/users">{{'NAV-BAR.USERS' | translate}}</a>
|
||||||
<a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button" routerLink="/dmp-profiles">{{'NAV-BAR.DMP-PROFILES' |
|
<a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button" routerLink="/dmp-profiles">{{'NAV-BAR.DMP-BLUEPRINTS' |
|
||||||
translate}}</a>
|
translate}}</a>
|
||||||
<a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button" routerLink="/dataset-profiles">{{'NAV-BAR.DATASETS-ADMIN'
|
<a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button" routerLink="/dataset-profiles">{{'NAV-BAR.DATASETS-ADMIN'
|
||||||
| translate}}</a>
|
| translate}}</a>
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
<!-- Admin -->
|
<!-- Admin -->
|
||||||
<!-- <a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button"
|
<!-- <a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button"
|
||||||
routerLink="/users">{{'NAV-BAR.USERS' | translate}}</a>
|
routerLink="/users">{{'NAV-BAR.USERS' | translate}}</a>
|
||||||
<a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button" routerLink="/dmp-profiles">{{'NAV-BAR.DMP-PROFILES' |
|
<a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button" routerLink="/dmp-profiles">{{'NAV-BAR.DMP-BLUEPRINTS' |
|
||||||
translate}}</a>
|
translate}}</a>
|
||||||
<a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button" routerLink="/dataset-profiles">{{'NAV-BAR.DATASETS-ADMIN'
|
<a *ngIf="isAdmin()" mat-button class="buttonNav navbar-button" routerLink="/dataset-profiles">{{'NAV-BAR.DATASETS-ADMIN'
|
||||||
| translate}}</a> -->
|
| translate}}</a> -->
|
||||||
|
|
Loading…
Reference in New Issue