# Conflicts:
#	dmp-frontend/src/app/app.module.ts
#	dmp-frontend/src/app/services/data-management-plan/data-management-plan.service.ts
dmp-editor
Diamantis Tziotzios 5 years ago
commit 68dddddf45

1
.gitignore vendored

@ -34,3 +34,4 @@ temp/
*.jar
*.lst
dmp-frontend/.vscode/
*.docx

@ -40,7 +40,9 @@ public class DMPDaoImpl extends DatabaseAccess<DMP> implements DMPDao {
if (criteria.getProjects() != null && !criteria.getProjects().isEmpty())
query.where(((builder, root) -> root.get("project").in(criteria.getProjects())));
if (!criteria.getAllVersions())
query.initSubQuery(String.class).where((builder, root) -> builder.equal(root.get("version"), query.<String>subQueryMax((builder1, externalRoot, nestedRoot) -> builder1.equal(externalRoot.get("groupId"), nestedRoot.get("groupId")), Arrays.asList(new SelectionField(FieldSelectionType.FIELD, "version")), String.class)));
query.initSubQuery(String.class).where((builder, root) -> builder.equal(root.get("version"),
query.<String>subQueryMax((builder1, externalRoot, nestedRoot) -> builder1.equal(externalRoot.get("groupId"),
nestedRoot.get("groupId")), Arrays.asList(new SelectionField(FieldSelectionType.FIELD, "version")), String.class)));
if (criteria.getGroupIds() != null && !criteria.getGroupIds().isEmpty())
query.where((builder, root) -> root.get("groupId").in(criteria.getGroupIds()));
query.where((builder, root) -> builder.notEqual(root.get("status"), DMP.DMPStatus.DELETED.getValue()));

@ -15,11 +15,13 @@ import java.util.stream.Collectors;
@NamedEntityGraphs({
@NamedEntityGraph(
name = "datasetListingModel",
attributeNodes = {@NamedAttributeNode("services"), @NamedAttributeNode(value = "datasetDataRepositories", subgraph = "datasetDataRepositories"), @NamedAttributeNode("datasetExternalDatasets"), @NamedAttributeNode("registries"),
attributeNodes = {@NamedAttributeNode("services"), @NamedAttributeNode(value = "datasetDataRepositories", subgraph = "datasetDataRepositories"),
@NamedAttributeNode(value = "datasetExternalDatasets", subgraph = "datasetExternalDatasets"), @NamedAttributeNode("registries"),
@NamedAttributeNode(value = "dmp", subgraph = "dmp"), @NamedAttributeNode("profile"), @NamedAttributeNode("creator")},
subgraphs = {
@NamedSubgraph(name = "dmp", attributeNodes = {@NamedAttributeNode("creator"), @NamedAttributeNode("users"), @NamedAttributeNode("project"), @NamedAttributeNode("organisations")}),
@NamedSubgraph(name = "datasetDataRepositories", attributeNodes = {@NamedAttributeNode("dataRepository")})
@NamedSubgraph(name = "datasetDataRepositories", attributeNodes = {@NamedAttributeNode("dataRepository")}),
@NamedSubgraph(name = "datasetExternalDatasets", attributeNodes = {@NamedAttributeNode("externalDataset")})
}),
@NamedEntityGraph(

@ -72,7 +72,6 @@ public class DevelDatabaseConfiguration {
properties.setProperty("hibernate.c3p0.maxPoolSize", "70");
properties.setProperty("hibernate.c3p0.timeout", "5000");
properties.setProperty("hibernate.connection.release_mode", "after_transaction");
//properties.setProperty("hibernate.connection.provider_class", "org.hibernate.c3p0.internal.C3P0ConnectionProvider");
return properties;
}
}

@ -44,19 +44,15 @@ public class Admin extends BaseController {
@Transactional
@RequestMapping(method = RequestMethod.POST, value = {"/admin/addDmp/{id}"}, consumes = "application/json", produces = "application/json")
public ResponseEntity<ResponseItem<UUID>> updateDmp(@PathVariable String id, @RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) {
//this.getLoggerService().info(principal, "Admin Edited Dataset Profile");
eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(profile, getApiContext());
eu.eudat.data.entities.DatasetProfile datasetprofile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id));
datasetprofile.setDefinition(modelDefinition.getDefinition());
this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(datasetprofile);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<UUID>().status(ApiMessageCode.NO_MESSAGE));
}
@RequestMapping(method = RequestMethod.GET, value = {"/admin/get/{id}"}, produces = "application/json")
public ResponseEntity<ResponseItem<DatasetProfile>> get(@PathVariable String id, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) {
//this.getLoggerService().info(principal, "Admin Open Dataset Profile");
eu.eudat.data.entities.DatasetProfile profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id));
eu.eudat.models.data.admin.composite.DatasetProfile datasetprofile = AdminManager.generateDatasetProfileModel(profile);
datasetprofile.setLabel(profile.getLabel());
@ -65,7 +61,6 @@ public class Admin extends BaseController {
@RequestMapping(method = RequestMethod.POST, value = {"/admin/preview"}, consumes = "application/json",produces = "application/json")
public ResponseEntity<ResponseItem<PagedDatasetProfile>> getPreview(@RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) {
//this.getLoggerService().info(principal, "Admin Previewed Dataset Profile");
eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(profile, getApiContext());
eu.eudat.models.data.user.composite.DatasetProfile datasetProfile = UserManager.generateDatasetProfileModel(modelDefinition);
PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile();

@ -8,6 +8,7 @@ import eu.eudat.data.entities.DMP;
import eu.eudat.data.query.items.item.dmp.DataManagementPlanCriteriaRequest;
import eu.eudat.data.query.items.table.dmp.DataManagementPlanTableRequest;
import eu.eudat.logic.managers.DataManagementPlanManager;
import eu.eudat.logic.managers.DatasetManager;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.utilities.documents.helpers.FileEnvelope;
import eu.eudat.models.data.dmp.DataManagementPlan;
@ -19,6 +20,7 @@ import eu.eudat.models.data.security.Principal;
import eu.eudat.types.ApiMessageCode;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@ -28,6 +30,7 @@ import org.springframework.web.bind.annotation.*;
import javax.activation.MimetypesFileTypeMap;
import javax.validation.Valid;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@ -37,33 +40,36 @@ import java.util.UUID;
@RestController
@CrossOrigin
@RequestMapping(value = {"/api"})
@RequestMapping(value = {"/api/dmps/"})
public class DMPs extends BaseController {
private DynamicProjectConfiguration dynamicProjectConfiguration;
private Environment environment;
@Autowired
public DMPs(ApiContext apiContext, DynamicProjectConfiguration dynamicProjectConfiguration) {
public DMPs(ApiContext apiContext, DynamicProjectConfiguration dynamicProjectConfiguration, Environment environment) {
super(apiContext);
this.dynamicProjectConfiguration = dynamicProjectConfiguration;
this.environment = environment;
}
@Transactional
@RequestMapping(method = RequestMethod.GET, value = {"/dmps/{id}/unlock"}, produces = "application/json")
@RequestMapping(method = RequestMethod.GET, value = {"{id}/unlock"}, produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<DMP>> unlock(@PathVariable(value = "id") UUID id, Principal principal) throws Exception {
new DataManagementPlanManager().unlock(this.getApiContext(), id);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DMP>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Unlocked"));
}
@RequestMapping(method = RequestMethod.POST, value = {"/dmps/getPaged"}, consumes = "application/json", produces = "application/json")
@RequestMapping(method = RequestMethod.POST, value = {"/getPaged"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<DataTableData<DataManagementPlanListingModel>>> getPaged(@Valid @RequestBody DataManagementPlanTableRequest dataManagementPlanTableRequest, Principal principal) throws Exception {
DataTableData<DataManagementPlanListingModel> dataTable = new DataManagementPlanManager().getPaged(this.getApiContext(), dataManagementPlanTableRequest, principal);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DataTableData<DataManagementPlanListingModel>>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable));
}
@RequestMapping(method = RequestMethod.GET, value = {"/dmps/getSingle/{id}"}, produces = "application/json")
@RequestMapping(method = RequestMethod.GET, value = {"/getSingle/{id}"}, produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<DataManagementPlan>> getSingle(@PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException {
eu.eudat.models.data.dmp.DataManagementPlan dataManagementPlan = new DataManagementPlanManager().getSingle(this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), id, principal, this.dynamicProjectConfiguration);
@ -71,28 +77,28 @@ public class DMPs extends BaseController {
}
@Transactional
@RequestMapping(method = RequestMethod.POST, value = {"/dmps/createOrUpdate"}, consumes = "application/json", produces = "application/json")
@RequestMapping(method = RequestMethod.POST, value = {"/createOrUpdate"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<DMP>> createOrUpdate(@RequestBody eu.eudat.models.data.dmp.DataManagementPlan dataManagementPlan, Principal principal) throws Exception {
DataManagementPlanManager.createOrUpdate(this.getApiContext(), dataManagementPlan, principal);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DMP>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created"));
}
@RequestMapping(method = RequestMethod.POST, value = {"/dmps/new/{id}"}, consumes = "application/json", produces = "application/json")
@RequestMapping(method = RequestMethod.POST, value = {"/new/{id}"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<DMP>> newVersion(@PathVariable UUID id, @Valid @RequestBody eu.eudat.models.data.dmp.DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) throws Exception {
DataManagementPlanManager.newVersion(this.getApiContext(), id, dataManagementPlan, principal);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DMP>().status(ApiMessageCode.NO_MESSAGE));
}
@RequestMapping(method = RequestMethod.POST, value = {"/dmps/clone/{id}"}, consumes = "application/json", produces = "application/json")
@RequestMapping(method = RequestMethod.POST, value = {"/clone/{id}"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<DMP>> clone(@PathVariable UUID id, @RequestBody eu.eudat.models.data.dmp.DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) throws Exception {
DataManagementPlanManager.clone(this.getApiContext(), id, dataManagementPlan, principal);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DMP>().status(ApiMessageCode.NO_MESSAGE));
}
@RequestMapping(method = RequestMethod.POST, value = {"/dmps/get"}, consumes = "application/json", produces = "application/json")
@RequestMapping(method = RequestMethod.POST, value = {"/get"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<List<DataManagementPlan>>> getWithCriteria(@RequestBody DataManagementPlanCriteriaRequest dataManagementPlanCriteria, Principal principal) throws InstantiationException, IllegalAccessException {
List<DataManagementPlan> dataTable = new DataManagementPlanManager().getWithCriteria(this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), dataManagementPlanCriteria, principal);
@ -100,21 +106,21 @@ public class DMPs extends BaseController {
}
@Transactional
@RequestMapping(method = RequestMethod.DELETE, value = {"/dmps/delete/{id}"}, consumes = "application/json", produces = "application/json")
@RequestMapping(method = RequestMethod.DELETE, value = {"/delete/{id}"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<DMP>> delete(@PathVariable UUID id, Principal principal) {
DataManagementPlanManager.delete(this.getApiContext(), id);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DMP>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Successfully Deleted Dataset"));
}
@RequestMapping(method = RequestMethod.POST, value = {"/dmps/dynamic"}, consumes = "application/json", produces = "application/json")
@RequestMapping(method = RequestMethod.POST, value = {"/dynamic"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<List<Tuple<String, String>>>> getWithCriteria(@RequestBody RequestItem<DynamicFieldsCriteria> criteriaRequestItem, Principal principal) throws InstantiationException, IllegalAccessException {
List<Tuple<String, String>> dataTable = new DataManagementPlanManager().getDynamicFields(criteriaRequestItem.getCriteria().getId(), this.dynamicProjectConfiguration, criteriaRequestItem.getCriteria());
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<List<Tuple<String, String>>>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable));
}
@RequestMapping(method = RequestMethod.GET, value = {"/dmps/getXml/{id}"})
@RequestMapping(method = RequestMethod.GET, value = {"/getXml/{id}"})
public @ResponseBody
ResponseEntity<byte[]> getXml(@PathVariable String id) throws IllegalAccessException, IOException, InstantiationException {
FileEnvelope envelope = new DataManagementPlanManager().getXmlDocument(this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), id, this.getApiContext().getUtilitiesService().getVisibilityRuleService());
@ -134,5 +140,45 @@ public class DMPs extends BaseController {
HttpStatus.OK);
}
@RequestMapping(method = RequestMethod.GET, value = {"/getWord/{id}"})
public @ResponseBody
ResponseEntity<byte[]> getWordDocument(@PathVariable String id) throws IOException, IllegalAccessException, InstantiationException {
File file = new DataManagementPlanManager().getWordDocument(this.environment, this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), id, this.getApiContext().getUtilitiesService().getVisibilityRuleService());
InputStream resource = new FileInputStream(file);
System.out.println("Mime Type of " + file.getName() + " is " +
new MimetypesFileTypeMap().getContentType(file));
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentLength(file.length());
responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
responseHeaders.set("Content-Disposition", "attachment;filename=" + file.getName());
responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition");
responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type");
byte[] content = org.apache.poi.util.IOUtils.toByteArray(resource);
return new ResponseEntity<>(content,
responseHeaders,
HttpStatus.OK);
}
@RequestMapping(method = RequestMethod.GET, value = {"/getPDF/{id}"})
public @ResponseBody
ResponseEntity<byte[]> getPDFDocument(@PathVariable String id) throws IllegalAccessException, IOException, InstantiationException, InterruptedException {
File file = new DataManagementPlanManager().getWordDocument(this.environment, this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), id, this.getApiContext().getUtilitiesService().getVisibilityRuleService());
File pdffile = new DatasetManager().convertToPDF(file, environment, file.getName());
InputStream resource = new FileInputStream(pdffile);
System.out.println("Mime Type of " + file.getName() + " is " +
new MimetypesFileTypeMap().getContentType(file));
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentLength(pdffile.length());
responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
responseHeaders.set("Content-Disposition", "attachment;filename=" + pdffile.getName());
responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition");
responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type");
byte[] content = org.apache.poi.util.IOUtils.toByteArray(resource);
return new ResponseEntity<>(content,
responseHeaders,
HttpStatus.OK);
}
}

@ -68,7 +68,7 @@ public class DatasetProfileController extends BaseController {
public ResponseEntity<ResponseItem<eu.eudat.models.data.admin.composite.DatasetProfile>> clone(@PathVariable String id, @ClaimedAuthorities(claims = {ADMIN})Principal principal) {
eu.eudat.data.entities.DatasetProfile profile = new DatasetProfileManager().clone(this.getApiContext(), id);
eu.eudat.models.data.admin.composite.DatasetProfile datasetprofile = AdminManager.generateDatasetProfileModel(profile);
datasetprofile.setLabel(profile.getLabel());
datasetprofile.setLabel(profile.getLabel() + " new ");
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<eu.eudat.models.data.admin.composite.DatasetProfile>().payload(datasetprofile));
}

@ -28,10 +28,7 @@ import org.springframework.web.bind.annotation.*;
import javax.activation.MimetypesFileTypeMap;
import javax.transaction.Transactional;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.util.List;
import java.util.UUID;
@ -82,7 +79,7 @@ public class DatasetWizardController extends BaseController {
@RequestMapping(method = RequestMethod.GET, value = {"/getPDF/{id}"})
public @ResponseBody
ResponseEntity<byte[]> getWordDocument(@PathVariable String id) throws IllegalAccessException, IOException, InstantiationException, InterruptedException {
ResponseEntity<byte[]> getPDFDocument(@PathVariable String id) throws IllegalAccessException, IOException, InstantiationException, InterruptedException {
File file = new DatasetManager().getWordDocument(this.environment, this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), id, this.getApiContext().getUtilitiesService().getVisibilityRuleService());
File pdffile = new DatasetManager().convertToPDF(file, environment, file.getName());
InputStream resource = new FileInputStream(pdffile);

@ -44,13 +44,7 @@ public final class PrincipalArgumentResolver implements HandlerMethodArgumentRes
if (principal == null) throw new UnauthorisedException("Authentication Information Missing");
if (!claimList.contains(Authorities.ANONYMOUS) && !principal.isAuthorized(claimList))
throw new UnauthorisedException("You are not Authorized For this Action");
/*Principal principal1 = new Principal();
principal1.setId(UUID.fromString("46366b8a-a712-4e0c-a499-1a3a0f209325"));
principal1.setToken(UUID.fromString("19031e80-6534-4aa5-b68a-78e97042c968"));
principal1.setName("Ioannis Kalyvas");
principal1.setAvatarUrl("https://lh5.googleusercontent.com/-X65vX1QO_Ew/AAAAAAAAAAI/AAAAAAAAAAA/AAN31DU5lFIOwD_fZiYW96D410pn6v4E-Q/s96-c/photo.jpg");
principal1.setAuthorities(new HashSet<>(Arrays.asList(Authorities.ADMIN, Authorities.USER)));
principal1.setExpiresAt(addADay(new Date()));*/
return principal;
}

@ -17,6 +17,8 @@ import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.forms.VisibilityRuleService;
import eu.eudat.logic.utilities.builders.XmlBuilder;
import eu.eudat.logic.utilities.documents.helpers.FileEnvelope;
import eu.eudat.logic.utilities.documents.types.ParagraphStyle;
import eu.eudat.logic.utilities.documents.word.WordBuilder;
import eu.eudat.logic.utilities.documents.xml.ExportXmlBuilder;
import eu.eudat.models.HintedModelFactory;
import eu.eudat.models.data.datasetwizard.DatasetWizardModel;
@ -30,16 +32,18 @@ import eu.eudat.models.data.listingmodels.DatasetListingModel;
import eu.eudat.models.data.security.Principal;
import eu.eudat.models.data.user.composite.PagedDatasetProfile;
import eu.eudat.queryable.QueryableList;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.json.JSONObject;
import org.springframework.core.env.Environment;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.*;
import java.math.BigInteger;
import java.net.URL;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@ -81,6 +85,51 @@ public class DataManagementPlanManager {
return;
}
public File getWordDocument(Environment environment, DMPDao dmpRepository, String id, VisibilityRuleService visibilityRuleService) throws InstantiationException, IllegalAccessException, IOException {
WordBuilder wordBuilder = new WordBuilder();
DatasetWizardModel dataset = new DatasetWizardModel();
String fileUrl = environment.getProperty("configuration.h2020template");
InputStream is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream();
XWPFDocument document = new XWPFDocument(is);
eu.eudat.data.entities.DMP dmpEntity = dmpRepository.find(UUID.fromString(id));
wordBuilder.addParagraphContent(dmpEntity.getLabel(), document, ParagraphStyle.TITLE, BigInteger.ZERO);
wordBuilder.addParagraphContent(dmpEntity.getDescription(), document, ParagraphStyle.TEXT, BigInteger.ZERO);
wordBuilder.addParagraphContent("Organisations", document, ParagraphStyle.HEADER2, BigInteger.ZERO);
wordBuilder.addParagraphContent(dmpEntity.getOrganisations().stream().map(x -> x.getLabel()).collect(Collectors.joining(","))
, document, ParagraphStyle.TEXT, BigInteger.ZERO);
wordBuilder.addParagraphContent("Researchers", document, ParagraphStyle.HEADER2, BigInteger.ZERO);
wordBuilder.addParagraphContent(dmpEntity.getResearchers().stream().map(x -> x.getLabel()).collect(Collectors.joining(","))
, document, ParagraphStyle.TEXT, BigInteger.ZERO);
wordBuilder.addParagraphContent("Datasets", document, ParagraphStyle.TITLE, BigInteger.ZERO);
dmpEntity.getDataset().stream().forEach(datasetEntity -> {
Map<String, Object> properties = new HashMap<>();
if (datasetEntity.getProperties() != null) {
JSONObject jobject = new JSONObject(datasetEntity.getProperties());
properties = jobject.toMap();
}
wordBuilder.addParagraphContent("Title: " + datasetEntity.getLabel(), document, ParagraphStyle.HEADER1, BigInteger.ZERO);
wordBuilder.addParagraphContent(datasetEntity.getDescription(), document, ParagraphStyle.TEXT, BigInteger.ZERO);
wordBuilder.addParagraphContent("Dataset Description", document, ParagraphStyle.HEADER1, BigInteger.ZERO);
PagedDatasetProfile pagedDatasetProfile = new DatasetManager().getPagedProfile(dataset, datasetEntity);
visibilityRuleService.setProperties(properties);
visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules());
try {
wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService);
} catch (IOException e) {
e.printStackTrace();
}
});
File exportFile = new File(dmpEntity.getLabel() + ".docx");
FileOutputStream out = new FileOutputStream(exportFile);
document.write(out);
out.close();
return exportFile;
}
public eu.eudat.models.data.dmp.DataManagementPlan getSingle(DMPDao dmpsRepository, String id, Principal principal, DynamicProjectConfiguration dynamicProjectConfiguration) throws InstantiationException, IllegalAccessException {
DMP dataManagementPlanEntity = dmpsRepository.find(UUID.fromString(id));
if (dataManagementPlanEntity.getCreator().getId() != principal.getId() && dataManagementPlanEntity.getUsers().stream().filter(userInfo -> userInfo.getId() == principal.getId()).collect(Collectors.toList()).size() == 0)
@ -102,7 +151,7 @@ public class DataManagementPlanManager {
datamanagementPlan.getDynamicFields().forEach(item -> {
Map<String, String> properties = (Map<String, String>) dmpProperties.get(item.getId());
if (properties != null)
item.setValue(new Tuple<String, String>(properties.get("id"), properties.get("label")));
item.setValue(new Tuple<>(properties.get("id"), properties.get("label")));
});
return datamanagementPlan;
}

@ -24,6 +24,7 @@ import eu.eudat.models.data.security.Principal;
import eu.eudat.models.data.user.composite.PagedDatasetProfile;
import eu.eudat.queryable.QueryableList;
import org.apache.commons.io.IOUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.json.JSONObject;
import org.springframework.core.env.Environment;
import org.springframework.core.io.FileSystemResource;
@ -32,10 +33,9 @@ import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.*;
import java.net.URL;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@ -91,7 +91,7 @@ public class DatasetManager {
else
items.where((builder, root) -> root.get("id").in(new UUID[]{UUID.randomUUID()}));
}
QueryableList<eu.eudat.data.entities.Dataset> pagedItems = PaginationManager.applyPaging(items , datasetTableRequest);
QueryableList<eu.eudat.data.entities.Dataset> pagedItems = PaginationManager.applyPaging(items, datasetTableRequest);
DataTableData<DatasetListingModel> dataTable = new DataTableData<>();
CompletableFuture<List<DatasetListingModel>> itemsFuture = pagedItems.
@ -134,6 +134,9 @@ public class DatasetManager {
public File getWordDocument(Environment environment, DatasetDao datatasetRepository, String id, VisibilityRuleService visibilityRuleService) throws InstantiationException, IllegalAccessException, IOException {
WordBuilder wordBuilder = new WordBuilder();
DatasetWizardModel dataset = new DatasetWizardModel();
String fileUrl = environment.getProperty("configuration.h2020template");
InputStream is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream();
XWPFDocument document = new XWPFDocument(is);
eu.eudat.data.entities.Dataset datasetEntity = datatasetRepository.find(UUID.fromString(id), HintedModelFactory.getHint(DatasetWizardModel.class));
Map<String, Object> properties = new HashMap<>();
if (datasetEntity.getProperties() != null) {
@ -143,8 +146,12 @@ public class DatasetManager {
PagedDatasetProfile pagedDatasetProfile = getPagedProfile(dataset, datasetEntity);
visibilityRuleService.setProperties(properties);
visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules());
File file = wordBuilder.build(environment, pagedDatasetProfile, datasetEntity.getLabel(), visibilityRuleService);
return file;
wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService);
File exportFile = new File(datasetEntity.getLabel() + ".docx");
FileOutputStream out = new FileOutputStream(exportFile);
document.write(out);
out.close();
return exportFile;
}
public FileEnvelope getXmlDocument(DatasetDao datatasetRepository, String id, VisibilityRuleService visibilityRuleService) throws InstantiationException, IllegalAccessException, IOException {
@ -262,7 +269,6 @@ public class DatasetManager {
}
}
private static void createRegistriesIfTheyDontExist(RegistryDao registryDao, eu.eudat.data.entities.Dataset dataset) {
if (dataset.getRegistries() != null && !dataset.getRegistries().isEmpty()) {
for (eu.eudat.data.entities.Registry registry : dataset.getRegistries()) {

@ -0,0 +1,141 @@
package eu.eudat.logic.managers;
import eu.eudat.data.dao.entities.DatasetDao;
import eu.eudat.logic.services.forms.VisibilityRuleService;
import eu.eudat.logic.utilities.documents.helpers.FileEnvelope;
import eu.eudat.logic.utilities.documents.word.WordBuilder;
import eu.eudat.logic.utilities.documents.xml.ExportXmlBuilder;
import eu.eudat.models.HintedModelFactory;
import eu.eudat.models.data.datasetwizard.DatasetWizardModel;
import eu.eudat.models.data.user.composite.PagedDatasetProfile;
import org.apache.commons.io.IOUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.json.JSONObject;
import org.springframework.core.env.Environment;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.*;
import java.net.URL;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* Created by ikalyvas on 10/16/2018.
*/
public class DocumentManager {
public File getWordDocument(Environment environment, DatasetDao datatasetRepository, String id, VisibilityRuleService visibilityRuleService) throws InstantiationException, IllegalAccessException, IOException {
WordBuilder wordBuilder = new WordBuilder();
DatasetWizardModel dataset = new DatasetWizardModel();
String fileUrl = environment.getProperty("configuration.h2020template");
InputStream is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream();
XWPFDocument document = new XWPFDocument(is);
eu.eudat.data.entities.Dataset datasetEntity = datatasetRepository.find(UUID.fromString(id), HintedModelFactory.getHint(DatasetWizardModel.class));
Map<String, Object> properties = new HashMap<>();
if (datasetEntity.getProperties() != null) {
JSONObject jobject = new JSONObject(datasetEntity.getProperties());
properties = jobject.toMap();
}
PagedDatasetProfile pagedDatasetProfile = new DatasetManager().getPagedProfile(dataset, datasetEntity);
visibilityRuleService.setProperties(properties);
visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules());
wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService);
File exportFile = new File(dataset.getLabel() + ".docx");
FileOutputStream out = new FileOutputStream(exportFile);
document.write(out);
out.close();
return exportFile;
}
public FileEnvelope getXmlDocument(eu.eudat.data.entities.Dataset datasetEntity, String id, VisibilityRuleService visibilityRuleService) throws InstantiationException, IllegalAccessException, IOException {
ExportXmlBuilder xmlBuilder = new ExportXmlBuilder();
DatasetWizardModel dataset = new DatasetWizardModel();
Map<String, Object> properties = new HashMap<>();
if (datasetEntity.getProperties() != null) {
JSONObject jobject = new JSONObject(datasetEntity.getProperties());
properties = jobject.toMap();
}
PagedDatasetProfile pagedDatasetProfile = new DatasetManager().getPagedProfile(dataset, datasetEntity);
visibilityRuleService.setProperties(properties);
visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules());
File file = xmlBuilder.build(pagedDatasetProfile, visibilityRuleService);
FileEnvelope fileEnvelope = new FileEnvelope();
fileEnvelope.setFile(file);
fileEnvelope.setFilename(datasetEntity.getLabel());
return fileEnvelope;
}
public File convertToPDF(File file, Environment environment, String label) throws IOException, InterruptedException {
LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("file", new FileSystemResource(file));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.add("Content-disposition", "attachment; filename=" + label + ".docx");
headers.add("Content-type", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<LinkedMultiValueMap<String, Object>>(
map, headers);
Map queueResult = new RestTemplate().postForObject(
environment.getProperty("pdf.converter.url") +
"api/v1/", requestEntity, Map.class);
Map mediaResult = new RestTemplate().getForObject(environment.getProperty("pdf.converter.url") +
"/api/v1/" + queueResult.get("id"), Map.class);
System.out.println("Status: " + mediaResult.get("status"));
while (!mediaResult.get("status").equals("finished")) {
Thread.sleep(500);
mediaResult = new RestTemplate().getForObject(environment.getProperty("pdf.converter.url") +
"api/v1/" + queueResult.get("id"), Map.class);
System.out.println("Polling");
}
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new ByteArrayHttpMessageConverter());
HttpHeaders headers2 = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM));
HttpEntity<String> entity = new HttpEntity<String>(headers2);
ResponseEntity<byte[]> response = restTemplate.exchange(environment.getProperty("pdf.converter.url") +
mediaResult.get("result_url"), HttpMethod.GET, entity, byte[].class, "1");
UUID uuid = UUID.randomUUID();
File zip = new File(uuid + ".zip");
if (response.getStatusCode().equals(HttpStatus.OK)) {
FileOutputStream output = new FileOutputStream(zip);
IOUtils.write(response.getBody(), output);
}
return extractFromZip(zip, label + ".pdf");
}
private File extractFromZip(File file, String filename) throws IOException {
byte[] buffer = new byte[1024];
File newFile = new File(filename);
ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
ZipEntry zipEntry = zis.getNextEntry();
while (zipEntry != null) {
String zippedFileName = zipEntry.getName();
if (zippedFileName.equals("pdf")) {
FileOutputStream fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
zipEntry = zis.getNextEntry();
}
}
zis.closeEntry();
zis.close();
return newFile;
}
}

@ -27,6 +27,7 @@ import eu.eudat.logic.services.helpers.FileStorageService;
import java.io.IOException;
import java.text.ParseException;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -91,7 +92,7 @@ public class ProjectManager {
projects.add(project);
}
projects.sort(Comparator.comparing(x-> x.getLabel()));
return projects;
}

@ -10,6 +10,7 @@ import eu.eudat.logic.builders.model.models.DataTableDataBuilder;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.operations.AuthenticationServiceImpl;
import eu.eudat.logic.utilities.builders.XmlBuilder;
import eu.eudat.models.HintedModelFactory;
import eu.eudat.models.data.dmp.DataManagementPlan;
import eu.eudat.models.data.helpers.common.DataTableData;
import eu.eudat.models.data.login.Credentials;
@ -41,7 +42,7 @@ public class UserManager {
}
public static DataTableData<UserListingModel> getPaged(ApiContext apiContext, UserInfoTableRequestItem userInfoTableRequestItem) throws Exception {
QueryableList<eu.eudat.data.entities.UserInfo> users = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().getWithCriteria(userInfoTableRequestItem.getCriteria());
QueryableList<eu.eudat.data.entities.UserInfo> users = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().getWithCriteria(userInfoTableRequestItem.getCriteria()).withHint(HintedModelFactory.getHint(UserListingModel.class));
QueryableList<eu.eudat.data.entities.UserInfo> pagedUsers = PaginationManager.applyPaging(users, userInfoTableRequestItem);
List<UserListingModel> modelUsers = pagedUsers.select(item -> new UserListingModel().fromDataModel(item));

@ -1,9 +1,13 @@
package eu.eudat.logic.utilities.documents.word;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.logic.services.forms.VisibilityRuleService;
import eu.eudat.logic.utilities.documents.types.ParagraphStyle;
import eu.eudat.logic.utilities.documents.types.TextStyle;
import eu.eudat.logic.utilities.interfaces.ApplierWithValue;
import eu.eudat.models.data.components.commons.datafield.CheckBoxData;
import eu.eudat.models.data.components.commons.datafield.ComboBoxData;
import eu.eudat.models.data.user.components.datasetprofile.Field;
import eu.eudat.models.data.user.components.datasetprofile.FieldSet;
import eu.eudat.models.data.user.components.datasetprofile.Section;
@ -14,16 +18,9 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLvl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat;
import org.springframework.core.env.Environment;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -40,6 +37,7 @@ public class WordBuilder {
public WordBuilder() {
this.cTAbstractNum = CTAbstractNum.Factory.newInstance();
this.cTAbstractNum.setAbstractNumId(BigInteger.valueOf(1));
this.buildOptions();
}
private void buildOptions() {
@ -52,6 +50,8 @@ public class WordBuilder {
});
this.options.put(ParagraphStyle.TITLE, (mainDocumentPart, item) -> {
XWPFParagraph paragraph = mainDocumentPart.createParagraph();
paragraph.setStyle("Title");
paragraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = paragraph.createRun();
run.setText(item);
run.setBold(true);
@ -60,29 +60,29 @@ public class WordBuilder {
});
this.options.put(ParagraphStyle.HEADER1, (mainDocumentPart, item) -> {
XWPFParagraph paragraph = mainDocumentPart.createParagraph();
paragraph.setStyle("Heading1");
XWPFRun run = paragraph.createRun();
run.setText(item);
run.setBold(true);
run.setFontSize(12);
run.setUnderline(UnderlinePatterns.SINGLE);
return paragraph;
});
this.options.put(ParagraphStyle.HEADER2, (mainDocumentPart, item) -> {
XWPFParagraph paragraph = mainDocumentPart.createParagraph();
paragraph.setStyle("Heading2");
XWPFRun run = paragraph.createRun();
run.setText(item);
run.setBold(true);
run.setFontSize(12);
run.setUnderline(UnderlinePatterns.SINGLE);
return paragraph;
});
this.options.put(ParagraphStyle.HEADER3, (mainDocumentPart, item) -> {
XWPFParagraph paragraph = mainDocumentPart.createParagraph();
paragraph.setStyle("Heading3");
XWPFRun run = paragraph.createRun();
run.setText(item);
run.setBold(true);
run.setFontSize(11);
run.setUnderline(UnderlinePatterns.SINGLE);
return paragraph;
});
this.options.put(ParagraphStyle.FOOTER, (mainDocumentPart, item) -> {
@ -91,41 +91,37 @@ public class WordBuilder {
run.setText(item);
return paragraph;
});
this.options.put(ParagraphStyle.COMMENT, (mainDocumentPart, item) -> {
XWPFParagraph paragraph = mainDocumentPart.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText(item);
run.setItalic(true);
return paragraph;
});
}
public File build(Environment environment, PagedDatasetProfile pagedDatasetProfile, String label, VisibilityRuleService visibilityRuleService) throws IOException {
String fileUrl = environment.getProperty("configuration.h2020template");
InputStream is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream();
XWPFDocument document = new XWPFDocument(is);
this.buildOptions();
public XWPFDocument build(XWPFDocument document, PagedDatasetProfile pagedDatasetProfile, VisibilityRuleService visibilityRuleService) throws IOException {
createPages(pagedDatasetProfile.getPages(), document, true, visibilityRuleService);
XWPFAbstractNum abstractNum = new XWPFAbstractNum(cTAbstractNum);
XWPFNumbering numbering = document.createNumbering();
BigInteger abstractNumID = numbering.addAbstractNum(abstractNum);
this.numId = numbering.addNum(abstractNumID);
createPages(pagedDatasetProfile.getPages(), document, false, visibilityRuleService);
File exportFile = new File(label + ".docx");
FileOutputStream out = new FileOutputStream(exportFile);
document.write(out);
out.close();
return exportFile;
return document;
}
public void createPages(List<DatasetProfilePage> datasetProfilePages, XWPFDocument mainDocumentPart, Boolean createListing, VisibilityRuleService visibilityRuleService) {
//if (createListing) this.addListing(mainDocumentPart, 0, false, true);
datasetProfilePages.forEach(item -> {
createSections(item.getSections(), mainDocumentPart, ParagraphStyle.TITLE, 0, createListing, visibilityRuleService);
createSections(item.getSections(), mainDocumentPart, ParagraphStyle.HEADER1, 0, createListing, visibilityRuleService);
});
}
public void createSections(List<Section> sections, XWPFDocument mainDocumentPart, ParagraphStyle style, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService) {
if (createListing) this.addListing(mainDocumentPart, indent, false, true);
BigInteger listing = numId;
sections.forEach(section -> {
if (visibilityRuleService.isElementVisible(section.getId())) {
if (!createListing) {
XWPFParagraph paragraph = addParagraphContent(section.getTitle(), mainDocumentPart, style, listing);
XWPFParagraph paragraph = addParagraphContent(section.getNumbering() + " " + section.getTitle(), mainDocumentPart, style, numId);
CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl();
number.setVal(BigInteger.valueOf(indent));
}
@ -139,13 +135,17 @@ public class WordBuilder {
if (createListing) this.addListing(mainDocumentPart, indent, true, true);
compositeFields.forEach(compositeField -> {
if (visibilityRuleService.isElementVisible(compositeField.getId())) {
if (compositeField.getTitle() != null && !compositeField.getTitle().isEmpty() && !createListing) {
XWPFParagraph paragraph = addParagraphContent(compositeField.getTitle(), mainDocumentPart, ParagraphStyle.HEADER3, numId);
XWPFParagraph paragraph = addParagraphContent(compositeField.getNumbering() + " " + compositeField.getTitle(), mainDocumentPart, ParagraphStyle.HEADER3, numId);
CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl();
number.setVal(BigInteger.valueOf(indent));
}
createFields(compositeField.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService);
if (compositeField.getHasCommentField() && compositeField.getCommentFieldValue() != null && !compositeField.getCommentFieldValue().isEmpty() && !createListing) {
XWPFParagraph paragraph = addParagraphContent("Comment: " + compositeField.getCommentFieldValue(), mainDocumentPart, ParagraphStyle.COMMENT, numId);
CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl();
number.setVal(BigInteger.valueOf(indent));
}
}
});
}
@ -155,18 +155,23 @@ public class WordBuilder {
fields.forEach(field -> {
if (visibilityRuleService.isElementVisible(field.getId())) {
if (!createListing) {
XWPFParagraph paragraph = addParagraphContent(field.getValue() == null ? "" : field.getValue(), mainDocumentPart, ParagraphStyle.TEXT, numId);
CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl();
number.setVal(BigInteger.valueOf(indent));
try {
XWPFParagraph paragraph = addParagraphContent(this.formatter(field), mainDocumentPart, ParagraphStyle.TEXT, numId);
CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl();
number.setVal(BigInteger.valueOf(indent));
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
public XWPFParagraph addParagraphContent(String text, XWPFDocument mainDocumentPart, ParagraphStyle style, BigInteger numId) {
XWPFParagraph paragraph = this.options.get(style).apply(mainDocumentPart, text);
if (numId != null) paragraph.setNumID(numId);
if (numId != null) {
paragraph.setNumID(numId);
}
return paragraph;
}
@ -176,8 +181,6 @@ public class WordBuilder {
}
public void addListing(XWPFDocument document, int indent, Boolean question, Boolean hasIndication) {
//this.cTAbstractNum.setAbstractNumId(BigInteger.valueOf(indent));
CTLvl cTLvl = this.cTAbstractNum.addNewLvl();
String textLevel = "";
@ -186,28 +189,50 @@ public class WordBuilder {
}
if (question) {
cTLvl.addNewNumFmt().setVal(STNumberFormat.DECIMAL);
cTLvl.addNewLvlText().setVal("Q " + textLevel);
cTLvl.addNewStart().setVal(BigInteger.valueOf(1));
cTLvl.setIlvl(BigInteger.valueOf(indent));
} else if (!question && hasIndication) {
cTLvl.addNewNumFmt().setVal(STNumberFormat.DECIMAL);
cTLvl.addNewLvlText().setVal(textLevel);
cTLvl.addNewStart().setVal(BigInteger.valueOf(1));
cTLvl.setIlvl(BigInteger.valueOf(indent));
}
if (!question && !hasIndication) {
cTLvl.addNewNumFmt().setVal(STNumberFormat.NONE);
cTLvl.addNewLvlText().setVal("");
cTLvl.addNewStart().setVal(BigInteger.valueOf(1));
cTLvl.setIlvl(BigInteger.valueOf(indent));
}
}
/*if (this.numId == null) {
XWPFAbstractNum abstractNum = new XWPFAbstractNum(cTAbstractNum);
XWPFNumbering numbering = document.createNumbering();
BigInteger abstractNumID = numbering.addAbstractNum(abstractNum);
this.numId = numbering.addNum(abstractNumID);
}*/
public String formatter(Field field) throws IOException {
switch (field.getViewStyle().getRenderStyle()) {
case "combobox": {
String comboboxType = ((ComboBoxData) field.getData()).getType();
if (comboboxType.equals("autocomplete")) {
ObjectMapper mapper = new ObjectMapper();
if (field.getValue() == null) return null;
Map<String, String> map = mapper.readValue(field.getValue(), new TypeReference<Map<String, String>>() {
});
return map.get("label");
} else if (comboboxType.equals("wordlist")) {
ObjectMapper mapper = new ObjectMapper();
if (field.getValue() == null) return null;
Map<String, String> map = mapper.readValue(field.getValue(), new TypeReference<Map<String, String>>() {
});
return map.get("label");
}
}
case "booleanDecision":
if (field.getValue() != null && field.getValue().equals("true")) return "Yes";
else return "No";
case "radiobox":
return field.getValue();
case "checkBox":
CheckBoxData data = (CheckBoxData) field.getData();
if (field.getValue() == null || field.getValue().equals("false")) return null;
return data.getLabel();
case "freetext":
return field.getValue();
case "textarea":
return field.getValue();
}
return null;
}
}

@ -88,7 +88,6 @@ public class FieldSet implements Comparable, ViewStyleDefinition<eu.eudat.models
@Override
public eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.FieldSet toDatabaseDefinition(eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.FieldSet item) {
if (this.id == null || this.id.isEmpty()) this.id = "fieldSet_" + RandomStringUtils.random(5, true, true);
List<eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field> viewStylefields = new ModelBuilder().toViewStyleDefinition(this.fields, eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field.class);
item.setFields(viewStylefields);
item.setId(this.id);

@ -18,6 +18,7 @@ import java.util.List;
public class Field implements DatabaseViewStyleDefinition, XmlSerializable<Field> {
private String id;
private int ordinal;
private String numbering;
private ViewStyle viewStyle;
private DefaultValue defaultValue;
private Visibility visible;
@ -80,6 +81,14 @@ public class Field implements DatabaseViewStyleDefinition, XmlSerializable<Field
this.validations = validations;
}
public String getNumbering() {
return numbering;
}
public void setNumbering(String numbering) {
this.numbering = numbering;
}
@Override
public Element toXml(Document doc) {
Element rootElement = doc.createElement("field");
@ -103,6 +112,10 @@ public class Field implements DatabaseViewStyleDefinition, XmlSerializable<Field
validations.appendChild(validation);
}
Element numbering = doc.createElement("numbering");
numbering.setTextContent(this.numbering);
rootElement.appendChild(numbering);
rootElement.appendChild(validations);
rootElement.appendChild(defaultValue);
rootElement.appendChild(visibility);
@ -116,6 +129,7 @@ public class Field implements DatabaseViewStyleDefinition, XmlSerializable<Field
this.id = element.getAttribute("id");
this.ordinal = Integer.parseInt(element.getAttribute("ordinal"));
this.viewStyle = new ViewStyle();
Element viewStyle = (Element) XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "viewStyle");
@ -126,6 +140,9 @@ public class Field implements DatabaseViewStyleDefinition, XmlSerializable<Field
this.visible = new Visibility().fromXml(visibility);
Element numbering = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "numbering");
if (numbering != null) this.numbering = numbering.getTextContent();
Element dataElement = (Element) XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "data");
Element defaultValue = (Element) XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "defaultValue");

@ -15,6 +15,7 @@ public class FieldSet implements DatabaseViewStyleDefinition, XmlSerializable<Fi
private String id;
private int ordinal;
private List<Field> fields;
private String numbering;
private String title;
private String description;
private String extendedDescription;
@ -94,6 +95,14 @@ public class FieldSet implements DatabaseViewStyleDefinition, XmlSerializable<Fi
this.commentFieldValue = commentFieldValue;
}
public String getNumbering() {
return numbering;
}
public void setNumbering(String numbering) {
this.numbering = numbering;
}
@Override
public Element toXml(Document doc) {
Element fieldSet = doc.createElement("fieldSet");
@ -116,11 +125,16 @@ public class FieldSet implements DatabaseViewStyleDefinition, XmlSerializable<Fi
commentField.setAttribute("hasCommentField", "" + this.hasCommentField);
commentField.setAttribute("commentFieldValue", this.commentFieldValue);
Element numbering = doc.createElement("numbering");
numbering.setTextContent(this.numbering);
Element fieldsElement = doc.createElement("fields");
for (Field field : fields) {
field.setNumbering(this.numbering + "." + (this.fields.indexOf(field) + 1));
fieldsElement.appendChild(field.toXml(doc));
}
fieldSet.appendChild(numbering);
fieldSet.appendChild(commentField);
fieldSet.appendChild(fieldsElement);
fieldSet.appendChild(multiplicity);
@ -146,6 +160,9 @@ public class FieldSet implements DatabaseViewStyleDefinition, XmlSerializable<Fi
this.commentFieldValue = commentField.getAttribute("commentFieldValue");
Element fields = (Element) XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "fields");
Element numbering = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "numbering");
if (numbering != null) this.numbering = numbering.getTextContent();
if (fields != null) {
NodeList fieldElements = fields.getChildNodes();
for (int temp = 0; temp < fieldElements.getLength(); temp++) {

@ -1,7 +1,7 @@
package eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition;
import eu.eudat.logic.utilities.interfaces.XmlSerializable;
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;
@ -14,6 +14,7 @@ public class Section implements DatabaseViewStyleDefinition, XmlSerializable<Sec
private String id;
private int ordinal;
private boolean defaultVisibility;
private String numbering;
private String page;
private String title;
private String description;
@ -93,6 +94,14 @@ public class Section implements DatabaseViewStyleDefinition, XmlSerializable<Sec
this.extendedDescription = extendedDescription;
}
public String getNumbering() {
return numbering;
}
public void setNumbering(String numbering) {
this.numbering = numbering;
}
@Override
public Element toXml(Document doc) {
Element rootElement = doc.createElement("section");
@ -107,12 +116,16 @@ public class Section implements DatabaseViewStyleDefinition, XmlSerializable<Sec
Element extendedDescription = doc.createElement("extendedDescription");
extendedDescription.setTextContent(this.extendedDescription);
Element numbering = doc.createElement("numbering");
numbering.setTextContent(this.numbering);
Element title = doc.createElement("title");
title.setTextContent(this.title);
if (sections != null) {
Element sections = doc.createElement("sections");
for (Section section : this.sections) {
section.setNumbering(this.numbering + "." + (this.sections.indexOf(section) + 1));
sections.appendChild(section.toXml(doc));
}
rootElement.appendChild(sections);
@ -121,11 +134,13 @@ public class Section implements DatabaseViewStyleDefinition, XmlSerializable<Sec
if (this.fieldSets != null) {
Element formGroups = doc.createElement("fieldSets");
for (FieldSet fieldSet : this.fieldSets) {
fieldSet.setNumbering(this.numbering + "." + (this.fieldSets.indexOf(fieldSet) + 1));
formGroups.appendChild(fieldSet.toXml(doc));
}
rootElement.appendChild(formGroups);
}
rootElement.appendChild(numbering);
rootElement.appendChild(title);
rootElement.appendChild(extendedDescription);
rootElement.appendChild(description);
@ -147,6 +162,9 @@ public class Section implements DatabaseViewStyleDefinition, XmlSerializable<Sec
Element extendedDescription = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "extendedDescription");
if (extendedDescription != null) this.extendedDescription = extendedDescription.getTextContent();
Element numbering = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "numbering");
if (numbering != null) this.numbering = numbering.getTextContent();
Element title = XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "title");
if (title != null) this.title = title.getTextContent();

@ -1,7 +1,7 @@
package eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition;
import eu.eudat.logic.utilities.interfaces.XmlSerializable;
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;
@ -36,6 +36,7 @@ public class ViewStyleModel implements XmlSerializable<ViewStyleModel> {
Element sections = doc.createElement("sections");
Element pages = doc.createElement("pages");
for (Section section : this.sections) {
section.setNumbering("" + (this.sections.indexOf(section) + 1));
sections.appendChild(section.toXml(doc));
}

@ -20,6 +20,7 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin
private String value;
private ViewStyle viewStyle;
private String datatype;
private String numbering;
private int page;
private DefaultValue defaultValue;
private Multiplicity multiplicity;
@ -128,6 +129,13 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin
this.validations = eu.eudat.models.data.admin.components.datasetprofile.Field.ValidationType.fromIntegers(validations);
}
public String getNumbering() {
return numbering;
}
public void setNumbering(String numbering) {
this.numbering = numbering;
}
public Field cloneForMultiplicity(String key, Map<String, Object> properties) {
Field newField = new Field();
@ -160,6 +168,7 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin
this.id = item.getId();
this.ordinal = item.getOrdinal();
this.viewStyle = item.getViewStyle();
this.numbering = item.getNumbering();
this.data = item.getData();
this.defaultValue = item.getDefaultValue();
this.visible = item.getVisible();

@ -13,6 +13,7 @@ public class FieldSet implements Comparable, PropertiesModelBuilder, ViewStyleDe
private String id;
private Integer ordinal;
private String title;
private String numbering;
private String description;
private String extendedDescription;
private Multiplicity multiplicity;
@ -83,6 +84,14 @@ public class FieldSet implements Comparable, PropertiesModelBuilder, ViewStyleDe
return multiplicityItems;
}
public String getNumbering() {
return numbering;
}
public void setNumbering(String numbering) {
this.numbering = numbering;
}
public void setMultiplicityItems(List<FieldSet> multiplicityItems) {
this.multiplicityItems = multiplicityItems;
}
@ -126,6 +135,7 @@ public class FieldSet implements Comparable, PropertiesModelBuilder, ViewStyleDe
this.ordinal = item.getOrdinal();
this.title = item.getTitle();
this.description = item.getDescription();
this.numbering = item.getNumbering();
this.extendedDescription = item.getExtendedDescription();
this.hasCommentField = item.getHasCommentField();
this.multiplicity = item.getMultiplicity();

@ -13,6 +13,7 @@ public class Section implements Comparable, ViewStyleDefinition<eu.eudat.models.
private List<Section> sections;
private List<FieldSet> compositeFields;
private Boolean defaultVisibility;
private String numbering;
private String page;
private Integer ordinal;
private String id;
@ -85,6 +86,14 @@ public class Section implements Comparable, ViewStyleDefinition<eu.eudat.models.
this.ordinal = ordinal;
}
public String getNumbering() {
return numbering;
}
public void setNumbering(String numbering) {
this.numbering = numbering;
}
@Override
public eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Section toDatabaseDefinition(eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Section item) {
item.setDefaultVisibility(this.defaultVisibility);
@ -107,6 +116,7 @@ public class Section implements Comparable, ViewStyleDefinition<eu.eudat.models.
this.compositeFields = new ModelBuilder().fromViewStyleDefinition(item.getFieldSets(), FieldSet.class);
this.id = item.getId();
this.ordinal = item.getOrdinal();
this.numbering = item.getNumbering();
this.page = item.getPage();
this.sections = new ModelBuilder().fromViewStyleDefinition(item.getSections(), Section.class);
this.title = item.getTitle();

@ -122,6 +122,6 @@ public class UserListingModel implements DataModel<eu.eudat.data.entities.UserIn
@Override
public String getHint() {
return null;
return "userInfo";
}
}

@ -26,7 +26,7 @@ public abstract class FluentValidator<T> implements Validator {
@Override
public void validate(Object target, Errors errors) {
List<FluentValidatorResult> validatorResults = new LinkedList<>();
this.fluentValidatorBuilders.forEach(x-> validatorResults.addAll(x.validate(target)));
validatorResults.forEach(x-> errors.rejectValue(x.getField(),x.getError()));
//this.fluentValidatorBuilders.forEach(x-> validatorResults.addAll(x.validate(target)));
//validatorResults.forEach(x-> errors.rejectValue(x.getField(),x.getError()));
}
}

@ -79,7 +79,10 @@ const appRoutes: Routes = [
},
{
path: 'users',
loadChildren: './users/users.module#UsersModule'
loadChildren: './users/users.module#UsersModule',
data: {
breadcrumb: true
},
},
{
path: 'welcome',

@ -1,60 +1,72 @@
<div class="container" [formGroup]='form'>
<div class="container" *ngIf="form" [formGroup]='form'>
<mat-form-field class="full-width">
<input matInput formControlName="label" placeholder="{{'FORM.LABEL' | translate}}" required>
<input matInput formControlName="label" placeholder="{{'DYNAMIC-FORM.FIELDS.LABEL' | translate}}" required>
<mat-error *ngIf="form.get('label').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-horizontal-stepper [linear]="true" #stepper>
<mat-step>
<div class="panel-group">
<mat-expansion-panel *ngFor="let page of dataModel.pages; let i=index;" #panel>
<mat-expansion-panel-header>
<mat-panel-title *ngIf="form.get('pages').at(i).get('title').value && !panel.expanded">{{i +
1}}.{{form.get('pages').at(i).get('title').value}}</mat-panel-title>
<div class="btn-group pull-right">
<button type="button" class="btn btn-sm" style="margin-left:5px;" (click)="DeletePage(i);">
<span class="glyphicon glyphicon-erase"></span>
</button>
</div>
</mat-expansion-panel-header>
<div id="{{'p' + i}}" *ngIf="panel.expanded">
<div>
<app-page-form [form]="form.get('pages').at(i)" [dataModel]="page"></app-page-form>
<ng-template matStepLabel>{{'DATASET-PROFILE.PAGES-DESCRIPTION' | translate}}</ng-template>
<div>
<div class="panel-group">
<mat-expansion-panel *ngFor="let page of dataModel.pages; let i=index;" #panel>
<mat-expansion-panel-header>
<mat-panel-title *ngIf="form.get('pages').at(i).get('title').value && !panel.expanded">{{i +
1}}.{{form.get('pages').at(i).get('title').value}}</mat-panel-title>
<div class="btn-group pull-right">
<button type="button" class="btn btn-sm" style="margin-left:5px;" (click)="DeletePage(i);">
<span class="glyphicon glyphicon-erase"></span>
</button>
</div>
</mat-expansion-panel-header>
<div id="{{'p' + i}}" *ngIf="panel.expanded">
<div>
<app-page-form [form]="form.get('pages').at(i)" [dataModel]="page"></app-page-form>
</div>
</div>
</div>
</mat-expansion-panel>
</div>
<div style="margin-top:20px; padding-left: 15px;" class="row">
<button mat-button (click)="addPage()" style="cursor: pointer">
Add Page +
</button>
</mat-expansion-panel>
</div>
<div style="margin-top:20px; padding-left: 15px;" class="row">
<button mat-button (click)="addPage()" style="cursor: pointer">
{{'DYNAMIC-FORM.ACTIONS.ADD-PAGE' | translate}}
</button>
</div>
</div>
</mat-step>
<mat-step>
<ng-template matStepLabel>{{'DATASET-PROFILE.FORM-DESCRIPTION' | translate}}</ng-template>
<div>
<mat-expansion-panel *ngFor="let section of dataModel.sections; let i=index;" #panel>
<mat-expansion-panel-header>
<mat-panel-title *ngIf="form.get('sections').get(''+i).get('title').value && !panel.expanded">{{i + 1}}.
{{form.get('sections').get(''+i).get('title').value}}</mat-panel-title>
<div class="btn-group pull-right">
<button type="button" class="btn btn-sm" style="margin-left:5px;" (click)="DeleteSection(i);">
<span class="glyphicon glyphicon-erase"></span>
</button>
<div>
<mat-expansion-panel *ngFor="let section of dataModel.sections; let i=index;" #panel>
<mat-expansion-panel-header>
<mat-panel-title *ngIf="form.get('sections').get(''+i).get('title').value && !panel.expanded">{{i + 1}}.
{{form.get('sections').get(''+i).get('title').value}}</mat-panel-title>
<div class="btn-group pull-right">
<button type="button" class="btn btn-sm" style="margin-left:5px;" (click)="DeleteSection(i);">
<span class="glyphicon glyphicon-erase"></span>
</button>
</div>
</mat-expansion-panel-header>
<div id="{{'s' + i}}" *ngIf="panel.expanded">
<div>
<app-section-form [form]="form.get('sections').get(''+i)" [dataModel]="section" [indexPath]="'s' + i"></app-section-form>
</div>
</div>
</mat-expansion-panel-header>
<div id="{{'s' + i}}" *ngIf="panel.expanded">
<div>
<app-section-form [form]="form.get('sections').get(''+i)" [dataModel]="section" [indexPath]="'s' + i"></app-section-form>
</div>
</div>
</mat-expansion-panel>
</mat-expansion-panel>
</div>
<div style="margin-top:20px; padding-left: 15px;" class="row">
<button mat-button (click)="addSection()" style="cursor: pointer">
{{'DYNAMIC-FORM.ACTIONS.ADD-SECTION' | translate}}
</button>
</div>
</div>
<div style="margin-top:20px; padding-left: 15px;" class="row">
<button mat-button (click)="addSection()" style="cursor: pointer">
Add Section +
</button>
</mat-step>
<mat-step>
<ng-template matStepLabel>{{'DATASET-PROFILE.PREVIEW' | translate}}</ng-template>
<div *ngIf='this.isStepActive(2)'>
<app-dynamic-form *ngIf="dataWizardModel && previewerFormGroup" [form]="this.previewerFormGroup" [dataModel]="dataWizardModel"></app-dynamic-form>
</div>
</mat-step>
</mat-horizontal-stepper>
<button mat-button (click)="preview()">Preview</button>
<button mat-raised-button color="primary" type="button" (click)='onSubmit()' [disabled]="form.valid">Save</button>
<button mat-raised-button color="primary" type="button" (click)='onSubmit()' [disabled]="!form.valid">Save</button>
</div>

@ -2,14 +2,17 @@
import { DatasetProfileService } from '../../services/dataset-profile.service';
import { DatasetProfileModelAdmin } from '../../models/datasetProfileAdmin/DatasetProfileModelAdmin';
import { Page } from '../../models/datasetProfileAdmin/Page';
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { FormArray } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { DatasetProfileAdmin } from '../../services/datasetProfileAdmin/datasetProfileAfmin.service';
import { Section } from '../../models/datasetProfileAdmin/Section';
import { MatDialog } from '@angular/material';
import { MatDialog, MatHorizontalStepper, MatStepper } from '@angular/material';
import { DatasetProfilePreviewerComponent } from '../previewer/dataset-profile-previewer.component';
import { Observable } from 'rxjs';
import { DatasetWizardModel } from '../../models/datasets/DatasetWizardModel';
import { DatasetProfileDefinitionModel } from '../../models/DatasetProfileDefinitionModel';
@Component({
selector: 'app-form-component',
@ -18,16 +21,20 @@ import { DatasetProfilePreviewerComponent } from '../previewer/dataset-profile-p
styleUrls: ['./form.component.scss']
})
export class FormComponent implements OnInit {
export class FormComponent implements OnInit, AfterViewInit {
dataModel: DatasetProfileModelAdmin;
form: FormGroup;
previewerFormGroup: FormGroup;
private profileID: string;
private cloneId: string;
dataWizardModel: DatasetWizardModel;
@ViewChild('stepper') stepper: MatHorizontalStepper;
constructor(
public datasetprofileAdmin: DatasetProfileAdmin,
private datasetProfileService: DatasetProfileService,
private datasetProfileAdminService: DatasetProfileAdmin,
private route: ActivatedRoute,
private router: Router,
public dialog: MatDialog,
@ -36,19 +43,40 @@ export class FormComponent implements OnInit {
this.cloneId = route.snapshot.params['cloneid'];
}
ngAfterViewInit(): void {
console.log(this.stepper);
}
ngOnInit() {
this.dataModel = JsonSerializer.fromJSONObject(new DatasetProfileModelAdmin(), DatasetProfileModelAdmin);
this.form = this.dataModel.buildForm();
if (this.profileID) {
this.datasetProfileService.getDatasetProfileById(this.profileID).subscribe((data) => {
this.dataModel = JsonSerializer.fromJSONObject(data, DatasetProfileModelAdmin);
this.form = this.dataModel.buildForm();
this.form.valueChanges.subscribe(change => {
this.datasetProfileAdminService.preview(this.dataModel).subscribe(dataset => {
const datasetModel = new DatasetWizardModel();
datasetModel.datasetProfileDefinition = JsonSerializer.fromJSONObject(dataset, DatasetProfileDefinitionModel);
this.dataWizardModel = datasetModel;
this.previewerFormGroup = <FormGroup>this.dataWizardModel.buildForm().get('datasetProfileDefinition');
});
});
this.form.updateValueAndValidity();
});
} else if (this.cloneId) {
this.datasetprofileAdmin.clone(this.cloneId).subscribe((data) => {
this.dataModel = JsonSerializer.fromJSONObject(data, DatasetProfileModelAdmin);
this.form = this.dataModel.buildForm();
this.form.valueChanges.subscribe(change => {
this.datasetProfileAdminService.preview(this.dataModel).subscribe(dataset => {
const datasetModel = new DatasetWizardModel();
datasetModel.datasetProfileDefinition = JsonSerializer.fromJSONObject(dataset, DatasetProfileDefinitionModel);
this.dataWizardModel = datasetModel;
this.previewerFormGroup = <FormGroup>this.dataWizardModel.buildForm().get('datasetProfileDefinition');
});
});
this.form.updateValueAndValidity();
});
} else {
this.addSection();
@ -97,23 +125,16 @@ export class FormComponent implements OnInit {
if (this.profileID) {
this.updateForm(this.profileID, data).subscribe(() => {
this.router.navigate(['/datasetsProfiles']);
this.router.navigate(['/dataset-profile']);
});
} else {
this.createForm(data).subscribe(() => {
this.router.navigate(['/datasetsProfiles']);
this.router.navigate(['/dataset-profile']);
});
}
}
preview() {
const dialogRef = this.dialog.open(DatasetProfilePreviewerComponent, {
height: '355px',
width: '700px',
data: {
model: this.dataModel
}
});
isStepActive(step: number) {
return this.stepper && this.stepper.selectedIndex === step;
}
}

@ -12,6 +12,7 @@ import { DataSource } from '@angular/cdk/table';
import { DatasetListingModel } from '../../models/datasets/DatasetListingModel';
import { DataTableRequest } from '../../models/data-table/DataTableRequest';
import { FacetSearchCriteriaModel } from '../../models/facet-search/FacetSearchCriteriaModel';
import { IBreadCrumbComponent } from '../../shared/components/breadcrumb/definition/IBreadCrumbComponent';
@Component({
@ -21,7 +22,6 @@ import { FacetSearchCriteriaModel } from '../../models/facet-search/FacetSearchC
})
export class DatasetPublicListingComponent implements OnInit {
@ViewChild(MatPaginator) _paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
criteria: FacetSearchCriteriaModel;
@ -44,6 +44,7 @@ export class DatasetPublicListingComponent implements OnInit {
}
ngOnInit() {
this.route.params.subscribe(async (params: Params) => {
this.dmpId = params['dmpId'];
this.refresh();

@ -15,228 +15,243 @@
</button>
</div>
<div *ngIf="this.datasetProfileDefinitionModel || this.datasetWizardModel?.datasetProfileDefinition">
<button mat-raised-button color="primary" *ngIf="datasetWizardModel&&datasetWizardModel?.status != 1 && !viewOnly" style="margin-top: 15px;margin-bottom: 15px;margin-right: 15px;"
(click)="save();" type="button">{{ 'DATASET-WIZARD.ACTIONS.SAVE' | translate }}</button>
<button mat-raised-button color="primary" *ngIf="datasetWizardModel&&datasetWizardModel?.status != 1 && !viewOnly" style="margin-top: 15px;margin-bottom: 15px;margin-right: 15px;"
(click)="saveFinalize();" type="button">{{ 'DATASET-WIZARD.ACTIONS.SAVE-AND-FINALISE' | translate }}</button>
<button mat-raised-button color="primary" *ngIf="datasetWizardModel&&datasetWizardModel?.status != 1 && !viewOnly"
style="margin-top: 15px;margin-bottom: 15px;margin-right: 15px;" (click)="save();" type="button">{{
'DATASET-WIZARD.ACTIONS.SAVE' | translate }}</button>
<button mat-raised-button color="primary" *ngIf="datasetWizardModel&&datasetWizardModel?.status != 1 && !viewOnly"
style="margin-top: 15px;margin-bottom: 15px;margin-right: 15px;" (click)="saveFinalize();" type="button">{{
'DATASET-WIZARD.ACTIONS.SAVE-AND-FINALISE' | translate }}</button>
<button mat-raised-button color="primary" *ngIf="datasetWizardModel&&datasetWizardModel?.status == 1" style="margin-top: 15px;margin-bottom: 15px;margin-right: 15px;"
(click)="downloadPDF();" type="button">{{ 'DATASET-WIZARD.ACTIONS.DOWNLOAD-PDF' | translate }}</button>
<button mat-raised-button color="primary" *ngIf="datasetWizardModel&&datasetWizardModel?.status == 1" style="margin-top: 15px;margin-bottom: 15px;margin-right: 15px;"
(click)="downloadXML();" type="button">{{ 'DATASET-WIZARD.ACTIONS.DOWNLOAD-XML' | translate }}</button>
<div class="fill-space"></div>
<!-- <button mat-button (click)="redirectToProject()">
<mat-icon>arrow_right_alt</mat-icon>{{'DATASET-WIZARD.ACTIONS.GO-TO-PROJECT' | translate}}</button>
<button mat-button (click)="redirectToDmp()">
<mat-icon>arrow_right_alt</mat-icon>{{'DATASET-WIZARD.ACTIONS.GO-TO-DMP' | translate}}</button> -->
</div>
<mat-horizontal-stepper [linear]="isLinear" #stepper>
<mat-step [stepControl]="formGroup">
<form *ngIf="formGroup" [formGroup]="formGroup">
<app-single-auto-complete [required]="true" [reactiveFormControl]="formGroup.get('dmp')" placeholder="{{'DATASET-EDITOR.FIELDS.DMP' | translate}}"
[configuration]="dmpAutoCompleteConfiguration">
</app-single-auto-complete>
<ng-template matStepLabel>{{'DATASET-WIZARD.FIRST-STEP.TITLE' | translate}}</ng-template>
<mat-form-field formGroupName="profile">
<mat-select placeholder=" {{'DATASET-WIZARD.FIRST-STEP.PROFILE'| translate}}" [required]="true" formControlName="id">
<mat-option *ngFor="let profile of availableProfiles" [value]="profile.id">
{{profile.label}}
</mat-option>
</mat-select>
<mat-error *ngIf="baseErrorModel?.status">{{baseErrorModel['Criteria.status']}}</mat-error>
</mat-form-field>
<app-dataset-editor-component [formGroup]="formGroup"></app-dataset-editor-component>
<div class="navigation-buttons-container">
<button matStepperNext mat-raised-button style="float:right;" color="primary">{{'DATASET-WIZARD.ACTIONS.NEXT' |
translate}}
</button>
</div>
</form>
<div *ngIf="this.isActiveStep(0)">
<form *ngIf="formGroup" [formGroup]="formGroup">
<app-single-auto-complete [required]="true" [reactiveFormControl]="formGroup.get('dmp')" placeholder="{{'DATASET-EDITOR.FIELDS.DMP' | translate}}"
[configuration]="dmpAutoCompleteConfiguration">
</app-single-auto-complete>
<ng-template matStepLabel>{{'DATASET-WIZARD.FIRST-STEP.TITLE' | translate}}</ng-template>
<mat-form-field formGroupName="profile">
<mat-select placeholder=" {{'DATASET-WIZARD.FIRST-STEP.PROFILE'| translate}}" [required]="true" formControlName="id">
<mat-option *ngFor="let profile of availableProfiles" [value]="profile.id">
{{profile.label}}
</mat-option>
</mat-select>
<mat-error *ngIf="baseErrorModel?.status">{{baseErrorModel['Criteria.status']}}</mat-error>
</mat-form-field>
<app-dataset-editor-component [formGroup]="formGroup"></app-dataset-editor-component>
<div class="navigation-buttons-container">
<button matStepperNext mat-raised-button style="float:right;" color="primary">{{'DATASET-WIZARD.ACTIONS.NEXT' |
translate}}
</button>
</div>
</form>
</div>
</mat-step>
<mat-step [stepControl]="formGroup">
<form *ngIf="formGroup" [formGroup]="formGroup">
<ng-template matStepLabel>{{'DATASET-WIZARD.SECOND-STEP.TITLE' | translate}}</ng-template>
<div *ngIf="this.isActiveStep(1)">
<form *ngIf="formGroup" [formGroup]="formGroup">
<ng-template matStepLabel>{{'DATASET-WIZARD.SECOND-STEP.TITLE' | translate}}</ng-template>
<mat-card>
<mat-card-header>
<mat-card-title class="thick" *ngIf='!viewOnly'>
{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES' | translate}}
<button mat-raised-button color="primary" (click)="addDataRepository()">
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
</button>
</mat-card-title>
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('dataRepositories') && dataRepositoriesTemplate && externalSourcesConfiguration"
[options]="externalSourcesConfiguration.dataRepositories" placeholder="{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES' | translate}}"
[parentTemplate]='dataRepositoriesTemplate' [displayFunction]='dataRepositoryDisplayFunc' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc'
[formGroup]="formGroup.get('dataRepositories')" [viewOnly]='viewOnly' [autoCompleteConfiguration]="dataRepositoriesAutoCompleteConfiguration"
(onItemChange)="dataRepositoriesOnItemChange($event)">
</app-external-item-listing>
<mat-card>
<mat-card-header>
<mat-card-title class="thick" *ngIf='!viewOnly'>
{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES' | translate}}
<button mat-raised-button color="primary" (click)="addDataRepository()">
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
</button>
</mat-card-title>
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('dataRepositories') && dataRepositoriesTemplate && externalSourcesConfiguration"
[options]="externalSourcesConfiguration.dataRepositories" placeholder="{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES' | translate}}"
[parentTemplate]='dataRepositoriesTemplate' [displayFunction]='dataRepositoryDisplayFunc' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc'
[formGroup]="formGroup.get('dataRepositories')" [viewOnly]='viewOnly' [autoCompleteConfiguration]="dataRepositoriesAutoCompleteConfiguration"
(onItemChange)="dataRepositoriesOnItemChange($event)">
</app-external-item-listing>
<ng-template #dataRepositoriesTemplate let-suggestion let-i="index" let-callback="function">
<div class="col-md-2">
<p>
{{i+1}}) {{suggestion.get('label').value}}
</p>
</div>
<div class="col-md-8">
<mat-form-field>
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES-INFO' | translate}}" type="text" name="info"
[formControl]="suggestion.get('info')">
</mat-form-field>
</div>
<div class="col-md-2" *ngIf='!viewOnly'>
<button mat-button (click)="callback(i)">
<mat-icon>close</mat-icon>
</button>
</div>
</ng-template>
</mat-card>
<mat-card>
<mat-card-header>
<mat-card-title class="thick" *ngIf='!viewOnly'>
{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASETS' | translate}}
<button mat-raised-button color="primary" (click)="addExternalDataset()">
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
</button>
</mat-card-title>
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('externalDatasets') && externalDatasetsTemplate && externalSourcesConfiguration"
[options]="externalSourcesConfiguration.externalDatasets" placeholder="{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASETS' | translate}}"
[parentTemplate]='externalDatasetsTemplate' [displayFunction]='externalDatasetDisplayFunc' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc'
[formGroup]="formGroup.get('externalDatasets')" [viewOnly]='viewOnly' [autoCompleteConfiguration]="externalDatasetAutoCompleteConfiguration"
(onItemChange)="externalDatasetsOnItemChange($event)">
</app-external-item-listing>
<ng-template #dataRepositoriesTemplate let-suggestion let-i="index" let-callback="function">
<div class="col-md-2">
<p>
{{i+1}}) {{suggestion.get('label').value}}
</p>
</div>
<div class="col-md-8">
<mat-form-field>
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES-INFO' | translate}}" type="text" name="info"
[formControl]="suggestion.get('info')">
</mat-form-field>
</div>
<div class="col-md-2" *ngIf='!viewOnly'>
<button mat-button (click)="callback(i)">
<mat-icon>close</mat-icon>
</button>
</div>
</ng-template>
</mat-card>
<mat-card>
<mat-card-header>
<mat-card-title class="thick" *ngIf='!viewOnly'>
{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASETS' | translate}}
<button mat-raised-button color="primary" (click)="addExternalDataset()">
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
</button>
</mat-card-title>
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('externalDatasets') && externalDatasetsTemplate && externalSourcesConfiguration"
[options]="externalSourcesConfiguration.externalDatasets" placeholder="{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASETS' | translate}}"
[parentTemplate]='externalDatasetsTemplate' [displayFunction]='externalDatasetDisplayFunc' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc'
[formGroup]="formGroup.get('externalDatasets')" [viewOnly]='viewOnly' [autoCompleteConfiguration]="externalDatasetAutoCompleteConfiguration"
(onItemChange)="externalDatasetsOnItemChange($event)">
</app-external-item-listing>
<ng-template #externalDatasetsTemplate let-suggestion let-i="index" let-callback="function">
<div class="col-md-2">
<p>
{{i+1}}) {{suggestion.get('label').value}}
</p>
</div>
<div class="col-md-4">
<mat-form-field>
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASET-INFO' | translate}}" type="text" name="info"
[formControl]="suggestion.get('info')">
</mat-form-field>
</div>
<ng-template #externalDatasetsTemplate let-suggestion let-i="index" let-callback="function">
<div class="col-md-2">
<p>
{{i+1}}) {{suggestion.get('label').value}}
</p>
</div>
<div class="col-md-4">
<mat-form-field>
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASET-INFO' | translate}}" type="text" name="info"
[formControl]="suggestion.get('info')">
</mat-form-field>
</div>
<div class="col-md-4">
<mat-form-field>
<mat-select placeholder="{{'DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-DATASET-TYPE' | translate}}" [formControl]="suggestion.get('type')">
<mat-option [value]="0">{{'TYPES.EXTERNAL-DATASET-TYPE.SOURCE' | translate}}</mat-option>
<mat-option [value]="1">{{'TYPES.EXTERNAL-DATASET-TYPE.OUTPUT' | translate}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-2">
<button mat-button (click)="callback(i)" *ngIf='!viewOnly'>
<mat-icon>close</mat-icon>
</button>
</div>
</ng-template>
</mat-card>
<div class="col-md-4">
<mat-form-field>
<mat-select placeholder="{{'DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-DATASET-TYPE' | translate}}" [formControl]="suggestion.get('type')">
<mat-option [value]="0">{{'TYPES.EXTERNAL-DATASET-TYPE.SOURCE' | translate}}</mat-option>
<mat-option [value]="1">{{'TYPES.EXTERNAL-DATASET-TYPE.OUTPUT' | translate}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-2">
<button mat-button (click)="callback(i)" *ngIf='!viewOnly'>
<mat-icon>close</mat-icon>
</button>
</div>
</ng-template>
</mat-card>
<mat-card>
<mat-card-header>
<mat-card-title class="thick" *ngIf='!viewOnly'>
{{'DATASET-EDITOR.FIELDS.REGISTRIES' | translate}}
<button mat-raised-button color="primary" (click)="addRegistry()">
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
</button>
</mat-card-title>
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('registries') && registriesTemplate && externalSourcesConfiguration"
[options]="externalSourcesConfiguration.registries" placeholder="{{'DATASET-EDITOR.FIELDS.REGISTRIES' | translate}}"
[parentTemplate]='registriesTemplate' [displayFunction]='registriesDisplayFunc' [formGroup]="formGroup.get('registries')"
[viewOnly]='viewOnly' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc' [autoCompleteConfiguration]="registriesAutoCompleteConfiguration"
(onItemChange)="registriesOnItemChange($event)">
</app-external-item-listing>
<mat-card>
<mat-card-header>
<mat-card-title class="thick" *ngIf='!viewOnly'>
{{'DATASET-EDITOR.FIELDS.REGISTRIES' | translate}}
<button mat-raised-button color="primary" (click)="addRegistry()">
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
</button>
</mat-card-title>
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('registries') && registriesTemplate && externalSourcesConfiguration"
[options]="externalSourcesConfiguration.registries" placeholder="{{'DATASET-EDITOR.FIELDS.REGISTRIES' | translate}}"
[parentTemplate]='registriesTemplate' [displayFunction]='registriesDisplayFunc' [formGroup]="formGroup.get('registries')"
[viewOnly]='viewOnly' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc' [autoCompleteConfiguration]="registriesAutoCompleteConfiguration"
(onItemChange)="registriesOnItemChange($event)">
</app-external-item-listing>
<ng-template #registriesTemplate let-suggestion let-i="index" let-callback="function">
<div class="col-md-2">
<p>
{{i+1}}) {{suggestion.get('label').value}}
</p>
</div>
<div class="col-md-10">
<button mat-button (click)="callback(i)" *ngIf='!viewOnly'>
<mat-icon>close</mat-icon>
</button>
</div>
</ng-template>
</mat-card>
<ng-template #registriesTemplate let-suggestion let-i="index" let-callback="function">
<div class="col-md-2">
<p>
{{i+1}}) {{suggestion.get('label').value}}
</p>
</div>
<div class="col-md-10">
<button mat-button (click)="callback(i)" *ngIf='!viewOnly'>
<mat-icon>close</mat-icon>
</button>
</div>
</ng-template>
</mat-card>
<mat-card>
<mat-card-header>
<mat-card-title class="thick" *ngIf='!viewOnly'>
{{'DATASET-EDITOR.FIELDS.SERVICES' | translate}}
<button mat-raised-button color="primary" (click)="addService()">
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
</button>
</mat-card-title>
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('services') && servicesTemplate && externalSourcesConfiguration"
[options]="externalSourcesConfiguration.services" placeholder="{{'DATASET-EDITOR.FIELDS.SERVICES' | translate}}"
[parentTemplate]='servicesTemplate' [displayFunction]='servicesDisplayFunc' [formGroup]="formGroup.get('services')"
[viewOnly]='viewOnly' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc' [autoCompleteConfiguration]="servicesAutoCompleteConfiguration"
(onItemChange)="servicesOnItemChange($event)">
</app-external-item-listing>
<mat-card>
<mat-card-header>
<mat-card-title class="thick" *ngIf='!viewOnly'>
{{'DATASET-EDITOR.FIELDS.SERVICES' | translate}}
<button mat-raised-button color="primary" (click)="addService()">
{{'DATASET-EDITOR.FIELDS.CREATE'|translate}}
</button>
</mat-card-title>
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('services') && servicesTemplate && externalSourcesConfiguration"
[options]="externalSourcesConfiguration.services" placeholder="{{'DATASET-EDITOR.FIELDS.SERVICES' | translate}}"
[parentTemplate]='servicesTemplate' [displayFunction]='servicesDisplayFunc' [formGroup]="formGroup.get('services')"
[viewOnly]='viewOnly' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc' [autoCompleteConfiguration]="servicesAutoCompleteConfiguration"
(onItemChange)="servicesOnItemChange($event)">
</app-external-item-listing>
<ng-template #servicesTemplate let-suggestion let-i="index" let-callback="function">
<div class="col-md-2">
<p>
{{i+1}}) {{suggestion.get('label').value}}
</p>
</div>
<div class="col-md-10">
<button mat-button (click)="callback(i)" *ngIf='!viewOnly'>
<mat-icon>close</mat-icon>
</button>
</div>
</ng-template>
</mat-card>
<ng-template #servicesTemplate let-suggestion let-i="index" let-callback="function">
<div class="col-md-2">
<p>
{{i+1}}) {{suggestion.get('label').value}}
</p>
</div>
<div class="col-md-10">
<button mat-button (click)="callback(i)" *ngIf='!viewOnly'>
<mat-icon>close</mat-icon>
</button>
</div>
</ng-template>
</mat-card>
<mat-card>
<mat-card-header>
<mat-card-title class="thick">
{{'DATASET-EDITOR.FIELDS.TAGS' | translate}}
</mat-card-title>
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('tags') && tagsTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.tags"
placeholder="{{'DATASET-EDITOR.FIELDS.TAGS' | translate}}" [parentTemplate]='tagsTemplate' [displayFunction]='tagsDisplayFunc'
[formGroup]="formGroup.get('tags')" [viewOnly]='viewOnly' [subtitleFunction]='tagsDisplaySubtitleFunc'
[autoCompleteConfiguration]="tagsAutoCompleteConfiguration" (onItemChange)="tagsOnItemChange($event)">
</app-external-item-listing>
<mat-card>
<mat-card-header>
<mat-card-title class="thick">
{{'DATASET-EDITOR.FIELDS.TAGS' | translate}}
</mat-card-title>
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('tags') && tagsTemplate && externalSourcesConfiguration"
[options]="externalSourcesConfiguration.tags" placeholder="{{'DATASET-EDITOR.FIELDS.TAGS' | translate}}"
[parentTemplate]='tagsTemplate' [displayFunction]='tagsDisplayFunc' [formGroup]="formGroup.get('tags')"
[viewOnly]='viewOnly' [subtitleFunction]='tagsDisplaySubtitleFunc' [autoCompleteConfiguration]="tagsAutoCompleteConfiguration"
(onItemChange)="tagsOnItemChange($event)">
</app-external-item-listing>
<ng-template #tagsTemplate let-suggestion let-i="index" let-callback="function">
<div class="col-md-2">
<p>
{{i+1}}) {{suggestion.get('name').value}}
</p>
</div>
<div class="col-md-10">
<button mat-button (click)="callback(i)" *ngIf='!viewOnly'>
<mat-icon>close</mat-icon>
</button>
</div>
</ng-template>
</mat-card>
<ng-template #tagsTemplate let-suggestion let-i="index" let-callback="function">
<div class="col-md-2">
<p>
{{i+1}}) {{suggestion.get('name').value}}
</p>
</div>
<div class="col-md-10">
<button mat-button (click)="callback(i)" *ngIf='!viewOnly'>
<mat-icon>close</mat-icon>
</button>
</div>
</ng-template>
</mat-card>
<div class="navigation-buttons-container">
<button matStepperPrevious mat-raised-button color="primary">{{'DATASET-WIZARD.ACTIONS.BACK' | translate}}</button>
<button matStepperNext mat-raised-button color="primary" style="float:right;" (click)="getDefinition()">{{'DATASET-WIZARD.ACTIONS.NEXT'
| translate}}</button>
</div>
</form>
</div>
</mat-step>
<mat-step>
<div *ngIf="this.isActiveStep(2)">
<ng-template matStepLabel>{{'DATASET-WIZARD.THIRD-STEP.TITLE' | translate}}</ng-template>
<app-dynamic-form class="full-width" *ngIf="formGroup && datasetWizardModel && datasetWizardModel.datasetProfileDefinition"
[form]="this.formGroup.get('datasetProfileDefinition')" [dataModel]="datasetWizardModel"></app-dynamic-form>
<div class="navigation-buttons-container">
<button matStepperPrevious mat-raised-button color="primary">{{'DATASET-WIZARD.ACTIONS.BACK' | translate}}</button>
<button matStepperNext mat-raised-button color="primary" style="float:right;" (click)="getDefinition()">{{'DATASET-WIZARD.ACTIONS.NEXT'
<button style="margin-top:10px;" matStepperPrevious mat-raised-button color="primary">{{'DATASET-WIZARD.ACTIONS.BACK'
| translate}}</button>
</div>
</form>
</div>
</mat-step>
<mat-step>
<ng-template matStepLabel>{{'DATASET-WIZARD.THIRD-STEP.TITLE' | translate}}</ng-template>
<app-dynamic-form class="full-width" *ngIf="formGroup && datasetWizardModel && datasetWizardModel.datasetProfileDefinition"
[form]="this.formGroup.get('datasetProfileDefinition')" [dataModel]="datasetWizardModel"></app-dynamic-form>
<div class="navigation-buttons-container">
<button style="margin-top:10px;" matStepperPrevious mat-raised-button color="primary">{{'DATASET-WIZARD.ACTIONS.BACK'
| translate}}</button>
<div *ngIf="this.isActiveStep(3)">
<ng-template matStepLabel>{{'DATASET-WIZARD.FOURTH-STEP.TITLE' | translate}}</ng-template>
<app-dynamic-form-pending-questions-display class="full-width" *ngIf="formGroup && datasetWizardModel && datasetWizardModel.datasetProfileDefinition"
[form]="this.formGroup.get('datasetProfileDefinition')" [dataModel]="datasetWizardModel"></app-dynamic-form-pending-questions-display>
<div class="navigation-buttons-container">
<button style="margin-top:10px;" matStepperPrevious mat-raised-button color="primary">{{'DATASET-WIZARD.ACTIONS.BACK'
| translate}}</button>
</div>
</div>
</mat-step>
</mat-horizontal-stepper>

@ -6,7 +6,6 @@ import { JsonSerializer } from '../../utilities/JsonSerializer';
import { DataManagementPlanCriteria } from '../../models/criteria/data-management-plan/DataManagementPlanCriteria';
import { RequestItem } from '../../models/criteria/RequestItem';
import { DatasetService } from '../../services/dataset/dataset.service';
import { ExternalSourcesItemModel } from '../../models/external-sources/ExternalSourcesItemModel';
import { DatasetProfileModel } from '../../models/datasetprofile/DatasetProfileModel';
import { DatasetProfileDefinitionModel } from '../../models/DatasetProfileDefinitionModel';
import { DatasetWizardModel, DatasetStatus } from '../../models/datasets/DatasetWizardModel';
@ -16,9 +15,9 @@ import { DatasetWizardService } from '../../services/dataset-wizard/dataset-wiza
import { TranslateService } from '@ngx-translate/core';
import { ActivatedRoute, Router, Params } from '@angular/router';
import { Component, ViewChild, OnInit, AfterViewInit, ViewEncapsulation, TemplateRef, ChangeDetectionStrategy } from '@angular/core';
import { FormGroup, Validators, FormBuilder, FormArray } from '@angular/forms';
import { FormGroup, FormBuilder, FormArray } from '@angular/forms';
import * as FileSaver from 'file-saver';
import { MatPaginator, MatSort, MatSnackBar, MatStepper, MatDialog } from '@angular/material';
import { MatSnackBar, MatStepper, MatDialog } from '@angular/material';
import { ExternalDatasetCriteria } from '../../models/criteria/external-dataset/ExternalDatasetCriteria';
import { ExternalDatasetModel } from '../../models/external-dataset/ExternalDatasetModel';
import { RegistryCriteria } from '../../models/criteria/registry/RegistryCriteria';
@ -156,14 +155,55 @@ export class DatasetWizardComponent implements OnInit, AfterViewInit, IBreadCrum
loadDataOnStart: true
};
this.route.params.subscribe((params: Params) => {
this.itemId = params['id'];
const dmpId = params['dmpId'];
if (this.itemId != null) {
this.isNew = false;
this.datasetWizardService.getSingle(this.itemId).map(data => data as DatasetWizardModel)
.subscribe(data => {
this.datasetWizardModel = JsonSerializer.fromJSONObject(data, DatasetWizardModel);
const params = this.route.snapshot.params;
this.itemId = params['id'];
const dmpId = params['dmpId'];
if (this.itemId != null) {
this.isNew = false;
this.datasetWizardService.getSingle(this.itemId).map(data => data as DatasetWizardModel)
.subscribe(data => {
this.datasetWizardModel = JsonSerializer.fromJSONObject(data, DatasetWizardModel);
this.breadCrumbs = Observable.of([
{
parentComponentName: null,
label: 'Datasets',
url: '/datasets',
notFoundResolver: [
{
parentComponentName: null,
label: this.datasetWizardModel.dmp.project.label,
url: '/projects/edit/' + this.datasetWizardModel.dmp.project.id
},
{
parentComponentName: null,
label: this.datasetWizardModel.dmp.label,
url: '/dmps/edit/' + this.datasetWizardModel.dmp.id,
},
]
}]);
this.formGroup = this.datasetWizardModel.buildForm();
this.editMode = this.datasetWizardModel.status === DatasetStatus.Draft;
if (this.datasetWizardModel.status === 1) {
this.formGroup.disable();
this.viewOnly = true;
}
if (this.viewOnly) { this.formGroup.disable(); }
this.loadDatasetProfiles();
});
} else if (dmpId != null) {
this.isNew = true;
this.dataManagementPlanService.getSingle(dmpId).map(data => data as DataManagementPlanModel)
.subscribe(data => {
this.datasetWizardModel = new DatasetWizardModel();
setTimeout(() => {
this.datasetWizardModel.dmp = data;
this.formGroup = this.datasetWizardModel.buildForm();
this.editMode = this.datasetWizardModel.status === DatasetStatus.Draft;
if (this.datasetWizardModel.status === 1) {
this.formGroup.disable();
this.viewOnly = true;
}
this.loadDatasetProfiles();
this.breadCrumbs = Observable.of([
{
parentComponentName: null,
@ -179,65 +219,23 @@ export class DatasetWizardComponent implements OnInit, AfterViewInit, IBreadCrum
parentComponentName: null,
label: this.datasetWizardModel.dmp.label,
url: '/dmps/edit/' + this.datasetWizardModel.dmp.id,
},
]
}]
}]);
this.formGroup = this.datasetWizardModel.buildForm();
this.editMode = this.datasetWizardModel.status === DatasetStatus.Draft;
if (this.datasetWizardModel.status === 1) {
this.formGroup.disable();
this.viewOnly = true;
}
if (this.viewOnly) { this.formGroup.disable(); }
this.loadDatasetProfiles();
});
} else if (dmpId != null) {
this.isNew = true;
this.dataManagementPlanService.getSingle(dmpId).map(data => data as DataManagementPlanModel)
.subscribe(data => {
this.datasetWizardModel = new DatasetWizardModel();
setTimeout(() => {
this.datasetWizardModel.dmp = data;
this.formGroup = this.datasetWizardModel.buildForm();
this.editMode = this.datasetWizardModel.status === DatasetStatus.Draft;
if (this.datasetWizardModel.status === 1) {
this.formGroup.disable();
this.viewOnly = true;
}
this.loadDatasetProfiles();
this.breadCrumbs = Observable.of([
{
parentComponentName: null,
label: 'Datasets',
url: '/datasets',
notFoundResolver: [
{
parentComponentName: null,
label: this.datasetWizardModel.dmp.project.label,
url: '/projects/edit/' + this.datasetWizardModel.dmp.project.id
},
{
parentComponentName: null,
label: this.datasetWizardModel.dmp.label,
url: '/dmps/edit/' + this.datasetWizardModel.dmp.id,
}]
}]);
});
});
} else {
this.datasetWizardModel = new DatasetWizardModel();
this.formGroup = this.datasetWizardModel.buildForm();
this.editMode = this.datasetWizardModel.status === DatasetStatus.Draft;
if (this.datasetWizardModel.status === 1) {
this.formGroup.disable();
this.viewOnly = true;
}
if (this.viewOnly) { this.formGroup.disable(); }
this.formGroup.get('dmp').valueChanges.subscribe(x => {
this.loadDatasetProfiles();
});
} else {
this.datasetWizardModel = new DatasetWizardModel();
this.formGroup = this.datasetWizardModel.buildForm();
this.editMode = this.datasetWizardModel.status === DatasetStatus.Draft;
if (this.datasetWizardModel.status === 1) {
this.formGroup.disable();
this.viewOnly = true;
}
});
if (this.viewOnly) { this.formGroup.disable(); }
this.formGroup.get('dmp').valueChanges.subscribe(x => {
this.loadDatasetProfiles();
});
}
}
ngAfterViewInit() {
@ -491,4 +489,8 @@ export class DatasetWizardComponent implements OnInit, AfterViewInit, IBreadCrum
this.viewOnly = true;
this.formGroup.disable();
}
isActiveStep(index: number) {
return this.stepper.selectedIndex === index;
}
}

@ -49,7 +49,9 @@ export const DatasetRoutes: Routes = [
{
path: 'public',
component: DatasetPublicListingComponent,
//canActivate: [AuthGuard],
data: {
breadcrumb: false
}
},
{
path: 'dmp/:dmpId',

@ -1,27 +1,28 @@
<div class="project-editor">
<form *ngIf="formGroup" (ngSubmit)="formSubmit()" [formGroup]="formGroup">
<form *ngIf="formGroup" (ngSubmit)="formSubmit()" [formGroup]="formGroup">
<mat-form-field class="full-width">
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.NAME' | translate}}" type="text" name="label" formControlName="label"
required>
<mat-error *ngIf="formGroup.get('label').errors?.backendError">{{baseErrorModel.label}}</mat-error>
<mat-error *ngIf="formGroup.get('label').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.NAME' | translate}}" type="text" name="label" formControlName="label"
required>
<mat-error *ngIf="formGroup.get('label').errors?.backendError">{{baseErrorModel.label}}</mat-error>
<mat-error *ngIf="formGroup.get('label').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.URI' | translate}}" type="text" name="uri" formControlName="uri">
<mat-error *ngIf="formGroup.get('uri').errors?.backendError">{{baseErrorModel.uri}}</mat-error>
<mat-error *ngIf="formGroup.get('uri').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.URI' | translate}}" type="text" name="uri" formControlName="uri">
<mat-error *ngIf="formGroup.get('uri').errors?.backendError">{{baseErrorModel.uri}}</mat-error>
<mat-error *ngIf="formGroup.get('uri').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
<textarea matInput class="description-area" placeholder="{{'DATASET-EDITOR.FIELDS.DESCRIPTION' | translate}}" formControlName="description"></textarea>
<mat-error *ngIf="formGroup.get('description').errors?.backendError">{{errorModel.description}}</mat-error>
<mat-error *ngIf="formGroup.get('description').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
<textarea matInput class="description-area" placeholder="{{'DATASET-EDITOR.FIELDS.DESCRIPTION' | translate}}"
formControlName="description"></textarea>
<mat-error *ngIf="formGroup.get('description').errors?.backendError">{{errorModel.description}}</mat-error>
<mat-error *ngIf="formGroup.get('description').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</form>
<!-- <div *ngIf="formGroup"> {{ formGroup.value | json }}</div> -->
</form>
<!-- <div *ngIf="formGroup"> {{ formGroup.value | json }}</div> -->
</div>

@ -36,9 +36,6 @@ export class DatasetEditorComponent implements AfterViewInit {
// filteredServices: ExternalSourcesItemModel[];
constructor(
private datasetService: DatasetService,
private externalSourcesService: ExternalSourcesService,
private route: ActivatedRoute,
public snackBar: MatSnackBar,
public router: Router,
public language: TranslateService,

@ -1,5 +1,5 @@
<div class="container-fluid">
<h3>{{titlePrefix}} {{'DATASET-LISTING.TITLE' | translate}}</h3>
<h3>{{titlePrefix}} {{'DMP-PROFILE-LISTING.TITLE' | translate}}</h3>
<app-dmp-profile-criteria-component></app-dmp-profile-criteria-component>
@ -11,19 +11,19 @@
<!-- Column Definition: Name -->
<ng-container cdkColumnDef="label">
<mat-header-cell *matHeaderCellDef mat-sort-header="label">{{'DATASET-LISTING.COLUMNS.NAME' | translate}}</mat-header-cell>
<mat-header-cell *matHeaderCellDef mat-sort-header="label">{{'DMP-PROFILE-LISTING.COLUMNS.NAME' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.label}}</mat-cell>
</ng-container>
<!-- Column Definition: status -->
<ng-container cdkColumnDef="status">
<mat-header-cell *matHeaderCellDef mat-sort-header="status">{{'DATASET-LISTING.COLUMNS.STATUS' | translate}}</mat-header-cell>
<mat-header-cell *matHeaderCellDef mat-sort-header="status">{{'DMP-PROFILE-LISTING.COLUMNS.STATUS' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.status}}</mat-cell>
</ng-container>
<!-- Column Definition: Created -->
<ng-container cdkColumnDef="created">
<mat-header-cell *matHeaderCellDef mat-sort-header="created">{{'DATASET-LISTING.COLUMNS.CREATED' | translate}}</mat-header-cell>
<mat-header-cell *matHeaderCellDef mat-sort-header="created">{{'DMP-PROFILE-LISTING.COLUMNS.CREATED' | translate}}</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.created | date:'shortDate'}}</mat-cell>
</ng-container>
@ -41,4 +41,4 @@
<button mat-fab class="mat-fab-bottom-right" color="primary" [routerLink]="['/dmp-profiles/new'] ">
<mat-icon class="mat-24">add</mat-icon>
</button>
</div>
</div>

@ -34,6 +34,12 @@
<button mat-menu-item (click)="downloadXml(this.dataManagementPlan.id)">
<mat-icon>save_alt</mat-icon>{{'DMP-LISTING.ACTIONS.DOWNLOAD-XML' | translate}}
</button>
<button mat-menu-item (click)="downloadDocx(this.dataManagementPlan.id)">
<mat-icon>save_alt</mat-icon>{{'DMP-LISTING.ACTIONS.DOWNLOAD-DOCX' | translate}}
</button>
<button mat-menu-item (click)="downloadPDF(this.dataManagementPlan.id)">
<mat-icon>save_alt</mat-icon>{{'DMP-LISTING.ACTIONS.DOWNLOAD-PDF' | translate}}
</button>
</mat-menu>
<div>
<button mat-icon-button type="button" [matMenuTriggerFor]="actionsMenu">
@ -133,8 +139,8 @@
translate}}</button>
<button *ngIf="this.formGroup.enabled" mat-raised-button color="primary" type="submit">{{'DMP-EDITOR.ACTIONS.SAVE'
| translate}}</button>
<button *ngIf="dataManagementPlan.lockable && this.formGroup.enabled" type="button" mat-raised-button
color="primary" (click)="saveAndFinalize()">{{'DMP-EDITOR.ACTIONS.FINALISE'
<button *ngIf="dataManagementPlan.lockable && this.formGroup.enabled" type="button" mat-raised-button color="primary"
(click)="saveAndFinalize()">{{'DMP-EDITOR.ACTIONS.FINALISE'
| translate}}</button>
<button *ngIf="!isNew && this.formGroup.enabled" mat-raised-button color="primary" type="button" (click)="openConfirm(formGroup.get('label').value, formGroup.get('id').value)">{{'DMP-EDITOR.ACTIONS.DELETE'
| translate}}</button>

@ -343,6 +343,24 @@ export class DataManagementPlanEditorComponent implements AfterViewInit, IBreadC
});
}
downloadDocx(id: string) {
this.dataManagementPlanService.downloadDocx(id).subscribe(response => {
const blob = new Blob([response.body], { type: 'application/octet-stream' });
const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
});
}
downloadPDF(id: string) {
this.dataManagementPlanService.downloadPDF(id).subscribe(response => {
const blob = new Blob([response.body], { type: 'application/octet-stream' });
const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
});
}
getFilenameFromContentDispositionHeader(header: string): string {
const regex: RegExp = new RegExp(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/g);

@ -3,4 +3,4 @@
<!-- <input type="checkbox" formControlName="value"> -->
</div>
<!-- label="{{field.data.label}}" formControlName="form.get('value').value"-->
<!-- label="{{field.data.label}}" formControlName="form.get('value').value"-->

@ -10,8 +10,12 @@ import { Component, Input, ViewEncapsulation, OnInit } from '@angular/core';
],
encapsulation: ViewEncapsulation.None
})
export class DynamicFieldCheckBoxComponent {
export class DynamicFieldCheckBoxComponent implements OnInit {
@Input() field: Field;
@Input() form: FormGroup;
ngOnInit(): void {
if (this.form.get('value').value === null) { this.form.get('value').patchValue(false); }
}
}

@ -1,9 +1,9 @@
<div [formGroup]="form">
<mat-form-field>
<mat-select formControlName="value" [required]="field.validationRequired">
<mat-option *ngFor="let opt of field.data.options" [value]="opt.value">{{opt.label}}</mat-option>
</mat-select>
<mat-error *ngIf="form.get('value').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<mat-form-field>
<mat-select formControlName="value" [required]="field.validationRequired">
<mat-option *ngFor="let opt of field.data.options" [value]="assign(opt)">{{opt.label}}</mat-option>
</mat-select>
<mat-error *ngIf="form.get('value').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</div>

@ -17,4 +17,13 @@ export class DynamicFieldDropdownComponent implements OnInit {
ngOnInit() {
}
assign(item: any) {
if (!item) { return null; }
return this.transform(item);
}
transform(item: any) {
if (typeof item === 'string') { return JSON.parse(item); } else { return JSON.stringify(item); }
}
}

@ -1,67 +1,73 @@
<div *ngIf="form && field" [id]="field.id" [formGroup]="form" [ngSwitch]="field.viewStyle.renderStyle">
<!-- <h5 *ngIf="field.title">{{field.title}}</h5> -->
<!-- <h5 *ngIf="field.title">{{field.title}}</h5> -->
<div [class.content-left-margin]="field.title">
<h5 *ngIf="field.description">{{field.description}}</h5>
<h5 *ngIf="field.extendedDescription" class="field-extended-desc">
<i>{{field.extendedDescription}}</i>
</h5>
<div [class.content-left-margin]="field.title">
<h5 *ngIf="field.description">{{field.description}}</h5>
<h5 *ngIf="field.extendedDescription" class="field-extended-desc">
<i>{{field.extendedDescription}}</i>
</h5>
<div *ngSwitchCase="'freetext'">
<mat-form-field>
<input matInput formControlName="value" placeholder="{{field.data.label}}" [required]="field.validationRequired">
<mat-error *ngIf="form.get('value')['errors'] && form.get('value')['errors']['required']">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<div *ngSwitchCase="'freetext'">
<mat-form-field>
<input matInput formControlName="value" placeholder="{{field.data.label}}" [required]="field.validationRequired">
<mat-error *ngIf="form.get('value')['errors'] && form.get('value')['errors']['required']">{{'GENERAL.VALIDATION.REQUIRED'
| translate}}</mat-error>
</mat-form-field>
</div>
<div *ngSwitchCase="'combobox'">
<!--TODO-->
<div *ngIf="this.field.data.type === 'autocomplete'">
<app-df-autocomplete [form]="form" [field]="field"></app-df-autocomplete>
</div>
<div *ngIf="this.field.data.type === 'wordlist'">
<app-df-dropdown [form]="form" [field]="field"></app-df-dropdown>
</div>
<div *ngSwitchCase="'combobox'">
<!--TODO-->
<div *ngIf="this.field.data.type === 'autocomplete'">
<app-df-autocomplete [form]="form" [field]="field"></app-df-autocomplete>
</div>
<div *ngIf="this.field.data.type === 'wordlist'">
<app-df-dropdown [form]="form" [field]="field"></app-df-dropdown>
</div>
</div>
<div *ngSwitchCase="'checkBox'" class="checkbox">
<app-df-checkbox [form]="form" [field]="field"></app-df-checkbox>
</div>
<div *ngSwitchCase="'textarea'">
<mat-form-field>
<textarea matInput formControlName="value" matTextareaAutosize matAutosizeMinRows="2" matAutosizeMaxRows="10"
[required]="field.validationRequired">
</div>
<div *ngSwitchCase="'checkBox'" class="checkbox">
<app-df-checkbox [form]="form" [field]="field"></app-df-checkbox>
</div>
<div *ngSwitchCase="'textarea'">
<mat-form-field>
<textarea matInput formControlName="value" matTextareaAutosize matAutosizeMinRows="2" matAutosizeMaxRows="10" [required]="field.validationRequired">
</textarea>
<button mat-button *ngIf="!form.get('value').disabled && form.get('value').value" matSuffix mat-icon-button aria-label="Clear" (click)="this.form.patchValue({'value': ''})">
<mat-icon>close</mat-icon>
</button>
<mat-error *ngIf="form.get('value')['errors'] && form.get('value')['errors']['required']">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
<button mat-button *ngIf="!form.get('value').disabled && form.get('value').value" matSuffix mat-icon-button
aria-label="Clear" (click)="this.form.patchValue({'value': ''})">
<mat-icon>close</mat-icon>
</button>
<mat-error *ngIf="form.get('value')['errors'] && form.get('value')['errors']['required']">{{'GENERAL.VALIDATION.REQUIRED'
| translate}}</mat-error>
</mat-form-field>
</div>
</div>
<div *ngSwitchCase="'booleanDecision'">
<app-df-boolean-decision [form]="form" [field]="field"></app-df-boolean-decision>
</div>
<div *ngSwitchCase="'booleanDecision'">
<app-df-boolean-decision [form]="form" [field]="field"></app-df-boolean-decision>
</div>
<div *ngSwitchCase="'radiobox'">
<app-df-radiobox [form]="form" [field]="field"></app-df-radiobox>
</div>
<div *ngSwitchCase="'radiobox'">
<app-df-radiobox [form]="form" [field]="field"></app-df-radiobox>
</div>
<div *ngSwitchCase="'label'"> </div>
<div *ngSwitchCase="'label'"> </div>
<!--<div [hidden]="isValid">
<!--<div [hidden]="isValid">
<mat-error *ngIf="isValidRequired">The field "{{field.data.label}}" <strong>required</strong></mat-error>
<div class="invalid-feedbackCustom" *ngIf="isValidRequired">The field "{{field.label}}" is required</div>
<div class="invalid-feedbackCustom" *ngIf="isValidPattern">The field {{field.label}} must match a regular expression {{field.regex}}</div>
<div class="invalid-feedbackCustom" *ngIf="isValidCustom">The field {{field.label}} custom Validation</div>
</div>-->
</div>
</div>
</div>
<!-- <div [formGroup]="form" class="form-group">

@ -19,10 +19,10 @@ import { Subscription } from 'rxjs';
export class DynamicFormFieldComponent implements OnInit, OnChanges, OnDestroy {
@Input() field: Field;
form: FormGroup;
@Input() pathName: string;
@Input() path: string;
change: Subscription;
trackByFn = (index, item) => item ? item['id'] : null;
constructor(private route: ActivatedRoute, public visibilityRulesService: VisibilityRulesService) {
}

@ -1,19 +1,25 @@
<div *ngIf="form" [id]="compositeField.id" [formGroup]="form">
<div *ngIf="compositeField.fields.length == 1" class="fieldset-component">
<h5 *ngIf="compositeField.title" style="font-weight:bold; color: #3a3737;">{{compositeField.title}}</h5>
<h5 *ngIf="compositeField.title" style="font-weight:bold; color: #3a3737;">{{compositeField.numbering}}
{{compositeField.title}}
<a *ngIf="this.markForConsiderationService.exists(compositeField)" (click)="markForConsideration()" style="cursor: pointer">
Mark For Consideration
</a>
</h5>
<div class="content-left-margin">
<h5 *ngIf="compositeField.description">{{compositeField.description}}</h5>
<h5 *ngIf="compositeField.extendedDescription" class="fieldset-extended-desc">
<i>{{compositeField.extendedDescription}}</i>
</h5>
<app-df-field *ngIf="compositeField.fields.length == 1" [field]="compositeField.fields[0]" [pathName]="pathName+'.fields.'+0"></app-df-field>
<app-df-field *ngIf="compositeField.fields.length == 1" [field]="compositeField.fields[0]"></app-df-field>
</div>
</div>
<div *ngIf="compositeField.fields.length > 1" class="fieldset-component">
<h5 *ngIf="compositeField.title" style="font-weight:bold; color: #3a3737;">{{compositeField.title}}</h5>
<h5 *ngIf="compositeField.title" style="font-weight:bold; color: #3a3737;">{{compositeField.numbering}}{{compositeField.title}}</h5>
<div class="content-left-margin">
<h5 *ngIf="compositeField.description">{{compositeField.description}}</h5>
<h5 *ngIf="compositeField.extendedDescription" class="fieldset-extended-desc">
@ -28,13 +34,14 @@
</div>
</div>
<app-df-field [field]="field" [pathName]="pathName+'.fields.'+i"></app-df-field>
<app-df-field #{{}} [field]="field"></app-df-field>
<div *ngIf="field">
<div *ngFor="let multipleField of field.multiplicityItems; let j = index; trackBy: trackByFn">
<app-df-field [field]="multipleField" [pathName]="pathName+'.fields.'+i+'.multiplicityItems.'+j"></app-df-field>
<app-df-field [field]="multipleField"></app-df-field>
</div>
</div>
</div>
</div>
</div>
</div>

@ -3,6 +3,8 @@ import { CompositeField } from '../../models/CompositeField';
import { FormGroup, FormArray } from '@angular/forms';
import { Component, Input, OnInit, ViewEncapsulation, ChangeDetectionStrategy } from '@angular/core';
import { Field } from '../../models/Field';
import { MarkForConsiderationService } from '../../utilities/mark-for-considerations/mark-for-consideration.service';
import { FormFocusService } from '../../utilities/form-focus-service/form-focus.service';
@Component({
selector: 'app-df-composite-field',
templateUrl: './dynamic-form-composite-field.html',
@ -15,11 +17,13 @@ export class DynamicFormCompositeFieldComponent implements OnInit {
@Input() compositeField: CompositeField;
form: FormGroup;
@Input() pathName: string;
@Input() path: string;
trackByFn = (index, item) => item ? item['id'] : null;
constructor(private visibilityRulesService: VisibilityRulesService) {
constructor(
private visibilityRulesService: VisibilityRulesService,
private markForConsiderationService: MarkForConsiderationService,
private formFocusService: FormFocusService
) {
}
ngOnInit() {
@ -28,10 +32,13 @@ export class DynamicFormCompositeFieldComponent implements OnInit {
}
}
addMultipleField(fieldIndex: number) {
const field: Field = this.compositeField.fields[fieldIndex].cloneForMultiplicity(fieldIndex, '');
this.compositeField.fields[fieldIndex].multiplicityItems.push(field);
(<FormArray>(this.form.get('fields').get('' + fieldIndex).get('multiplicityItems'))).push(field.buildForm());
}
markForConsideration() {
this.markForConsiderationService.markForConsideration(this.compositeField);
}
}

@ -1,20 +1,20 @@
<div *ngIf="form" class="group-component" [id]="group.id" [formGroup]="form">
<div class="content-left-margin">
<div class="content-left-margin">
<div *ngFor="let compositeField of group.compositeFields; let i = index; trackBy: trackByFn">
<div>
<div *ngIf="(compositeField?.multiplicity?.max - 1) > (compositeField?.multiplicityItems?.length)">
<a (click)="addMultipleField(i)" style="cursor: pointer">
Add one more fieldset +
</a>
</div>
</div>
<app-df-composite-field [compositeField]="compositeField" [path]="path" [pathName]="pathName+'.compositeFields.'+i"></app-df-composite-field>
<div *ngIf="compositeField">
<div *ngFor="let multipleCompositeField of compositeField.multiplicityItems; let j = index; trackBy: trackByFn">
<app-df-composite-field [compositeField]="multipleCompositeField" [pathName]="pathName+'.compositeFields.'+i+'.multiplicityItems.'+j"></app-df-composite-field>
</div>
</div>
</div>
</div>
<div *ngFor="let compositeField of group.compositeFields; let i = index; trackBy: trackByFn">
<div>
<div *ngIf="(compositeField?.multiplicity?.max - 1) > (compositeField?.multiplicityItems?.length)">
<a (click)="addMultipleField(i)" style="cursor: pointer">
Add one more fieldset +
</a>
</div>
</div>
<app-df-composite-field [compositeField]="compositeField"></app-df-composite-field>
<div *ngIf="compositeField">
<div *ngFor="let multipleCompositeField of compositeField.multiplicityItems; let j = index; trackBy: trackByFn">
<app-df-composite-field [compositeField]="multipleCompositeField"></app-df-composite-field>
</div>
</div>
</div>
</div>
</div>

@ -3,7 +3,7 @@
<mat-expansion-panel expanded=true>
<mat-expansion-panel-header>
<mat-panel-title>
{{path}} {{section.title}}
{{section.numbering}} {{section.title}}
</mat-panel-title>
<mat-panel-description>
<h3 *ngIf="section.description">{{section.description}}</h3>
@ -18,16 +18,19 @@
Add one more fieldset +
</a>
</div>
<app-df-composite-field [compositeField]="compositeField" [path]="path" [pathName]="pathName+'.compositeFields.'+i"></app-df-composite-field>
<app-df-composite-field [compositeField]="compositeField"></app-df-composite-field>
<div *ngIf="compositeField">
<div *ngFor="let multipleCompositeField of compositeField.multiplicityItems; let j = index; trackBy: trackByFn">
<app-df-composite-field [compositeField]="multipleCompositeField" [pathName]="pathName+'.compositeFields.'+i+'.multiplicityItems.'+j"></app-df-composite-field>
<app-df-composite-field [compositeField]="multipleCompositeField"></app-df-composite-field>
</div>
<div *ngIf="compositeField.hasCommentField" [formGroup]="form.get('compositeFields').get(''+i)">
<mat-form-field>
<input matInput formControlName="commentFieldValue" placeholder="comment">
</mat-form-field>
</div>
<button mat-icon-button type="button" (click)="next(compositeField)">
<mat-icon>expand_more</mat-icon>
</button>
</div>
</div>

@ -3,6 +3,7 @@ import { FormGroup, Form, FormArray } from '@angular/forms';
import { Component, Input, OnInit, ViewEncapsulation, ChangeDetectionStrategy, AfterViewInit } from '@angular/core';
import { CompositeField } from '../../models/CompositeField';
import { Section } from '../../models/Section';
import { FormFocusService } from '../../utilities/form-focus-service/form-focus.service';
@Component({
@ -20,7 +21,10 @@ export class DynamicFormSectionComponent implements OnInit, AfterViewInit {
@Input() pathName: string;
@Input() path: string;
trackByFn = (index, item) => item ? item['id'] : null;
constructor(public visibilityRulesService: VisibilityRulesService) { }
constructor(
public visibilityRulesService: VisibilityRulesService,
private formFocusService: FormFocusService
) { }
ngOnInit() {
if (this.section) {
@ -47,4 +51,8 @@ export class DynamicFormSectionComponent implements OnInit, AfterViewInit {
}
return false;
}
next(compositeField: CompositeField) {
this.formFocusService.focusNext(compositeField);
}
}

@ -32,6 +32,9 @@ import { NgModule } from '@angular/core';
import { DatasetProfileAdmin } from '../services/datasetProfileAdmin/datasetProfileAfmin.service';
import { DatasetProfileService } from '../services/dataset-profile.service';
import { DatasetWizardService } from '../services/dataset-wizard/dataset-wizard.service';
import { DynamicFormPendingQuestionsDisplayComponent } from './helpers/dynamic-form-pending-questions/dynamic-form-pending-questions-display.component';
import { MarkForConsiderationService } from '../utilities/mark-for-considerations/mark-for-consideration.service';
import { FormFocusService } from '../utilities/form-focus-service/form-focus.service';
@NgModule({
@ -57,6 +60,7 @@ import { DatasetWizardService } from '../services/dataset-wizard/dataset-wizard.
DynamicFormCompositeFieldComponent,
DynamicFieldBooleanDecisionComponent,
DynamicFieldRadioBoxComponent,
DynamicFormPendingQuestionsDisplayComponent,
TableOfContentsComponent,
TableOfContentsFieldSetComponent,
TableOfContentsGroupComponent,
@ -76,6 +80,7 @@ import { DatasetWizardService } from '../services/dataset-wizard/dataset-wizard.
DynamicFormCompositeFieldComponent,
DynamicFieldBooleanDecisionComponent,
DynamicFieldRadioBoxComponent,
DynamicFormPendingQuestionsDisplayComponent,
TableOfContentsComponent,
TableOfContentsFieldSetComponent,
TableOfContentsGroupComponent,
@ -92,7 +97,9 @@ import { DatasetWizardService } from '../services/dataset-wizard/dataset-wizard.
PaginationService,
DatasetProfileService,
DatasetProfileAdmin,
DatasetWizardService
DatasetWizardService,
MarkForConsiderationService,
FormFocusService
]
})

@ -6,15 +6,17 @@ import { BaseHttpService } from '../../utilities/cite-http-service-module/base-h
import { VisibilityRulesService } from '../../utilities/visibility-rules/visibility-rules.service';
import { DatasetProfileDefinitionModel } from '../../models/DatasetProfileDefinitionModel';
import { DatasetWizardModel } from '../../models/datasets/DatasetWizardModel';
import { Component, Input, OnInit, AfterViewChecked, ViewChild, forwardRef, ViewEncapsulation, AfterViewInit, ChangeDetectionStrategy } from '@angular/core';
import { FormGroup, Validators, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NgForm } from '@angular/forms';
import { Router, ActivatedRoute, ParamMap, Params } from '@angular/router';
import { Component, Input, OnInit, ViewEncapsulation, AfterViewInit, ViewChild } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import 'rxjs/add/operator/switchMap';
import '../../utilities/enhancers/flatJoinOn';
import { Location } from '@angular/common';
import { MatSidenavModule } from '@angular/material/sidenav';
declare function simple_notifier(type: string, title: string, message: string): any;
import { MarkForConsiderationService } from '../../utilities/mark-for-considerations/mark-for-consideration.service';
import { FormFocusService } from '../../utilities/form-focus-service/form-focus.service';
import { CompositeField } from '../../models/CompositeField';
import { Pair } from '../../models/helpers/Pair';
import { MatStepper } from '@angular/material';
@Component({
selector: 'app-dynamic-form',
@ -23,6 +25,7 @@ declare function simple_notifier(type: string, title: string, message: string):
'./dynamic-form.component.scss'
],
providers: [
FormFocusService
],
encapsulation: ViewEncapsulation.None,
})
@ -35,8 +38,8 @@ export class DynamicFormComponent implements OnInit, AfterViewInit {
datasetProfileDefinitionModel: DatasetProfileDefinitionModel;
private progressbar = false;
private currentPageIndex = 0;
@ViewChild('stepper') stepper: MatStepper;
private fragment: string;
@Input() dataModel: DatasetWizardModel = new DatasetWizardModel();
@Input() path: string;
@Input() form: FormGroup;
@ -48,11 +51,9 @@ export class DynamicFormComponent implements OnInit, AfterViewInit {
constructor(
private router: Router,
private _location: Location,
private route: ActivatedRoute,
private visibilityRulesService: VisibilityRulesService,
private http: BaseHttpService,
private datasetWizardService: DatasetWizardService,
private formFocusService: FormFocusService
) {
//this.datasetId = route.snapshot.params['id'];
}
@ -69,14 +70,26 @@ export class DynamicFormComponent implements OnInit, AfterViewInit {
this.visibilityRulesService.buildVisibilityRules(rules);
this.datasetProfileDefinitionModel = this.dataModel.datasetProfileDefinition;
this.visibilityRulesService.setModel(this.datasetProfileDefinitionModel);
this.createPagination();
this.progressbar = true;
const sections: Pair<Section[], number>[] = this.datasetProfileDefinitionModel.pages.map(page => new Pair<Section[], number>(page.sections, page.ordinal)).filter(x => x);
const compositeFields: Pair<CompositeField[], number>[] = sections.map(section => new Pair<CompositeField[], number>(section.left.flatMap(sec => sec.compositeFields), section.right)).filter(x => x);
const nestedSections: Pair<Section[], number>[] = sections.map(section => new Pair<Section[], number>(section.left.flatMap(x => x.sections), section.right)).filter(x => x);
const nestedCompositeFields: Pair<CompositeField[], number>[] = nestedSections.map(section => new Pair<CompositeField[], number>(section.left.flatMap(x => x.compositeFields), section.right)).filter(x => x);
const compositeFieldsUnion: Pair<CompositeField[], number>[] = compositeFields.concat(nestedCompositeFields);
//const fields = compositeFieldsUnion.flatJoinOn(x => x.right);
this.formFocusService.setFields(compositeFieldsUnion);
this.route.fragment.subscribe((fragment: string) => {
const self = this;
setTimeout(function () { self.scrollTo(fragment); });
});
}
ngAfterViewInit() {
this.visibilityRulesService.triggerVisibilityEvaluation();
this.route.queryParams.subscribe((params) => {
if (params && 'page' in params) {
this.changeCurrentPage(params['page']);
@ -84,35 +97,17 @@ export class DynamicFormComponent implements OnInit, AfterViewInit {
});
}
ngAfterViewInit() {
this.visibilityRulesService.triggerVisibilityEvaluation();
}
toggleSidebar() {
this.visibleSidebar = !this.visibleSidebar;
}
// getPages(model: DatasetProfileDefinitionModel): Array<number> {
// let pageSet = new Set<number>();
// model.sections.forEach(section => {
// pageSet.add(section.page);
// });
// return Array.from(pageSet).sort((a, b) => a - b);
// }
shouldDisplaySection(section: Section): Boolean {
return (section.page) === this.currentPageIndex;
}
createPagination() {
/*this.pages.forEach(item => {
this.stepperItems.push({
label: '',
})
});*/
}
changePageIndex(index: any) {
@ -125,16 +120,14 @@ export class DynamicFormComponent implements OnInit, AfterViewInit {
if (!element) { return; }
element.scrollIntoView();
this.visibleSidebar = true;
const scrollElement = document.querySelector('.scrollableContent');
//scrollElement.scrollTop = topElement.offsetTop;
}
changeCurrentPage(pageString: string) {
if (!pageString) { return; }
//if (!pageString) { return; }
const page = parseInt(pageString);
if (isNaN(page)) { return; }
/*if (isNaN(page)) { return; }
const pageIndex = this.pages.indexOf(page);
if (pageIndex === -1) { return; }
this.currentPageIndex = page;
if (pageIndex === -1) { return; }*/
this.stepper.selectedIndex = page;
}
}

@ -0,0 +1,4 @@
<div *ngFor="let field of this.markForConsideration.getFields()">
<app-df-composite-field [compositeField]="field">
</app-df-composite-field>
</div>

@ -0,0 +1,52 @@
import { Component, ViewEncapsulation, OnInit, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { VisibilityRulesService } from '../../../utilities/visibility-rules/visibility-rules.service';
import { JsonSerializer } from '../../../utilities/JsonSerializer';
import { Rule } from '../../../models/Rule';
import { DatasetWizardModel } from '../../../models/datasets/DatasetWizardModel';
import { DatasetProfileDefinitionModel } from '../../../models/DatasetProfileDefinitionModel';
import { Section } from '../../../models/Section';
import { CompositeField } from '../../../models/CompositeField';
import '../../../utilities/enhancers/flatMap';
import { Field } from '../../../models/Field';
import { MarkForConsiderationService } from '../../../utilities/mark-for-considerations/mark-for-consideration.service';
@Component({
selector: 'app-dynamic-form-pending-questions-display',
templateUrl: './dynamic-form-pending-questions-display.component.html',
styleUrls: [
'./dynamic-form-pending-questions-display.component.scss'
],
providers: [
],
encapsulation: ViewEncapsulation.None,
})
export class DynamicFormPendingQuestionsDisplayComponent implements OnInit {
constructor(
private visibilityRulesService: VisibilityRulesService,
private markForConsideration: MarkForConsiderationService) {
}
datasetProfileDefinitionModel: DatasetProfileDefinitionModel;
@Input()
form: FormGroup;
@Input() dataModel: DatasetWizardModel = new DatasetWizardModel();
fields: CompositeField[];
ngOnInit(): void {
const rules: Rule[] = JsonSerializer.fromJSONArray(this.dataModel.datasetProfileDefinition.rules, Rule);
this.datasetProfileDefinitionModel = this.dataModel.datasetProfileDefinition;
const sections: Section[] = this.datasetProfileDefinitionModel.pages.flatMap(page => page.sections).filter(x => x);
const compositeFields: CompositeField[] = sections.flatMap(section => section.compositeFields).filter(x => x);
const nestedSections: Section[] = sections.flatMap(section => section.sections).filter(x => x);
const nestedCompositeFiels: CompositeField[] = nestedSections.flatMap(section => section.compositeFields).filter(x => x);
const compositeFieldsUnion = compositeFields.concat(nestedCompositeFiels);
//const fields: Field[] = compositeFields.flatMap(composite => composite.fields).concat(nestedCompositeFiels.flatMap(composite => composite.fields));
const fields = compositeFieldsUnion.filter(compositeField => this.visibilityRulesService.checkElementVisibility(compositeField.id))
.filter(compositeField => compositeField.fields.filter(x => x && x.validationRequired && this.visibilityRulesService.getFormGroup(x.id).value == null).length > 0);
fields.forEach(x => this.markForConsideration.markForConsideration(x));
}
}

@ -54,12 +54,13 @@ export class ProgressBarComponent implements OnInit {
if (control instanceof FormGroup) { value += this.getFormControlDepthLength(control); } else if (control instanceof FormArray) {
const formArray = (<FormArray>control);
for (let i = 0; i < formArray.length; i++) {
//if (<FormGroup>formArray.get("" + i).value && this.visibilityRulesService.isElementVisible(null, formArray.get("" + i).value.id))
//value += this.getFormControlDepthLength(<FormGroup>formArray.get("" + i))
if (<FormGroup>formArray.get('' + i).value && this.visibilityRulesService.checkElementVisibility(formArray.get('' + i).value.id)) {
value += this.getFormControlDepthLength(<FormGroup>formArray.get('' + i));
}
}
} else if (key === 'value' && this.visibilityRulesService.checkElementVisibility(form.controls['id'].value)) {
value++;
}
//else if (key === "value" && this.visibilityRulesService.isElementVisible(null, form.controls["id"].value))
//value++;
});
return value;
}

@ -8,6 +8,7 @@ export class CompositeField extends BaseModel implements Serializable<CompositeF
public fields: Array<Field> = new Array<Field>();
public ordinal: number;
public id: string;
public numbering: string;
public multiplicity: Multiplicity;
public multiplicityItems: Array<CompositeField> = new Array<CompositeField>();
public title: string;
@ -22,6 +23,7 @@ export class CompositeField extends BaseModel implements Serializable<CompositeF
this.ordinal = item.ordinal;
this.id = item.id;
this.title = item.title;
this.numbering = item.numbering;
this.description = item.description;
this.extendedDescription = item.extendedDescription;
this.hasCommentField = item.hasCommentField;

@ -15,6 +15,7 @@ export class Field extends BaseModel implements Serializable<Field>, FormGenerat
public value: any;
public defaultValue: DefaultValue;
public description: string;
public numbering: string;
public extendedDescription: string;
public viewStyle: ViewStyle;
public defaultVisibility: boolean;
@ -29,6 +30,7 @@ export class Field extends BaseModel implements Serializable<Field>, FormGenerat
this.id = item.id;
this.title = item.title;
//this.value = item.value;
this.numbering = item.numbering;
this.description = item.description;
this.extendedDescription = item.extendedDescription;
this.viewStyle = item.viewStyle;

@ -11,6 +11,7 @@ export class Section extends BaseModel implements Serializable<Section>, FormGen
//public fieldGroups: Array<FieldGroup>;
public defaultVisibility: boolean;
public page: number;
public numbering: string;
public ordinal: number;
public id: string;
public title: string;
@ -22,6 +23,7 @@ export class Section extends BaseModel implements Serializable<Section>, FormGen
//this.fieldGroups = new JsonSerializer<FieldGroup>().fromJSONArray(item.fieldGroups, FieldGroup);
this.page = item.page;
this.defaultVisibility = item.defaultVisibility;
this.numbering = item.numbering;
this.id = item.id;
this.title = item.title;
this.ordinal = item.ordinal;

@ -0,0 +1,9 @@
export class Pair<L, R> {
public readonly left: L;
public readonly right: R;
constructor(left: L, right: R) {
this.left = left;
this.right = right;
}
}

@ -29,7 +29,7 @@ export class BreadCrumbResolverService {
}
public resolve(activatedRoute: ActivatedRoute): Observable<BreadcrumbItem[]> {
this.breadCrumbs = Observable.of([]);
this.breadCrumbs = null;
const routeComponents = this.getComponentsFromRoute(activatedRoute, []);
this.activeComponents.filter(x => routeComponents.indexOf(x.constructor.name) !== -1).forEach(x => {
if (x.hasOwnProperty('breadCrumbs')) {

@ -1,17 +1,17 @@
import 'rxjs/add/operator/map';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { HostConfiguration } from './../../app.constants';
import { BaseHttpService } from '../../utilities/cite-http-service-module/base-http.service';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
import { environment } from '../../../environments/environment';
import { DataTableRequest } from '../../models/data-table/DataTableRequest';
import { DataTableData } from '../../models/data-table/DataTableData';
import { DataManagementPlanModel } from '../../models/data-managemnt-plans/DataManagementPlanModel';
import { DataManagementPlanListingModel } from '../../models/data-managemnt-plans/DataManagementPlanListingModel';
import { DataManagementPlanCriteria } from '../../models/criteria/data-management-plan/DataManagementPlanCriteria';
import { DatasetProfileCriteria } from '../../models/criteria/dataset-profile/DatasetProfileCriteria';
import { RequestItem } from '../../models/criteria/RequestItem';
import { DataManagementPlanListingModel } from '../../models/data-managemnt-plans/DataManagementPlanListingModel';
import { DataManagementPlanModel } from '../../models/data-managemnt-plans/DataManagementPlanModel';
import { DataTableData } from '../../models/data-table/DataTableData';
import { DataTableRequest } from '../../models/data-table/DataTableRequest';
import { DatasetProfileModel } from '../../models/datasets/DatasetProfileModel';
import { BaseHttpService } from '../../utilities/cite-http-service-module/base-http.service';
import { DatasetProfileCriteria } from '../../models/criteria/dataset-profile/DatasetProfileCriteria';
@Injectable()
@ -22,7 +22,7 @@ export class DataManagementPlanService {
constructor(private http: BaseHttpService, private httpClient: HttpClient) {
this.actionUrl = environment.Server + 'dmps/';
this.actionUrl = HostConfiguration.Server + 'dmps/';
this.headers = new HttpHeaders();
this.headers = this.headers.set('Content-Type', 'application/json');
@ -75,4 +75,12 @@ export class DataManagementPlanService {
public downloadXML(id: string): Observable<HttpResponse<Blob>> {
return this.httpClient.get(this.actionUrl + 'getXml/' + id, { responseType: 'blob', observe: 'response' });
}
public downloadDocx(id: string): Observable<HttpResponse<Blob>> {
return this.httpClient.get(this.actionUrl + 'getWord/' + id, { responseType: 'blob', observe: 'response' });
}
public downloadPDF(id: string): Observable<HttpResponse<Blob>> {
return this.httpClient.get(this.actionUrl + 'getPDF/' + id, { responseType: 'blob', observe: 'response' });
}
}

@ -7,7 +7,6 @@
</a>
</li>
<mat-icon fxFlex="nogrow">chevron_right</mat-icon>
</div>
</div>
</ol>

@ -30,7 +30,8 @@ export class BreadcrumbComponent implements OnInit {
}
buildBreadCrumb(route: ActivatedRoute): Observable<BreadcrumbItem[]> {
return this.breadCrumbService.resolve(route).map(x => { x.unshift({ label: 'Dashboard', url: '/welcome' }); return x; });
if (this.breadCrumbService.resolve(route)) { return this.breadCrumbService.resolve(route).map(x => { x.unshift({ label: 'Dashboard', url: '/welcome' }); return x; }); }
return Observable.of([]);
}
navigate(url, params) {

@ -0,0 +1,9 @@
interface Array<T> {
flatJoinOn<E, J>(by: (item: T) => J): Array<E>;
}
Array.prototype.flatJoinOn = function (f: Function) {
return this.groupBy(f).reduce((ys: any, x: any) => {
return ys.concat(f.call(this, x));
}, []);
};

@ -0,0 +1,9 @@
interface Array<T> {
flatMap<E>(callback: (t: T) => Array<E>): Array<E>;
}
Array.prototype.flatMap = function (f: Function) {
return this.reduce((ys: any, x: any) => {
return ys.concat(f.call(this, x));
}, []);
};

@ -0,0 +1,11 @@
interface Array<T> {
groupBy<E, J>(by: (item: T) => J): Array<Array<E>>;
}
Array.prototype.groupBy = function (f: Function) {
return this.reduce((ys: any, x: any) => {
ys[f.call(this, x)] = ys[f.call(this, x)] || [];
ys[f.call(this, x)].push(x);
return ys;
}, []);
};

@ -0,0 +1,36 @@
import { Injectable } from '@angular/core';
import { CompositeField } from '../../models/CompositeField';
import { Router, ActivatedRoute } from '@angular/router';
import { Pair } from '../../models/helpers/Pair';
import '../../utilities/enhancers/groupBy';
import { VisibilityRulesService } from '../visibility-rules/visibility-rules.service';
@Injectable()
export class FormFocusService {
private compositeFields: Pair<CompositeField[], number>[] = [];
constructor(
public router: Router,
public route: ActivatedRoute,
public visibilityService: VisibilityRulesService
) {
}
setFields(compositeFields: Pair<CompositeField[], number>[]) {
this.compositeFields = compositeFields;
}
focusNext(field: CompositeField) {
const flattenedCompositeFields = this.compositeFields.groupBy(x => x.right)
.map(x => x.reduce((first: Pair<CompositeField[], number>, second: Pair<CompositeField[], number>) =>
(new Pair<CompositeField[], number>(first.left.concat(second.left), first.right))));
const page = flattenedCompositeFields.filter(x => x['left'].map(y => y.id).indexOf(field.id) !== -1)[0];
let pageIndex = page['right'];
const currentFields = page['left'].filter(x => this.visibilityService.checkElementVisibility(x.id)).map(x => x.id);
const fieldIndex = currentFields.indexOf(field.id);
if (fieldIndex === currentFields.length - 1) { pageIndex = pageIndex + 1; }
this.router.navigate(['datasets/' + this.route.snapshot.url[0] + '/' + this.route.snapshot.url[1]], { fragment: page['left'].filter(x => this.visibilityService.checkElementVisibility(x.id))[fieldIndex].id, queryParams: { page: pageIndex } });
}
}

@ -0,0 +1,22 @@
import { Injectable } from '@angular/core';
import { CompositeField } from '../../models/CompositeField';
@Injectable()
export class MarkForConsiderationService {
private compositeFields: CompositeField[] = [];
markForConsideration(field: CompositeField) {
if (this.exists(field)) {
this.compositeFields.push(field);
}
}
getFields() {
return this.compositeFields;
}
exists(field: CompositeField) {
return this.compositeFields.map(x => x.id).indexOf(field.id) === -1;
}
}

@ -39,7 +39,7 @@ export class VisibilityRulesService {
}
public checkElementVisibility(id: string): boolean {
if (!this.elementVisibilityMap.has(id) || this.elementVisibilityMap.get(id)) { return true; } else { return false; }
return !this.elementVisibilityMap.has(id) || this.elementVisibilityMap.get(id);
}
public buildVisibilityRules(item: Array<Rule>) {
@ -55,7 +55,7 @@ export class VisibilityRulesService {
private evaluateVisibility(visibilityRule: VisibilityRule) {
for (let i = 0; i < visibilityRule.sourceVisibilityRules.length; i++) {
const pathKey = this.fieldsPathMemory[visibilityRule.sourceVisibilityRules[i].sourceControlId];
if (this.formGroup.get(pathKey + '.value') && ((this.formGroup.get(pathKey + '.value').value == null || this.formGroup.get(pathKey + '.value').value == null) || '' + this.formGroup.get(pathKey + '.value').value !== '' + visibilityRule.sourceVisibilityRules[i].sourceControlValue)) {
if (this.formGroup.get(pathKey + '.value') && (this.parseValue(this.formGroup.get(pathKey + '.value').value) !== this.parseValue(visibilityRule.sourceVisibilityRules[i].sourceControlValue))) {
if (this.formGroup.get(pathKey).parent.get('id')) {
if (!this.checkElementVisibility(this.formGroup.get(pathKey).parent.get('id').value)) {
const targetPathKey = this.fieldsPathMemory[visibilityRule.targetControlId];
@ -88,20 +88,11 @@ export class VisibilityRulesService {
}
}
// deleteFromModel(path: string, obj: any) {
// if (!path) return
// const _obj = JSON.parse(JSON.stringify(obj));
// const keys = path.split('.');
// keys.reduce((acc, key, index) => {
// if (index === keys.length - 1) {
// delete acc[key];
// return true;
// }
// return acc[key];
// }, _obj);
// return _obj;
// }
parseValue(value: any) {
if (typeof value === 'string') {
if (value === 'true') { return true; } else if (value === 'false') { return false; } else { return this.translate(value); }
} else { return value; }
}
updateValue(obj, value, path) {
let i;
@ -146,4 +137,12 @@ export class VisibilityRulesService {
}
}
}
private translate(item: any) {
try {
return JSON.parse(item).value;
} catch (error) {
return item;
}
}
}

@ -72,7 +72,9 @@
"NEW-VERSION": "New Version",
"VIEW-VERSION": "All DMP Versions",
"CLONE": "Clone",
"DOWNLOAD-XML": "Download XML"
"DOWNLOAD-XML": "Download XML",
"DOWNLOAD-DOCX": "Download Document",
"DOWNLOAD-PDF": "Download PDF"
}
},
"DATASET-WIZARD": {
@ -132,6 +134,30 @@
"DATASET-PUBLIC-LISTING": {
"TITLE": "Published dataset descriptions"
},
"DATASET-PROFILE-LISTING": {
"TITLE": "Dataset Profiles",
"COLUMNS": {
"NAME": "Name",
"REFERNCE": "Reference",
"PROJECT": "Project",
"URI": "Uri",
"STATUS": "Status",
"DESCRIPTION": "Description",
"CREATED": "Created",
"ACTIONS": "Actions",
"DMP": "Dmp",
"PROFILE": "Profile",
"DATAREPOSITORIES": "Data Repositories",
"REGISTRIES": "Registries",
"SERVICES": "Services"
},
"ACTIONS": {
"EDIT": "Edit",
"MAKE-IT-PUBLIC": "Make it public",
"VIEW": "View",
"CLONE": "Clone"
}
},
"DMP-PROFILE-EDITOR": {
"TITLE": {
"NEW": "New DMP Profile",
@ -195,6 +221,24 @@
"FINALISE": "Finalise"
}
},
"DMP-PROFILE-LISTING": {
"TITLE": "DMP Profiles",
"COLUMNS": {
"NAME": "Name",
"STATUS": "Status",
"CREATED": "Created"
}
},
"DYNAMIC-FORM": {
"FIELDS": {
"LABEL": "Label"
},
"ACTIONS": {
"PREVIEW": "Preview",
"ADD-PAGE": "Add Page +",
"ADD-SECTION": "Add Section +"
}
},
"CRITERIA": {
"FILTERS": "Filters",
"PROJECTS": {
@ -207,8 +251,10 @@
"FINISHED": "Finished"
}
},
"DATASET-PROFILE": {
"LIKE": "Search"
},
"DATA-SETS": {
"LIKE": "Search",
"PERIOD-FROM": "Start",
"PERIOD-TO": "End",
"STATUS": "Status",
@ -316,6 +362,11 @@
"SAVE": "Save"
}
},
"DATASET-PROFILE": {
"PREVIEW": "Preview",
"FORM-DESCRIPTION": "Form Description",
"PAGES-DESCRIPTION": "Pages Description"
},
"RECENT-ACTIVITY": {
"MY-TITLE-PROJECT": "My Recent Project Activity",
"MY-TITLE-DMP": "My Recent DMP Activity",

Loading…
Cancel
Save