From 985b3de3859dddc793823478357351b383799034 Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Fri, 16 Jun 2023 14:10:52 +0300 Subject: [PATCH 001/110] rich-text-editor.component.ts: Removed "backgroundColor" from toolbarHiddenButtons | Do not show (x) close to clear the input when editable is false. --- .../library/rich-text-editor/rich-text-editor.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts b/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts index edaf1dd56..5453a6404 100644 --- a/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts +++ b/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts @@ -10,7 +10,7 @@ import {FormControl} from "@angular/forms"; [config]="editorConfig" [formControlName]="controlName" placeholder="{{(placeholder? (placeholder | translate) : '') + (required ? ' *': '')}}" (paste)="pasteWithoutFormatting($event)"> - close + close `, styleUrls: ['./rich-text-editor.component.scss'] @@ -56,7 +56,7 @@ export class RichTextEditorComponent { ], [ 'fontSize', - 'backgroundColor', + // 'backgroundColor', // 'customClasses', 'insertImage', 'insertVideo', From eb4f1d23e1064fd4d9bd9f9bc93f344f7fbb7968 Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Fri, 16 Jun 2023 14:19:07 +0300 Subject: [PATCH 002/110] dataset-description.component.html: [Bug fix] Removed forgotten log {{form | json}} from html. --- .../dataset-description-form/dataset-description.component.html | 1 - 1 file changed, 1 deletion(-) diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html index c827ecbf3..ca244cf88 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html @@ -10,7 +10,6 @@
- {{form | json}} From 1a2a93a95f7ea384975d0921c2416fc4add4d3c4 Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Fri, 16 Jun 2023 14:36:24 +0300 Subject: [PATCH 003/110] #8738 - Disable input fields in finalised DMPs/datasets. 1. dataset-editor.component.html & form-composite-field.component.html & form-field.component.html & form-section.component.html: Added [editable] parameter input in or [disabled] attribute in inputs, buttons, and to disable then when form is disabled & do not add "pointer" class when form is disabled. 2. form-field.component.ts: For DatasetIdentifier and Validation view styles, when removing and re-adding control, check if form was disabled and disable it again. 3. form-section.component.ts: In method "addMultipleField()", return without doing anything when form is disabled. --- .../dataset-editor.component.html | 3 ++- .../form-composite-field.component.html | 6 +++--- .../form-field/form-field.component.html | 20 +++++++++++-------- .../form-field/form-field.component.ts | 8 ++++++++ .../form-section/form-section.component.html | 10 +++++----- .../form-section/form-section.component.ts | 3 +++ 6 files changed, 33 insertions(+), 17 deletions(-) diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.html b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.html index a7be0544d..cb8dab53d 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.html +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.html @@ -32,7 +32,8 @@ + ((formGroup.get('description').touched && (formGroup.get('description').hasError('required') || formGroup.get('description').hasError('backendError'))) ? 'required' : '')" + [editable]="!formGroup.get('description').disabled">
{{formGroup.get('description').getError('backendError').message}} diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-field/form-composite-field.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-field/form-composite-field.component.html index 24f35ac7a..471e5623b 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-field/form-composite-field.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-field/form-composite-field.component.html @@ -10,7 +10,7 @@
-
@@ -64,10 +64,10 @@ {{fieldFormGroup.getRawValue() | fieldValue | translate}} - - diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html index ccfc2e038..e24890e11 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html @@ -114,7 +114,8 @@ [placeholder]="form.get('data').value.label" [required]="form.get('validationRequired').value" [wrapperClasses]="'full-width editor ' + - ((form.get('validationRequired').value && form.get('value').touched && form.get('value').hasError('required')) ? 'required' : '')"> + ((form.get('validationRequired').value && form.get('value').touched && form.get('value').hasError('required')) ? 'required' : '')" + [editable]="!form.get('value').disabled">
@@ -125,7 +126,7 @@
+ [multiple]="false" [accept]="typesToString()" [disabled]="form.get('value').disabled"> {{ form.value.value.name }} @@ -134,12 +135,13 @@
- @@ -422,12 +424,14 @@
- + {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + {{ type.name }} @@ -451,7 +455,7 @@
-
+
{{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -467,7 +471,7 @@
- + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts index 23320fe92..dcd6039f9 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts @@ -314,8 +314,12 @@ export class FormFieldComponent extends BaseComponent implements OnInit { break; case DatasetProfileFieldViewStyle.DatasetIdentifier: const value = this.form.get('value').value; + const disabled = this.form.disabled; this.form.removeControl('value'); this.form.addControl('value', new DatasetIdModel(value).buildForm()); + if(disabled) { + this.form.disable(); + } this.datasetIdInitialized = true; break; case DatasetProfileFieldViewStyle.Currency: @@ -329,8 +333,12 @@ export class FormFieldComponent extends BaseComponent implements OnInit { break; case DatasetProfileFieldViewStyle.Validation: const value1 = this.form.get('value').value; + const disabled1 = this.form.disabled; this.form.removeControl('value'); this.form.addControl('value', new DatasetIdModel(value1).buildForm()); + if(disabled1) { + this.form.disable(); + } //this.datasetIdInitialized = true; break; } diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html index a71b95049..43c45f710 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html @@ -32,7 +32,7 @@
- + @@ -44,7 +44,7 @@ + [wrapperClasses]="'mb-2'" [editable]="!compositeFieldFormGroup.get('commentFieldValue').disabled">
@@ -116,7 +116,7 @@ - + @@ -139,7 +139,7 @@
- + @@ -151,7 +151,7 @@ + [wrapperClasses]="' mb-2'" [editable]="!fieldsetEntry.form.get('commentFieldValue').disabled">
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts index a87a937a9..c7ca771b8 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts @@ -217,6 +217,9 @@ export class FormSectionComponent extends BaseComponent implements OnInit, OnCha } addMultipleField(fieldsetIndex: number) { + if(this.form.get('compositeFields').get('' + fieldsetIndex).disabled) { + return; + } const compositeFieldToBeCloned = (this.form.get('compositeFields').get('' + fieldsetIndex) as FormGroup).getRawValue(); const multiplicityItemsArray = ((this.form.get('compositeFields').get('' + fieldsetIndex).get('multiplicityItems'))); From b6505cda4ef46eecfe2121eb883d61024787d185 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Wed, 21 Jun 2023 11:51:26 +0300 Subject: [PATCH 004/110] refactor signing of saml2 authentication request --- .../controllers/Saml2MetadataController.java | 7 +- .../configurableProvider/Saml2SSOUtils.java | 76 ++++++++++++------- .../models/data/saml2/AuthnRequestModel.java | 47 ++++++++++++ .../app/core/model/saml2/AuthnRequestModel.ts | 6 ++ .../app/core/services/saml-login.service.ts | 5 +- .../configurable-login.component.ts | 15 +--- 6 files changed, 112 insertions(+), 44 deletions(-) create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/saml2/AuthnRequestModel.java create mode 100644 dmp-frontend/src/app/core/model/saml2/AuthnRequestModel.ts diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Saml2MetadataController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Saml2MetadataController.java index 9f95273c7..4563e2f9f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Saml2MetadataController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Saml2MetadataController.java @@ -5,6 +5,7 @@ import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.sam import eu.eudat.logic.security.validators.configurableProvider.Saml2SSOUtils; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.models.data.saml2.AuthnRequestModel; import eu.eudat.types.ApiMessageCode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; @@ -56,14 +57,14 @@ public class Saml2MetadataController extends BaseController { } @RequestMapping(method = RequestMethod.GET, value = {"authnRequest/{configurableProviderId}"}) public @ResponseBody - ResponseEntity> getAuthnRequest(@PathVariable String configurableProviderId) { + ResponseEntity getAuthnRequest(@PathVariable String configurableProviderId) { Saml2ConfigurableProvider saml2ConfigurableProvider = (Saml2ConfigurableProvider) this.configLoader.getConfigurableProviders().getProviders().stream() .filter(prov -> prov.getConfigurableLoginId().equals(configurableProviderId)) .findFirst().orElse(null); if (saml2ConfigurableProvider != null) { try { - String authnRequestXml = Saml2SSOUtils.getAuthnRequest(saml2ConfigurableProvider); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(authnRequestXml)); + AuthnRequestModel authnRequest = Saml2SSOUtils.getAuthnRequest(saml2ConfigurableProvider); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(authnRequest)); } catch (Exception e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Failed to create authentication request.")); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java index 5f31b65a2..862996ea6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java @@ -3,6 +3,7 @@ package eu.eudat.logic.security.validators.configurableProvider; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.saml2.CertificateInfo; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.saml2.Saml2ConfigurableProvider; import eu.eudat.logic.utilities.builders.XmlBuilder; +import eu.eudat.models.data.saml2.AuthnRequestModel; import jakarta.xml.soap.*; import net.shibboleth.utilities.java.support.component.ComponentInitializationException; import net.shibboleth.utilities.java.support.resolver.CriteriaSet; @@ -34,7 +35,6 @@ import org.opensaml.core.xml.config.XMLObjectProviderRegistry; import org.opensaml.core.xml.io.*; import org.opensaml.core.xml.schema.*; import org.opensaml.saml.common.SAMLObject; -import org.opensaml.saml.common.SAMLObjectContentReference; import org.opensaml.saml.common.SAMLVersion; import org.opensaml.saml.common.xml.SAMLConstants; import org.opensaml.saml.criterion.EntityRoleCriterion; @@ -64,8 +64,6 @@ import org.opensaml.xmlsec.keyinfo.impl.X509KeyInfoGeneratorFactory; import org.opensaml.xmlsec.signature.KeyInfo; import org.opensaml.xmlsec.signature.Signature; import org.opensaml.xmlsec.signature.X509Data; -import org.opensaml.xmlsec.signature.impl.SignatureBuilder; -import org.opensaml.xmlsec.signature.support.SignatureConstants; import org.opensaml.xmlsec.signature.support.SignatureValidator; import org.opensaml.xmlsec.signature.support.Signer; import org.slf4j.Logger; @@ -88,6 +86,7 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; +import java.net.URLEncoder; import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.security.*; @@ -794,47 +793,68 @@ public class Saml2SSOUtils { } - public static String getAuthnRequest(Saml2ConfigurableProvider provider) throws Exception { + public static AuthnRequestModel getAuthnRequest(Saml2ConfigurableProvider provider) throws Exception { AuthnRequest authnRequest = buildAuthnRequest(provider); + String relayState = "spId=" + provider.getSpEntityId() + "&configurableLoginId=" + provider.getConfigurableLoginId(); String authnRequestXml = null; - DocumentBuilder builder; - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + String signatureBase64 = null; try { - Signature signature = (Signature) buildXMLObject(Signature.DEFAULT_ELEMENT_NAME); - if(provider.isAuthnRequestsSigned()){ - - Credential credential = getCredential(provider.getSigningCert()); - signature.setSigningCredential(credential); - signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); - signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - - X509KeyInfoGeneratorFactory keyInfoGeneratorFactory = new X509KeyInfoGeneratorFactory(); - keyInfoGeneratorFactory.setEmitEntityCertificate(true); - KeyInfoGenerator keyInfoGenerator = keyInfoGeneratorFactory.newInstance(); - signature.setKeyInfo(keyInfoGenerator.generate(getCredential(provider.getSigningCert()))); - - authnRequest.setSignature(signature); - } - - builder = factory.newDocumentBuilder(); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); Marshaller out = registry.getMarshallerFactory().getMarshaller(authnRequest); out.marshall(authnRequest, document); - if(provider.isAuthnRequestsSigned()) { - Signer.signObject(signature); - } - authnRequestXml = XmlBuilder.generateXml(document); + if(provider.isAuthnRequestsSigned()) { + signatureBase64 = buildSignature(authnRequestXml, relayState, provider.getSigningCert()); + } } catch (MarshallingException | ParserConfigurationException e) { logger.error(e.getMessage(), e); } - return authnRequestXml; + AuthnRequestModel authnRequestModel = new AuthnRequestModel(); + authnRequestModel.setAuthnRequestXml(authnRequestXml); + authnRequestModel.setRelayState(relayState); + authnRequestModel.setAlgorithm("http://www.w3.org/2000/09/xmldsig#rsa-sha1"); + authnRequestModel.setSignature(signatureBase64); + return authnRequestModel; + + } + + private static String buildSignature(String authnRequest, String relayState, CertificateInfo signingCertInfo) throws Exception{ + + KeyStore ks = (signingCertInfo.getKeyFormat().getType().equals("JKS")) ? KeyStore.getInstance("JKS") : KeyStore.getInstance("PKCS12"); + String archivePassword = signingCertInfo.getKeystorePassword(); + char[] pwdArray = (archivePassword != null) ? archivePassword.toCharArray() : "changeit".toCharArray(); + ks.load(new FileInputStream(signingCertInfo.getKeystorePath()), pwdArray); + PrivateKey pk = (PrivateKey) ks.getKey(signingCertInfo.getAlias(), signingCertInfo.getPassword().toCharArray()); + + String signAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; + String message = "SAMLRequest=" + URLEncoder.encode(authnRequest, "UTF-8") + + "&RelayState=" + URLEncoder.encode(relayState, "UTF-8") + + "&SigAlg=" + URLEncoder.encode(signAlgorithm, "UTF-8"); + + String signature = null; + try{ + signature = new String(org.apache.commons.codec.binary.Base64.encodeBase64(sign(message, pk)), StandardCharsets.UTF_8); + } + catch(InvalidKeyException | SignatureException | NoSuchAlgorithmException e){ + logger.error(e.getMessage(), e); + } + + return signature; + } + + private static byte[] sign(String message, PrivateKey key) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException { + java.security.Signature instance = java.security.Signature.getInstance("SHA1withRSA"); + instance.initSign(key); + instance.update(message.getBytes()); + return instance.sign(); } private static AuthnRequest buildAuthnRequest(Saml2ConfigurableProvider provider) throws Exception { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/saml2/AuthnRequestModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/saml2/AuthnRequestModel.java new file mode 100644 index 000000000..90ba44eb9 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/saml2/AuthnRequestModel.java @@ -0,0 +1,47 @@ +package eu.eudat.models.data.saml2; + +public class AuthnRequestModel { + + String authnRequestXml; + String relayState; + String algorithm; + String signature; + + public AuthnRequestModel() {} + + public AuthnRequestModel(String authnRequestXml, String relayState, String algorithm, String signature) { + this.authnRequestXml = authnRequestXml; + this.relayState = relayState; + this.algorithm = algorithm; + this.signature = signature; + } + + public String getAuthnRequestXml() { + return authnRequestXml; + } + public void setAuthnRequestXml(String authnRequestXml) { + this.authnRequestXml = authnRequestXml; + } + + public String getRelayState() { + return relayState; + } + public void setRelayState(String relayState) { + this.relayState = relayState; + } + + public String getAlgorithm() { + return algorithm; + } + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public String getSignature() { + return signature; + } + public void setSignature(String signature) { + this.signature = signature; + } + +} diff --git a/dmp-frontend/src/app/core/model/saml2/AuthnRequestModel.ts b/dmp-frontend/src/app/core/model/saml2/AuthnRequestModel.ts new file mode 100644 index 000000000..683dba6fa --- /dev/null +++ b/dmp-frontend/src/app/core/model/saml2/AuthnRequestModel.ts @@ -0,0 +1,6 @@ +export interface AuthnRequestModel { + authnRequestXml: string; + relayState: string; + algorithm: string; + signature: string; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/saml-login.service.ts b/dmp-frontend/src/app/core/services/saml-login.service.ts index c3db23658..d052205d6 100644 --- a/dmp-frontend/src/app/core/services/saml-login.service.ts +++ b/dmp-frontend/src/app/core/services/saml-login.service.ts @@ -4,6 +4,7 @@ import { ConfigurationService } from './configuration/configuration.service'; import { BaseHttpService } from './http/base-http.service'; import { Observable } from 'rxjs'; import { BaseComponent } from '@common/base/base.component'; +import { AuthnRequestModel } from '../model/saml2/AuthnRequestModel'; @Injectable() export class SamlLoginService extends BaseComponent { @@ -27,8 +28,8 @@ export class SamlLoginService extends BaseComponent { return routeParams.has('spId') ? routeParams.get('spId') : ''; } - getAuthnRequest(configurableLoginId: string): Observable { - return this.http.get(this.actionUrl + 'authnRequest/' + configurableLoginId, { headers: this.headers }); + getAuthnRequest(configurableLoginId: string): Observable { + return this.http.get(this.actionUrl + 'authnRequest/' + configurableLoginId, { headers: this.headers }); } } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts b/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts index 4997571dd..00902cdfa 100644 --- a/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts @@ -90,25 +90,18 @@ export class ConfigurableLoginComponent extends BaseComponent implements OnInit this.samlLoginService.getAuthnRequest(provider.configurableLoginId).pipe(takeUntil(this._destroyed)) .subscribe( authenticationRequest => { - const uint = new Uint8Array(authenticationRequest.length); - for (let i = 0, j = authenticationRequest.length; i < j; ++i) { - uint[i] = authenticationRequest.charCodeAt(i); + const uint = new Uint8Array(authenticationRequest.authnRequestXml.length); + for (let i = 0, j = authenticationRequest.authnRequestXml.length; i < j; ++i) { + uint[i] = authenticationRequest.authnRequestXml.charCodeAt(i); } const base64String = btoa(pk.deflateRaw(uint, { to: 'string' })); - const relayState = this.buildRelayState(provider.spEntityId, provider.configurableLoginId); - const url = provider.idpUrl + '?RelayState=' + relayState + '&SAMLRequest=' + encodeURIComponent(base64String); + const url = provider.idpUrl + '?SAMLRequest=' + encodeURIComponent(base64String) + '&RelayState=' + encodeURIComponent(authenticationRequest.relayState) + '&SigAlg=' + encodeURIComponent(authenticationRequest.algorithm) + '&Signature=' + encodeURIComponent(authenticationRequest.signature); window.location.href = url; } ); } } - buildRelayState(spId: string, configurableLoginId: string): string { - let uri = 'spId=' + spId; - uri += '&configurableLoginId=' + configurableLoginId; - return encodeURIComponent(uri); - } - public configurableLoginUser(code: string, state: string) { if (state !== (this.provider).state) { this.router.navigate(['/login']) From 3d367b0589fba1aeca7d30d5d30057a319fd857f Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Wed, 21 Jun 2023 12:00:20 +0300 Subject: [PATCH 005/110] #8765 - make pids coming from apis as hypelinks in export --- .../managers/DataManagementPlanManager.java | 2 +- .../eudat/logic/managers/DatasetManager.java | 4 +- .../config/configloaders/ConfigLoader.java | 2 + .../configloaders/DefaultConfigLoader.java | 29 +++ .../utilities/documents/word/WordBuilder.java | 206 +++++++++++++----- .../eu/eudat/models/data/pid/PidLink.java | 21 ++ .../eu/eudat/models/data/pid/PidLinks.java | 16 ++ .../config/application-devel.properties | 1 + .../config/application-docker.properties | 1 + .../config/application-production.properties | 1 + .../resources/config/application.properties | 1 + .../web/src/main/resources/pidLinks.json | 100 +++++++++ 12 files changed, 324 insertions(+), 60 deletions(-) create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/pid/PidLink.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/pid/PidLinks.java create mode 100644 dmp-backend/web/src/main/resources/pidLinks.json diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index cb2e8a2bc..4e38e6411 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -1192,7 +1192,7 @@ public class DataManagementPlanManager { } public FileEnvelope getWordDocument(String id, Principal principal, ConfigLoader configLoader, Boolean versioned) throws IOException { - WordBuilder wordBuilder = new WordBuilder(this.environment); + WordBuilder wordBuilder = new WordBuilder(this.environment, configLoader); VisibilityRuleService visibilityRuleService = new VisibilityRuleServiceImpl(); DatasetWizardModel dataset = new DatasetWizardModel(); XWPFDocument document = configLoader.getDocument(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index 793f6382d..875181cc7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -397,7 +397,7 @@ public class DatasetManager { } private XWPFDocument getWordDocument(ConfigLoader configLoader, eu.eudat.data.entities.Dataset datasetEntity, VisibilityRuleService visibilityRuleService, Principal principal) throws IOException { - WordBuilder wordBuilder = new WordBuilder(this.environment); + WordBuilder wordBuilder = new WordBuilder(this.environment, configLoader); DatasetWizardModel dataset = new DatasetWizardModel(); XWPFDocument document = configLoader.getDatasetDocument(); @@ -509,7 +509,7 @@ public class DatasetManager { } private XWPFDocument getLightWordDocument(ConfigLoader configLoader, DatasetWizardModel dataset, VisibilityRuleService visibilityRuleService) throws IOException { - WordBuilder wordBuilder = new WordBuilder(this.environment); + WordBuilder wordBuilder = new WordBuilder(this.environment, configLoader); XWPFDocument document = configLoader.getDocument(); // Space below Dataset title. diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java index f253f5c12..ff27f43fe 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java @@ -3,6 +3,7 @@ package eu.eudat.logic.proxy.config.configloaders; import eu.eudat.logic.proxy.config.ExternalUrls; import eu.eudat.logic.proxy.config.Semantic; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; +import eu.eudat.models.data.pid.PidLinks; import org.apache.poi.xwpf.usermodel.XWPFDocument; import java.util.List; @@ -14,5 +15,6 @@ public interface ConfigLoader { XWPFDocument getDocument(); XWPFDocument getDatasetDocument(); ConfigurableProviders getConfigurableProviders(); + PidLinks getPidLinks(); Map getKeyToSourceMap(); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java index 4faa489d9..b9f7ddb0c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.logic.proxy.config.ExternalUrls; import eu.eudat.logic.proxy.config.Semantic; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; +import eu.eudat.models.data.pid.PidLinks; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,6 +42,7 @@ public class DefaultConfigLoader implements ConfigLoader { private XWPFDocument document; private XWPFDocument datasetDocument; private ConfigurableProviders configurableProviders; + private PidLinks pidLinks; private Map keyToSourceMap; @Autowired @@ -134,6 +136,25 @@ public class DefaultConfigLoader implements ConfigLoader { } } + private void setPidLinks() { + String filePath = environment.getProperty("configuration.pid_links"); + logger.info("Loaded also config file: " + filePath); + InputStream is = null; + try { + is = getStreamFromPath(filePath); + ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + this.pidLinks = mapper.readValue(is, PidLinks.class); + } catch (IOException | NullPointerException e) { + logger.error(e.getMessage(), e); + } finally { + try { + if (is != null) is.close(); + } catch (IOException e) { + logger.warn("Warning: Could not close a stream after reading from file: " + filePath, e); + } + } + } + private void setKeyToSourceMap() { String filePath = this.environment.getProperty("configuration.externalUrls"); logger.info("Loaded also config file: " + filePath); @@ -192,6 +213,14 @@ public class DefaultConfigLoader implements ConfigLoader { return configurableProviders; } + public PidLinks getPidLinks() { + if (pidLinks == null) { + pidLinks = new PidLinks(); + this.setPidLinks(); + } + return pidLinks; + } + public Map getKeyToSourceMap() { if (keyToSourceMap == null) { keyToSourceMap = new HashMap<>(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java index 0a3d64dbe..a10cf44d8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java @@ -7,11 +7,14 @@ import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.Dataset; import eu.eudat.data.entities.Organisation; import eu.eudat.data.entities.Researcher; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.utilities.documents.types.ParagraphStyle; import eu.eudat.logic.utilities.interfaces.ApplierWithValue; import eu.eudat.logic.utilities.json.JavaToJson; import eu.eudat.models.data.components.commons.datafield.*; +import eu.eudat.models.data.pid.PidLink; +import eu.eudat.models.data.pid.PidLinks; 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; @@ -71,8 +74,9 @@ public class WordBuilder { private Integer indent; private final ObjectMapper mapper; private Integer imageCount; + private ConfigLoader configLoader; - public WordBuilder(Environment environment) { + public WordBuilder(Environment environment, ConfigLoader configLoader) { this.cTAbstractNum = CTAbstractNum.Factory.newInstance(); this.cTAbstractNum.setAbstractNumId(BigInteger.valueOf(1)); this.indent = 0; @@ -80,6 +84,7 @@ public class WordBuilder { this.mapper = new ObjectMapper(); this.buildOptions(environment); this.buildOptionsInTable(environment); + this.configLoader = configLoader; } private void buildOptionsInTable(Environment environment) { @@ -568,6 +573,37 @@ public class WordBuilder { return hasValue; } + private void createHypeLink(XWPFDocument mainDocumentPart, String format, String pidType, String pid, boolean hasMultiplicityItems, boolean isMultiAutoComplete){ + PidLink pidLink = this.configLoader.getPidLinks().getPidLinks().stream().filter(pl -> pl.getPid().equals(pidType)).findFirst().orElse(null); + if (pidLink != null) { + if (!hasMultiplicityItems) { + XWPFParagraph paragraph = mainDocumentPart.createParagraph(); + paragraph.setIndentFromLeft(400 * indent); + if (numId != null) { + paragraph.setNumID(numId); + } + } + if (isMultiAutoComplete) { + XWPFRun r = mainDocumentPart.getLastParagraph().createRun(); + r.setText("• "); + } + XWPFHyperlinkRun run = mainDocumentPart.getLastParagraph().createHyperlinkRun(pidLink.getLink().replace("{pid}", pid)); + run.setText(format); + run.setUnderline(UnderlinePatterns.SINGLE); + run.setColor("0000FF"); + run.setFontSize(11); + } + else { + String newFormat = (isMultiAutoComplete) ? "• " + format : format; + if (hasMultiplicityItems) { + mainDocumentPart.getLastParagraph().createRun().setText(newFormat); + } + else { + addParagraphContent(newFormat, mainDocumentPart, ParagraphStyle.TEXT, numId, indent); + } + } + } + private Boolean createFields(List fields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService, boolean hasMultiplicityItems) { if (createListing) this.addListing(mainDocumentPart, indent, false, false); boolean hasValue = false; @@ -607,70 +643,126 @@ public class WordBuilder { } else if (field.getViewStyle().getRenderStyle().equals("combobox") && field.getData() instanceof AutoCompleteData) { format = getCommaSeparatedFormatsFromJson(format, "label"); } - boolean isResearcher = field.getViewStyle().getRenderStyle().equals("researchers"); - if(format != null && !format.isEmpty()){ - Object hasMultiAutoComplete = mapper.convertValue(field.getData(), Map.class).get("multiAutoComplete"); - boolean isMultiAutoComplete = hasMultiAutoComplete != null && (boolean)hasMultiAutoComplete; - boolean arrayStringFormat = format.charAt(0) == '['; - if(arrayStringFormat || isMultiAutoComplete){ - List values = (arrayStringFormat) ? Arrays.asList(format.substring(1, format.length() - 1).split(",[ ]*")) : Arrays.asList(format.split(",[ ]*")); - if(values.size() > 1) { - boolean orcidResearcher; - for (String val : values) { - orcidResearcher = false; - String orcId = null; - if(isResearcher && val.contains("orcid:")){ - orcId = val.substring(val.indexOf(':') + 1, val.indexOf(')')); - val = val.substring(0, val.indexOf(':') + 1) + " "; - orcidResearcher = true; - } - format = "• " + val; + switch (field.getViewStyle().getRenderStyle()) { + case "organizations": + case "externalDatasets": + case "publications": + if(format != null && !format.isEmpty()){ + Object hasMultiAutoComplete = mapper.convertValue(field.getData(), Map.class).get("multiAutoComplete"); + boolean isMultiAutoComplete = hasMultiAutoComplete != null && (boolean)hasMultiAutoComplete; + if(!isMultiAutoComplete){ + Map value = mapper.readValue((String)field.getValue(), Map.class); if(hasMultiplicityItems){ - mainDocumentPart.getLastParagraph().createRun().setText(format); - if(orcidResearcher){ - XWPFHyperlinkRun run = mainDocumentPart.getLastParagraph().createHyperlinkRun("https://orcid.org/" + orcId); - run.setText(orcId); - run.setUnderline(UnderlinePatterns.SINGLE); - run.setColor("0000FF"); - mainDocumentPart.getLastParagraph().createRun().setText(")"); - } + createHypeLink(mainDocumentPart, format, value.get("pidTypeField"), value.get("pid"), true, false); hasMultiplicityItems = false; } else{ - XWPFParagraph paragraph = addParagraphContent(format, mainDocumentPart, field.getViewStyle().getRenderStyle().equals("richTextarea") ? ParagraphStyle.HTML : ParagraphStyle.TEXT, numId, indent); - if(orcidResearcher){ - XWPFHyperlinkRun run = paragraph.createHyperlinkRun("https://orcid.org/" + orcId); - run.setText(orcId); - run.setUnderline(UnderlinePatterns.SINGLE); - run.setColor("0000FF"); - paragraph.createRun().setText(")"); - } - if (paragraph != null) { -// CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); -// number.setVal(BigInteger.valueOf(indent)); - hasValue = true; + createHypeLink(mainDocumentPart, format, value.get("pidTypeField"), value.get("pid"), false, false); + } + } + else{ + mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + List> values = new ArrayList<>(); + try { + values = Arrays.asList(mapper.readValue(field.getValue().toString(), HashMap[].class)); + } + catch (Exception e) { + Map map = new HashMap<>(); + map.put("label", field.getValue()); + values.add(map); + } + if (values.size() > 1) { + for (Map value : values) { + if(hasMultiplicityItems){ + createHypeLink(mainDocumentPart, (String) value.get("name"), (String) value.get("pidTypeField"), (String) value.get("pid"), true, true); + hasMultiplicityItems = false; + } + else{ + createHypeLink(mainDocumentPart, (String) value.get("name"), (String) value.get("pidTypeField"), (String) value.get("pid"), false, true); + } } } - format = null; + else if(values.size() == 1){ + if(hasMultiplicityItems){ + createHypeLink(mainDocumentPart, format, (String) values.get(0).get("pidTypeField"), (String) values.get(0).get("pid"), true, false); + hasMultiplicityItems = false; + } + else{ + createHypeLink(mainDocumentPart, format, (String) values.get(0).get("pidTypeField"), (String) values.get(0).get("pid"), false, false); + } + } + } + hasValue = true; + } + break; + default: + boolean isResearcher = field.getViewStyle().getRenderStyle().equals("researchers"); + if(format != null && !format.isEmpty()){ + Object hasMultiAutoComplete = mapper.convertValue(field.getData(), Map.class).get("multiAutoComplete"); + boolean isMultiAutoComplete = hasMultiAutoComplete != null && (boolean)hasMultiAutoComplete; + boolean arrayStringFormat = format.charAt(0) == '['; + if(arrayStringFormat || isMultiAutoComplete){ + List values = (arrayStringFormat) ? Arrays.asList(format.substring(1, format.length() - 1).split(",[ ]*")) : Arrays.asList(format.split(",[ ]*")); + if(values.size() > 1) { + boolean orcidResearcher; + for (String val : values) { + orcidResearcher = false; + String orcId = null; + if(isResearcher && val.contains("orcid:")){ + orcId = val.substring(val.indexOf(':') + 1, val.indexOf(')')); + val = val.substring(0, val.indexOf(':') + 1) + " "; + orcidResearcher = true; + } + format = "• " + val; + if(hasMultiplicityItems){ + mainDocumentPart.getLastParagraph().createRun().setText(format); + if(orcidResearcher){ + XWPFHyperlinkRun run = mainDocumentPart.getLastParagraph().createHyperlinkRun("https://orcid.org/" + orcId); + run.setText(orcId); + run.setUnderline(UnderlinePatterns.SINGLE); + run.setColor("0000FF"); + mainDocumentPart.getLastParagraph().createRun().setText(")"); + } + hasMultiplicityItems = false; + } + else{ + XWPFParagraph paragraph = addParagraphContent(format, mainDocumentPart, field.getViewStyle().getRenderStyle().equals("richTextarea") ? ParagraphStyle.HTML : ParagraphStyle.TEXT, numId, indent); + if(orcidResearcher){ + XWPFHyperlinkRun run = paragraph.createHyperlinkRun("https://orcid.org/" + orcId); + run.setText(orcId); + run.setUnderline(UnderlinePatterns.SINGLE); + run.setColor("0000FF"); + paragraph.createRun().setText(")"); + } + if (paragraph != null) { +// CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); +// number.setVal(BigInteger.valueOf(indent)); + hasValue = true; + } + } + format = null; + } + } + else if(values.size() == 1){ + format = values.get(0); + } } } - else if(values.size() == 1){ - format = values.get(0); + if (format != null) { + if (hasMultiplicityItems) { + mainDocumentPart.getLastParagraph().createRun().setText(format); + hasMultiplicityItems = false; + hasValue = true; + } + else { + XWPFParagraph paragraph = addParagraphContent(format, mainDocumentPart, field.getViewStyle().getRenderStyle().equals("richTextarea") ? ParagraphStyle.HTML : ParagraphStyle.TEXT, numId, indent); + if (paragraph != null) { +// CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); +// number.setVal(BigInteger.valueOf(indent)); + hasValue = true; + } + } } - } - } - if(hasMultiplicityItems && format != null){ - mainDocumentPart.getLastParagraph().createRun().setText(format); - hasMultiplicityItems = false; - hasValue = true; - } - else{ - XWPFParagraph paragraph = addParagraphContent(format, mainDocumentPart, field.getViewStyle().getRenderStyle().equals("richTextarea") ? ParagraphStyle.HTML : ParagraphStyle.TEXT, numId, indent); - if (paragraph != null) { -// CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); -// number.setVal(BigInteger.valueOf(indent)); - hasValue = true; - } } } } catch (IOException e) { @@ -881,7 +973,7 @@ public class WordBuilder { // logger.info("Reverting to custom parsing"); identifierData = customParse(field.getValue().toString()); } - return "id: " + identifierData.get("identifier") + ", Validation Type: " + identifierData.get("type"); + return "id: " + identifierData.get("identifier") + ", Type: " + identifierData.get("type"); } return ""; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/pid/PidLink.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/pid/PidLink.java new file mode 100644 index 000000000..bb0b83456 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/pid/PidLink.java @@ -0,0 +1,21 @@ +package eu.eudat.models.data.pid; + +public class PidLink { + + private String pid; + private String link; + + public String getPid() { + return pid; + } + public void setPid(String pid) { + this.pid = pid; + } + + public String getLink() { + return link; + } + public void setLink(String link) { + this.link = link; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/pid/PidLinks.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/pid/PidLinks.java new file mode 100644 index 000000000..4d1ffa3af --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/pid/PidLinks.java @@ -0,0 +1,16 @@ +package eu.eudat.models.data.pid; + +import java.util.ArrayList; +import java.util.List; + +public class PidLinks { + + private List pidLinks = new ArrayList<>(); + + public List getPidLinks() { + return pidLinks; + } + public void setPidLinks(List pidLinks) { + this.pidLinks = pidLinks; + } +} diff --git a/dmp-backend/web/src/main/resources/config/application-devel.properties b/dmp-backend/web/src/main/resources/config/application-devel.properties index 7156a62d5..372b55e17 100644 --- a/dmp-backend/web/src/main/resources/config/application-devel.properties +++ b/dmp-backend/web/src/main/resources/config/application-devel.properties @@ -27,6 +27,7 @@ configuration.semantics=Semantics.json configuration.h2020template=documents/h2020.docx configuration.h2020datasettemplate=documents/h2020_dataset.docx configuration.configurable_login_providers=configurableLoginProviders.json +configuration.pid_links=pidLinks.json ####################EMAIL FILE TEMPLATES OVERRIDES CONFIGURATIONS########## email.invite=classpath:templates/email/email.html diff --git a/dmp-backend/web/src/main/resources/config/application-docker.properties b/dmp-backend/web/src/main/resources/config/application-docker.properties index caeec702f..2c200ae68 100644 --- a/dmp-backend/web/src/main/resources/config/application-docker.properties +++ b/dmp-backend/web/src/main/resources/config/application-docker.properties @@ -26,6 +26,7 @@ configuration.externalUrls=externalUrls/ExternalUrls.xml configuration.h2020template=documents/h2020.docx configuration.h2020datasettemplate=documents/h2020_dataset.docx configuration.configurable_login_providers=configurableLoginProviders.json +configuration.pid_links=pidLinks.json ####################EMAIL FILE TEMPLATES OVERRIDES CONFIGURATIONS########## email.invite=classpath:templates/email/email.html diff --git a/dmp-backend/web/src/main/resources/config/application-production.properties b/dmp-backend/web/src/main/resources/config/application-production.properties index 61118ce55..87b5847bc 100644 --- a/dmp-backend/web/src/main/resources/config/application-production.properties +++ b/dmp-backend/web/src/main/resources/config/application-production.properties @@ -21,6 +21,7 @@ configuration.h2020template=documents/h2020.docx configuration.h2020datasettemplate=documents/h2020_dataset.docx configuration.configurable_login_providers=ConfigurableLoginProviders.json configuration.doi_funder=DOI_Funder.json +configuration.pid_links=pidLinks.json ####################SPRING MAIL CONFIGURATIONS################# spring.mail.default-encoding=UTF-8 diff --git a/dmp-backend/web/src/main/resources/config/application.properties b/dmp-backend/web/src/main/resources/config/application.properties index 0135ef7d6..0facad0ba 100644 --- a/dmp-backend/web/src/main/resources/config/application.properties +++ b/dmp-backend/web/src/main/resources/config/application.properties @@ -53,6 +53,7 @@ configuration.semantics=Semantics.json configuration.h2020template=documents/h2020.docx configuration.h2020datasettemplate=documents/h2020_dataset.docx configuration.configurable_login_providers=configurableLoginProviders.json +configuration.pid_links=pidLinks.json ####################EMAIL FILE TEMPLATES OVERRIDES CONFIGURATIONS########## email.invite=file:templates/email/email.html diff --git a/dmp-backend/web/src/main/resources/pidLinks.json b/dmp-backend/web/src/main/resources/pidLinks.json new file mode 100644 index 000000000..d2a011677 --- /dev/null +++ b/dmp-backend/web/src/main/resources/pidLinks.json @@ -0,0 +1,100 @@ +{ + "pidLinks": [ + { + "pid": "doi", + "link": "https://doi.org/{pid}" + }, + { + "pid": "uniprot", + "link": "https://uniprot.org/uniprotkb/{pid}" + }, + { + "pid": "handle", + "link": "https://hdl.handle.net/{pid}" + }, + { + "pid": "arxiv", + "link": "https://arxiv.org/abs/{pid}" + }, + { + "pid": "ascl", + "link": "https://ascl.net/{pid}" + }, + { + "pid": "orcid", + "link": "https://orcid.org/{pid}" + }, + { + "pid": "pmid", + "link": "https://pubmed.ncbi.nlm.nih.gov/{pid}" + }, + { + "pid": "ads", + "link": "https://ui.adsabs.harvard.edu/#abs/{pid}" + }, + { + "pid": "pmcid", + "link": "https://ncbi.nlm.nih.gov/pmc/{pid}" + }, + { + "pid": "gnd", + "link": "https://d-nb.info/gnd/{pid}" + }, + { + "pid": "urn", + "link": "https://nbn-resolving.org/{pid}" + }, + { + "pid": "sra", + "link": "https://ebi.ac.uk/ena/data/view/{pid}" + }, + { + "pid": "bioproject", + "link": "https://ebi.ac.uk/ena/data/view/{pid}" + }, + { + "pid": "biosample", + "link": "https://ebi.ac.uk/ena/data/view/{pid}" + }, + { + "pid": "ensembl", + "link": "https://ensembl.org/id/{pid}" + }, + { + "pid": "refseq", + "link": "https://ncbi.nlm.nih.gov/entrez/viewer.fcgi?val={pid}" + }, + { + "pid": "genome", + "link": "https://ncbi.nlm.nih.gov/assembly/{pid}" + }, + { + "pid": "geo", + "link": "https://ncbi.nlm.nih.gov/geo/query/acc.cgi?acc={pid}" + }, + { + "pid": "arrayexpress_array", + "link": "https://ebi.ac.uk/arrayexpress/arrays/{pid}" + }, + { + "pid": "arrayexpress_experiment", + "link": "https://ebi.ac.uk/arrayexpress/experiments/{pid}" + }, + { + "pid": "hal", + "link": "https://hal.archives-ouvertes.fr/{pid}" + }, + { + "pid": "swh", + "link": "https://archive.softwareheritage.org/{pid}" + }, + { + "pid": "ror", + "link": "https://ror.org/{pid}" + }, + { + "pid": "viaf", + "link": "https://viaf.org/viaf/{pid}" + } + ] +} \ No newline at end of file From dfa2f0cd38c28a3bdce35ed345f261fa783dc3ae Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Wed, 21 Jun 2023 12:05:51 +0300 Subject: [PATCH 006/110] #8737 - make elastic fetch 100 inner hits instead of the default 3. --- .../java/eu/eudat/elastic/repository/DatasetRepository.java | 4 ++-- .../src/main/resources/config/application-devel.properties | 1 + .../src/main/resources/config/application-docker.properties | 1 + .../main/resources/config/application-production.properties | 1 + .../web/src/main/resources/config/application.properties | 1 + 5 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java index dcc158405..dad039e94 100644 --- a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java @@ -146,7 +146,7 @@ public class DatasetRepository extends ElasticRepository 0) { searchSourceBuilder.size(criteria.getSize()); @@ -206,7 +206,7 @@ public class DatasetRepository extends ElasticRepository Date: Wed, 21 Jun 2023 12:17:22 +0300 Subject: [PATCH 007/110] bug fixes regarding tickets: #8739, #8763, #8833 --- .../elastic/repository/DatasetRepository.java | 7 +++ .../java/eu/eudat/controllers/Datasets.java | 3 +- .../eudat/logic/managers/DatasetManager.java | 28 +++++---- .../logic/proxy/fetching/RemoteFetcher.java | 61 +++++++++++-------- .../user/components/datasetprofile/Field.java | 2 +- .../models/rda/mapper/DatasetRDAMapper.java | 4 +- .../eudat/models/rda/mapper/DmpRDAMapper.java | 21 +++++-- .../core/model/dataset/dataset-id.model.ts | 11 +++- 8 files changed, 88 insertions(+), 49 deletions(-) diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java index dad039e94..8364d6c57 100644 --- a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java @@ -261,6 +261,7 @@ public class DatasetRepository extends ElasticRepository 0) { + criteria.setDatasetTemplates(criteria.getDatasetTemplates().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.template", criteria.getDatasetTemplates().stream().map(UUID::toString).collect(Collectors.toList()))); } @@ -269,14 +270,17 @@ public class DatasetRepository extends ElasticRepository 0) { + criteria.setDmps(criteria.getDmps().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.dmp", criteria.getDmps().stream().map(UUID::toString).collect(Collectors.toList()))); } if (criteria.getGroupIds() != null && criteria.getGroupIds().size() > 0) { + criteria.setGroupIds(criteria.getGroupIds().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.group", criteria.getGroupIds().stream().map(UUID::toString).collect(Collectors.toList()))); } if (criteria.getGrants() != null && criteria.getGrants().size() > 0) { + criteria.setGrants(criteria.getGrants().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.grant", criteria.getGrants().stream().map(UUID::toString).collect(Collectors.toList()))); } @@ -285,6 +289,7 @@ public class DatasetRepository extends ElasticRepository 0) { + criteria.setCollaborators(criteria.getCollaborators().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.collaborators.id.keyword", criteria.getCollaborators().stream().map(UUID::toString).collect(Collectors.toList()))); } @@ -295,10 +300,12 @@ public class DatasetRepository extends ElasticRepository 0) { + criteria.setOrganiztions(criteria.getOrganiztions().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.organizations.id", criteria.getOrganiztions())); } if (criteria.getTags() != null && criteria.getTags().size() > 0) { + criteria.setTags(criteria.getTags().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.tags.name", criteria.getTags().stream().map(Tag::getName).collect(Collectors.toList()))); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java index 8c5b003fa..4b4a79d1e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java @@ -256,7 +256,8 @@ public class Datasets extends BaseController { public @ResponseBody ResponseEntity> createOrUpdate(@RequestBody DatasetWizardModel profile, Principal principal) throws Exception { DatasetWizardModel dataset = new DatasetWizardModel().fromDataModel(this.datasetManager.createOrUpdate(profile, principal)); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(dataset)); + dataset.setTags(profile.getTags()); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(dataset)); } @Transactional diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index 875181cc7..9cc087e02 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -1143,19 +1143,21 @@ public class DatasetManager { if (!tagNodes.isEmpty()) { tagNodes.forEach(node -> { JsonNode value = node.get("value"); - if (!value.toString().equals("\"\"") && !value.toString().equals("null") && value.toString().startsWith("[")) { - String stringValue = value.toString().replaceAll("=", ":"); - JSONArray values = new JSONArray(stringValue); - values.iterator().forEachRemaining(element -> { - Map data = ((JSONObject) element).toMap(); - this.addTag(tags, wizardModel.getTags(), data.get("id").toString(), data.get("name").toString()); - }); - } else { - List values = Arrays.asList(value.textValue().split(", ")); - List tagValues = values.stream().map(stringValue -> new Tag(stringValue, stringValue)).collect(Collectors.toList()); - tagValues.iterator().forEachRemaining(tag -> { - this.addTag(tags, wizardModel.getTags(), tag.getId(), tag.getName()); - }); + if (!value.toString().equals("\"\"") && !value.toString().equals("null")) { + if (value.toString().startsWith("[")) { + String stringValue = value.toString().replaceAll("=", ":"); + JSONArray values = new JSONArray(stringValue); + values.iterator().forEachRemaining(element -> { + Map data = ((JSONObject) element).toMap(); + this.addTag(tags, wizardModel.getTags(), data.get("id").toString(), data.get("name").toString()); + }); + } else { + List values = Arrays.asList(value.textValue().split(", ")); + List tagValues = values.stream().map(stringValue -> new Tag(stringValue, stringValue)).collect(Collectors.toList()); + tagValues.iterator().forEachRemaining(tag -> { + this.addTag(tags, wizardModel.getTags(), tag.getId(), tag.getName()); + }); + } } }); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java index 6b9a8b9b5..77f05c1fc 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java @@ -271,6 +271,10 @@ public class RemoteFetcher { */ completedPath = completedPath.replace("{funderId}", funderId); } + else if(completedPath.contains("{funderId}")){ + logger.warn("FunderId is null."); + completedPath = completedPath.replace("{funderId}", " "); + } if (externalUrlCriteria.getPage() != null) { completedPath = completedPath.replace("{page}", externalUrlCriteria.getPage()); } else { @@ -305,33 +309,38 @@ public class RemoteFetcher { String replacedBody = replaceCriteriaOnUrl(requestBody, externalUrlCriteria, firstPage, queries); Results results = getResultsFromUrl(replacedPath, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType); - if(filterType != null && filterType.equals("local") && (externalUrlCriteria.getLike() != null && !externalUrlCriteria.getLike().isEmpty())){ - results.setResults(results.getResults().stream() - .filter(r -> r.get("name").toLowerCase().contains(externalUrlCriteria.getLike().toLowerCase())) - .collect(Collectors.toList())); + if(results != null) { + if (filterType != null && filterType.equals("local") && (externalUrlCriteria.getLike() != null && !externalUrlCriteria.getLike().isEmpty())) { + results.setResults(results.getResults().stream() + .filter(r -> r.get("name").toLowerCase().contains(externalUrlCriteria.getLike().toLowerCase())) + .collect(Collectors.toList())); + } + if (fetchStrategy == FetchStrategy.FIRST) + return results.getResults().stream().peek(x -> x.put("tag", tag)).peek(x -> x.put("key", key)).collect(Collectors.toList()); + + if (results.getPagination() != null && results.getPagination().get("pages") != null) //if has more pages, add them to the pages set + for (int i = 2; i <= results.getPagination().get("pages"); i++) + pages.add(i); + + Long maxResults = configLoader.getExternalUrls().getMaxresults(); + if ((maxResults > 0) && (results.getPagination().get("count") > maxResults)) + throw new HugeResultSet("The submitted search query " + externalUrlCriteria.getLike() + " is about to return " + results.getPagination().get("count") + " results... Please submit a more detailed search query"); + + Optional optionalResults = pages.parallelStream() + .map(page -> getResultsFromUrl(path + "&page=" + page, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType)) + .filter(Objects::nonNull) + .reduce((result1, result2) -> { + result1.getResults().addAll(result2.getResults()); + return result1; + }); + Results remainingResults = optionalResults.orElseGet(Results::new); + remainingResults.getResults().addAll(results.getResults()); + + return remainingResults.getResults().stream().peek(x -> x.put("tag", tag)).collect(Collectors.toList()); + } + else { + return new LinkedList<>(); } - if (fetchStrategy == FetchStrategy.FIRST) - return results == null ? new LinkedList<>() : results.getResults().stream().peek(x -> x.put("tag", tag)).peek(x -> x.put("key", key)).collect(Collectors.toList()); - - if (results != null && results.getPagination() != null && results.getPagination().get("pages") != null) //if has more pages, add them to the pages set - for (int i = 2; i <= results.getPagination().get("pages"); i++) - pages.add(i); - - Long maxResults = configLoader.getExternalUrls().getMaxresults(); - if ((maxResults > 0 && results != null) && (results.getPagination().get("count") > maxResults)) - throw new HugeResultSet("The submitted search query " + externalUrlCriteria.getLike() + " is about to return " + results.getPagination().get("count") + " results... Please submit a more detailed search query"); - - Optional optionalResults = pages.parallelStream() - .map(page -> getResultsFromUrl(path + "&page=" + page, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType)) - .filter(Objects::nonNull) - .reduce((result1, result2) -> { - result1.getResults().addAll(result2.getResults()); - return result1; - }); - Results remainingResults = optionalResults.orElseGet(Results::new); - remainingResults.getResults().addAll(results.getResults()); - - return remainingResults.getResults().stream().peek(x -> x.put("tag", tag)).collect(Collectors.toList()); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java index 46f11ded7..3a277ce3e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java @@ -256,7 +256,7 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin @Override public void toMap(Map fieldValues) { if (this.value != null) { - if ((this.viewStyle != null && this.viewStyle.getRenderStyle().equals("datasetIdentifier") || this.value instanceof Collection)) { + if ((this.viewStyle != null && this.viewStyle.getRenderStyle().equals("datasetIdentifier") && this.value instanceof Map || this.value instanceof Collection)) { ObjectMapper mapper = new ObjectMapper(); String valueString = null; try { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java index c1a2d9dbc..4bcf83017 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java @@ -347,7 +347,9 @@ public class DatasetRDAMapper { List tags = this.apiContext.getOperationsContext().getElasticRepository().getDatasetRepository().query(criteria).stream().map(eu.eudat.elastic.entities.Dataset::getTags).flatMap(Collection::stream).filter(StreamDistinctBy.distinctByKey(Tag::getId)).collect(Collectors.toList()); if(!rda.getKeyword().isEmpty()){ List templateTags = tags.stream().filter(tag -> rda.getKeyword().contains(tag.getName())).collect(Collectors.toList()); - properties.put(keywordIds.get(0), mapper.writeValueAsString(templateTags)); + if(!templateTags.isEmpty()) { + properties.put(keywordIds.get(0), mapper.writeValueAsString(templateTags)); + } // for (int i = 0; i < keywordIds.size(); i++) { // //if (takeAll) { // List tags = new ArrayList<>(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java index 66ceff6c3..2cf81d3bd 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java @@ -7,9 +7,12 @@ import eu.eudat.models.rda.Cost; import eu.eudat.models.rda.Dmp; import eu.eudat.models.rda.DmpId; import net.minidev.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import javax.persistence.NoResultException; import javax.transaction.Transactional; import java.io.IOException; import java.util.*; @@ -18,6 +21,8 @@ import java.util.stream.Collectors; @Component public class DmpRDAMapper { + private static final Logger logger = LoggerFactory.getLogger(DmpRDAMapper.class); + private DatasetRDAMapper datasetRDAMapper; private ApiContext apiContext; @@ -109,10 +114,16 @@ public class DmpRDAMapper { DMP entity = new DMP(); entity.setLabel(rda.getTitle()); if (rda.getDmpId().getType() == DmpId.Type.DOI) { - EntityDoi doi = apiContext.getOperationsContext().getDatabaseRepository().getEntityDoiDao().findFromDoi(rda.getDmpId().getIdentifier()); - Set dois = new HashSet<>(); - dois.add(doi); - entity.setDois(dois); + try { + EntityDoi doi = apiContext.getOperationsContext().getDatabaseRepository().getEntityDoiDao().findFromDoi(rda.getDmpId().getIdentifier()); + Set dois = new HashSet<>(); + dois.add(doi); + entity.setDois(dois); + } + catch (NoResultException e) { + logger.warn("No entity doi: " + rda.getDmpId().getIdentifier() + " found in database. No dois are added to dmp."); + entity.setDois(new HashSet<>()); + } } if (((List) rda.getAdditionalProperties().get("templates")) != null && !((List) rda.getAdditionalProperties().get("templates")).isEmpty()) { entity.setAssociatedDmps(((List) rda.getAdditionalProperties().get("templates")).stream().map(this::getProfile).filter(Objects::nonNull).collect(Collectors.toSet())); @@ -127,7 +138,7 @@ public class DmpRDAMapper { } } if (rda.getContributor() != null && !rda.getContributor().isEmpty() && rda.getContributor().get(0).getContributorId() != null) { - entity.setResearchers(rda.getContributor().stream().map(ContributorRDAMapper::toEntity).filter(StreamDistinctBy.distinctByKey(Researcher::getReference)).collect(Collectors.toSet())); + entity.setResearchers(rda.getContributor().stream().filter(r -> r.getContributorId() != null).map(ContributorRDAMapper::toEntity).filter(StreamDistinctBy.distinctByKey(Researcher::getReference)).collect(Collectors.toSet())); } entity.setCreated(rda.getCreated()); entity.setModified(rda.getModified()); diff --git a/dmp-frontend/src/app/core/model/dataset/dataset-id.model.ts b/dmp-frontend/src/app/core/model/dataset/dataset-id.model.ts index 9724ad28e..5cac63659 100644 --- a/dmp-frontend/src/app/core/model/dataset/dataset-id.model.ts +++ b/dmp-frontend/src/app/core/model/dataset/dataset-id.model.ts @@ -9,8 +9,15 @@ export class DatasetIdModel { try{ const parsed = JSON.parse(data); if (!isNullOrUndefined(parsed)) { - this.identifier = parsed.identifier; - this.type = parsed.type; + if(typeof parsed !== 'string'){ + this.identifier = parsed.identifier; + this.type = parsed.type; + } + else{ + const parsedObjectFromString = JSON.parse(parsed); + this.identifier = parsedObjectFromString.identifier; + this.type = parsedObjectFromString.type; + } } } catch(error){ From 3630727fed223639dca6b9e683ea516a902ba592 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Wed, 21 Jun 2023 12:20:30 +0300 Subject: [PATCH 008/110] dmp profile bug fixes: 1) dmp profile was not saved 2) if you select external autocomplete field and change it to another type, the external field was saved --- .../eu/eudat/logic/managers/DataManagementPlanManager.java | 4 ++++ .../dmp-profile/editor/dmp-profile-editor.component.ts | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index 4e38e6411..f767bc2dd 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -477,6 +477,10 @@ public class DataManagementPlanManager { } DMP newDmp = dataManagementPlan.toDataModel(); + if(dataManagementPlan.getProfile() != null){ + DMPProfile dmpProfile = apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().find(dataManagementPlan.getProfile().getId()); + newDmp.setProfile(dmpProfile); + } if (newDmp.getStatus() == (int) DMP.DMPStatus.FINALISED.getValue()) { checkDmpValidationRules(newDmp); } diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts index 5cd76ceda..55a0cff24 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts @@ -245,6 +245,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie this.addControl(formGroup); return true; } else { + this.removeControl(formGroup); return false; } } @@ -253,4 +254,9 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie if (formGroup.get('dataType').value == 3) formGroup.addControl('externalAutocomplete', new DmpProfileExternalAutoCompleteFieldDataEditorModel().buildForm()); } + + removeControl(formGroup: FormGroup) { + if (formGroup.get('dataType').value != 3) + formGroup.removeControl('externalAutocomplete'); + } } From 741179a53f2cc67fea4683c555ec37f52173da6c Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Wed, 21 Jun 2023 12:46:37 +0300 Subject: [PATCH 009/110] #8740 - multiple configuration for a deposit repository --- dmp-backend/web/pom.xml | 2 +- .../managers/DataManagementPlanManager.java | 18 ++++++----- .../eudat/logic/managers/DepositManager.java | 27 +++++++++++------ repo-jars/dataverse.json | 24 ++++++++------- repo-jars/zenodo.json | 30 ++++++++++--------- 5 files changed, 58 insertions(+), 43 deletions(-) diff --git a/dmp-backend/web/pom.xml b/dmp-backend/web/pom.xml index 3dbee2826..2e1e495d1 100644 --- a/dmp-backend/web/pom.xml +++ b/dmp-backend/web/pom.xml @@ -34,7 +34,7 @@ gr.cite.opendmp repositorydepositbase - 1.0.3 + 1.0.4 diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index f767bc2dd..df74d3258 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -2134,15 +2134,17 @@ public class DataManagementPlanManager { DMPDepositModel dmpDepositModel = DMPToDepositMapper.fromDMP(dmp, pdfEnvelope, rdaJsonFile, supportingFilesZip, previousDOI); - Optional repo = this.repositoriesDeposit.stream().filter(x -> x.getConfiguration().getRepositoryId().equals(depositRequest.getRepositoryId())).findFirst(); - String finalDoi = repo.map(r -> { - try { - return r.deposit(dmpDepositModel, depositRequest.getAccessToken()); - } catch (Exception e) { - logger.error(e.getMessage(), e); - return null; + String finalDoi = null; + for(RepositoryDeposit repo: this.repositoriesDeposit){ + if(repo.getConfiguration().stream().anyMatch(x-> x.getRepositoryId().equals(depositRequest.getRepositoryId()))){ + try { + finalDoi = repo.deposit(depositRequest.getRepositoryId(), dmpDepositModel, depositRequest.getAccessToken()); + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } } - }).orElse(null); + } Doi doiModel = null; if (finalDoi != null) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java index df71d4f65..fa8e20d42 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java @@ -31,18 +31,24 @@ public class DepositManager { public List getAvailableRepos() { List reposConfigModel = new ArrayList<>(); for (RepositoryDeposit r: this.repositories) { - RepositoryConfig repoModel = new RepositoryConfig(); - RepositoryDepositConfiguration repoConf = r.getConfiguration(); + List repoConf = r.getConfiguration(); if(repoConf != null) { - reposConfigModel.add(repoModel.toModel(repoConf)); + for(RepositoryDepositConfiguration cf: repoConf){ + RepositoryConfig repoModel = new RepositoryConfig(); + reposConfigModel.add(repoModel.toModel(cf)); + } } } return reposConfigModel; } public String authenticate(String id, String code) { - Optional repo = repositories.stream().filter(x -> x.getConfiguration().getRepositoryId().equals(id)).findFirst(); - return repo.map(repositoryDeposit -> repositoryDeposit.authenticate(code)).orElse(null); + for(RepositoryDeposit r: this.repositories){ + if(r.getConfiguration().stream().anyMatch(x -> x.getRepositoryId().equals(id))){ + return r.authenticate(id, code); + } + } + return null; } public Doi deposit(DepositRequest depositRequest, Principal principal) throws Exception { @@ -50,9 +56,12 @@ public class DepositManager { } public String getRepositoryLogo(String repositoryId){ - Optional repo = repositories.stream().filter(x -> x.getConfiguration().getRepositoryId().equals(repositoryId)).findFirst(); - return repo.map(repositoryDeposit -> - (repositoryDeposit.getConfiguration().isHasLogo()) ? repositoryDeposit.getLogo() : null - ).orElse(null); + for(RepositoryDeposit r: this.repositories){ + Optional cf = r.getConfiguration().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst(); + if(cf.isPresent()){ + return cf.get().isHasLogo() ? r.getLogo(repositoryId) : null; + } + } + return null; } } diff --git a/repo-jars/dataverse.json b/repo-jars/dataverse.json index 473d94515..680018a1c 100644 --- a/repo-jars/dataverse.json +++ b/repo-jars/dataverse.json @@ -1,11 +1,13 @@ -{ - "depositType": 0, - "repositoryId": "Dataverse", - "apiToken": "", - "repositoryUrl": "https://demo.dataverse.org/api/", - "repositoryRecordUrl": "https://demo.dataverse.org/dataset.xhtml?persistentId=doi:", - "server": "https://demo.dataverse.org", - "parentDataverseAlias": "test1000" - "parentDataverseAlias": "test1000", - "hasLogo": false -} \ No newline at end of file +[ + { + "depositType": 0, + "repositoryId": "Dataverse", + "apiToken": "", + "repositoryUrl": "https://demo.dataverse.org/api/", + "repositoryRecordUrl": "https://demo.dataverse.org/dataset.xhtml?persistentId=doi:", + "server": "https://demo.dataverse.org", + "parentDataverseAlias": "test1000", + "hasLogo": true, + "logo": "dataverse.png" + } +] \ No newline at end of file diff --git a/repo-jars/zenodo.json b/repo-jars/zenodo.json index cd77e1ed4..c81eaabc7 100644 --- a/repo-jars/zenodo.json +++ b/repo-jars/zenodo.json @@ -1,14 +1,16 @@ -{ - "depositType": 2, - "repositoryId": "Zenodo", - "accessToken": "", - "repositoryUrl": "https://sandbox.zenodo.org/api/", - "repositoryAuthorizationUrl": "https://sandbox.zenodo.org/oauth/authorize", - "repositoryRecordUrl": "https://sandbox.zenodo.org/record/", - "repositoryAccessTokenUrl": "https://sandbox.zenodo.org/oauth/token", - "repositoryClientId": "", - "repositoryClientSecret": "", - "redirectUri": "http://localhost:4200/login/external/zenodo" - "redirectUri": "http://localhost:4200/login/external/zenodo", - "hasLogo": true -} \ No newline at end of file +[ + { + "depositType": 2, + "repositoryId": "Zenodo", + "accessToken": "", + "repositoryUrl": "https://sandbox.zenodo.org/api/", + "repositoryAuthorizationUrl": "https://sandbox.zenodo.org/oauth/authorize", + "repositoryRecordUrl": "https://sandbox.zenodo.org/record/", + "repositoryAccessTokenUrl": "https://sandbox.zenodo.org/oauth/token", + "repositoryClientId": "", + "repositoryClientSecret": "", + "redirectUri": "http://localhost:4200/login/external/zenodo", + "hasLogo": true, + "logo": "zenodo.jpg" + } +] \ No newline at end of file From d996acdcc4a8b4d877cb739f473713c742a24cbb Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Wed, 21 Jun 2023 13:09:20 +0300 Subject: [PATCH 010/110] #8842 - add notification templates html files to application properties --- .../java/eu/eudat/logic/managers/NotificationManager.java | 8 ++++---- .../web/src/main/resources/config/application.properties | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/NotificationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/NotificationManager.java index f9c6403c7..a579d1870 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/NotificationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/NotificationManager.java @@ -60,20 +60,20 @@ public class NotificationManager { case DMP_MODIFIED: case DATASET_MODIFIED: subjectTemplate = this.environment.getProperty("notification.modified.subject"); - contentTemplate = mailService.getMailTemplateContent("classpath:templates/notifications/modifiedNotification.html"); + contentTemplate = mailService.getMailTemplateContent(this.environment.getProperty("notification.modified.template")); break; case DMP_PUBLISH: subjectTemplate = this.environment.getProperty("notification.publish.subject"); - contentTemplate = mailService.getMailTemplateContent("classpath:templates/notifications/publishNotification.html"); + contentTemplate = mailService.getMailTemplateContent(this.environment.getProperty("notification.publish.template")); break; case DMP_FINALISED: subjectTemplate = this.environment.getProperty("notification.finalised.subject"); - contentTemplate = mailService.getMailTemplateContent("classpath:templates/notifications/finalisedNotification.html"); + contentTemplate = mailService.getMailTemplateContent(this.environment.getProperty("notification.finalised.template")); break; case DMP_MODIFIED_FINALISED: case DATASET_MODIFIED_FINALISED: subjectTemplate = this.environment.getProperty("notification.modifiedFinalised.subject"); - contentTemplate = mailService.getMailTemplateContent("classpath:templates/notifications/modifiedFinalisedNotification.html"); + contentTemplate = mailService.getMailTemplateContent(this.environment.getProperty("notification.modified_finalised.template")); break; } diff --git a/dmp-backend/web/src/main/resources/config/application.properties b/dmp-backend/web/src/main/resources/config/application.properties index 8b4de3430..2ceb9e5ee 100644 --- a/dmp-backend/web/src/main/resources/config/application.properties +++ b/dmp-backend/web/src/main/resources/config/application.properties @@ -63,6 +63,12 @@ email.merge=file:templates/email/emailMergeConfirmation.html email.unlink=classpath:templates/email/emailUnlinkConfirmation.html email.dataset.template=file:templates/email/emailAdmin.html +##################NOTIFICATION FILE TEMPLATES OVERRIDES CONFIGURATIONS########## +notification.finalised.template=classpath:templates/notifications/finalisedNotification.html +notification.modified_finalised.template=classpath:templates/notifications/modifiedFinalisedNotification.html +notification.modified.template=classpath:templates/notifications/modifiedNotification.html +notification.publish.template=classpath:templates/notifications/publishNotification.html + #############LOGIN CONFIGURATIONS######### #############GENERIC LOGIN CONFIGURATIONS######### autouser.root.email= From cb972c394cf6d72d5277c67c81f0d707f7abf703 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Thu, 22 Jun 2023 13:47:01 +0300 Subject: [PATCH 011/110] change maDmpTarget type in prefilling to semanticTarget --- .../mapper/prefilling/PrefillingMapper.java | 6 +- .../entities/DefaultPrefillingMapping.java | 12 ++-- .../entities/PrefillingFixedMapping.java | 12 ++-- .../config/entities/PrefillingMapping.java | 4 +- .../resources/externalUrls/ExternalUrls.xml | 56 +++++++++---------- 5 files changed, 45 insertions(+), 45 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java index 9efc1e713..2ec8e9fd4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java @@ -112,11 +112,11 @@ public class PrefillingMapper { throw e; } } else { - List nodes = JsonSearcher.findNodes(parentNode, "schematics", "rda." + prefillingMapping.getMaDmpTarget()); + List nodes = JsonSearcher.findNodes(parentNode, "schematics", prefillingMapping.getSemanticTarget()); // zenodo prefilling customizations if(type.equals("zenodo")){ - if(prefillingMapping.getMaDmpTarget().equals("dataset.distribution.data_access")){ + if(prefillingMapping.getSemanticTarget().equals("rda.dataset.distribution.data_access")){ if(parsedValue != null && parsedValue.equals("open")){ List issuedNodes = JsonSearcher.findNodes(parentNode, "schematics", "rda.dataset.issued"); if(!issuedNodes.isEmpty()){ @@ -131,7 +131,7 @@ public class PrefillingMapper { } } - if (prefillingMapping.getMaDmpTarget().equals("dataset.distribution.available_until") && parsedValue != null && !parsedValue.equals("null")) { + if (prefillingMapping.getSemanticTarget().equals("rda.dataset.distribution.available_until") && parsedValue != null && !parsedValue.equals("null")) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd"); LocalDate date = LocalDate.parse(parsedValue, formatter); date = date.plusYears(20); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/DefaultPrefillingMapping.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/DefaultPrefillingMapping.java index 5fee3d153..4346796af 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/DefaultPrefillingMapping.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/DefaultPrefillingMapping.java @@ -7,7 +7,7 @@ import javax.xml.bind.annotation.XmlRootElement; public class DefaultPrefillingMapping implements PrefillingMapping{ private String source; private String target; - private String maDmpTarget; + private String semanticTarget; private String subSource; private String trimRegex; @@ -29,13 +29,13 @@ public class DefaultPrefillingMapping implements PrefillingMapping{ this.target = target; } - public String getMaDmpTarget() { - return maDmpTarget; + public String getSemanticTarget() { + return semanticTarget; } - @XmlAttribute(name = "maDmpTarget") - public void setMaDmpTarget(String maDmpTarget) { - this.maDmpTarget = maDmpTarget; + @XmlAttribute(name = "semanticTarget") + public void setSemanticTarget(String semanticTarget) { + this.semanticTarget = semanticTarget; } public String getSubSource() { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingFixedMapping.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingFixedMapping.java index 4514308f1..aa59f8386 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingFixedMapping.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingFixedMapping.java @@ -6,7 +6,7 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "fixedMapping") public class PrefillingFixedMapping implements PrefillingMapping{ private String target; - private String maDmpTarget; + private String semanticTarget; private String value; public String getTarget() { @@ -18,13 +18,13 @@ public class PrefillingFixedMapping implements PrefillingMapping{ this.target = target; } - public String getMaDmpTarget() { - return maDmpTarget; + public String getSemanticTarget() { + return semanticTarget; } - @XmlAttribute(name = "maDmpTarget") - public void setMaDmpTarget(String maDmpTarget) { - this.maDmpTarget = maDmpTarget; + @XmlAttribute(name = "semanticTarget") + public void setSemanticTarget(String semanticTarget) { + this.semanticTarget = semanticTarget; } @Override diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingMapping.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingMapping.java index 34f1ca95f..ae81f6176 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingMapping.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingMapping.java @@ -7,9 +7,9 @@ public interface PrefillingMapping { void setTarget(String target); - String getMaDmpTarget(); + String getSemanticTarget(); - void setMaDmpTarget(String maDmpTarget); + void setSemanticTarget(String semanticTarget); String getSubSource(); diff --git a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml index 5107fdb99..bdedc03a5 100644 --- a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml +++ b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml @@ -1224,38 +1224,38 @@ but not https://zenodo.org/api/records/{id} - + - - + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + From 469a8b4def5d897c394d84ea3bd7e4c26a7d0b1c Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Fri, 23 Jun 2023 10:33:58 +0300 Subject: [PATCH 012/110] add config properties to zenodo.json --- repo-jars/zenodo.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/repo-jars/zenodo.json b/repo-jars/zenodo.json index c81eaabc7..e957ab7a1 100644 --- a/repo-jars/zenodo.json +++ b/repo-jars/zenodo.json @@ -12,5 +12,10 @@ "redirectUri": "http://localhost:4200/login/external/zenodo", "hasLogo": true, "logo": "zenodo.jpg" + "logo": "zenodo.jpg", + "doiFunder": "DOI_Funder.json", + "community": "argos", + "affiliation": "ARGOS", + "domain": "https://argos.openaire.eu/" } ] \ No newline at end of file From 8fbc20c823b13fcab7a9d3c7e005ea40551e9d68 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Fri, 23 Jun 2023 10:43:03 +0300 Subject: [PATCH 013/110] no message --- repo-jars/zenodo.json | 1 - 1 file changed, 1 deletion(-) diff --git a/repo-jars/zenodo.json b/repo-jars/zenodo.json index e957ab7a1..3d5e3916c 100644 --- a/repo-jars/zenodo.json +++ b/repo-jars/zenodo.json @@ -11,7 +11,6 @@ "repositoryClientSecret": "", "redirectUri": "http://localhost:4200/login/external/zenodo", "hasLogo": true, - "logo": "zenodo.jpg" "logo": "zenodo.jpg", "doiFunder": "DOI_Funder.json", "community": "argos", From 1c0562d7e73d3538115674eadffe3539973ff675 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Mon, 26 Jun 2023 14:16:41 +0300 Subject: [PATCH 014/110] catch error when a field's external api is not available and interrupts prefilling process --- .../eudat/logic/mapper/prefilling/PrefillingMapper.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java index 2ec8e9fd4..a1fae4005 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java @@ -203,7 +203,13 @@ public class PrefillingMapper { AutoCompleteData autoCompleteData = mapper.treeToValue(dataNode, AutoCompleteData.class); isMultiSelect = autoCompleteData.getMultiAutoComplete(); for (String format : parsedValues) { - List result = DatasetProfileManager.getAutocomplete(autoCompleteData, format); + List result = new ArrayList<>(); + try { + result = DatasetProfileManager.getAutocomplete(autoCompleteData, format); + } + catch (Exception e) { + logger.error(e.getMessage(), e); + } result = result.stream().filter(StreamDistinctBy.distinctByKey(ExternalAutocompleteFieldModel::getId)).collect(Collectors.toList()); if(!result.isEmpty()){ List tempValues = new LinkedList<>(); From 000882cbdb416904ff5b29b6f1d051d9482111bd Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Mon, 3 Jul 2023 11:40:35 +0300 Subject: [PATCH 015/110] 1) fix bug when tags don't show after saving the dataset 2) save the email when user logs in with orcid 3) refactor unlink, delete credential of user to be unlinked --- .../eudat/logic/managers/DatasetManager.java | 32 +++++++++---------- .../managers/EmailConfirmationManager.java | 9 ++++++ .../UnlinkEmailConfirmationManager.java | 15 +-------- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index 9cc087e02..74fa3d3ce 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -289,14 +289,6 @@ public class DatasetManager { .stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()) .collect(Collectors.toList()).size() == 0 && !datasetEntity.getDmp().isPublic()) throw new UnauthorisedException(); - eu.eudat.elastic.entities.Dataset datasetElastic; - try { - datasetElastic = datasetRepository.exists() ? - datasetRepository.findDocument(id) : new eu.eudat.elastic.entities.Dataset(); - } catch (Exception ex) { - logger.warn(ex.getMessage()); - datasetElastic = null; - } dataset.setDatasetProfileDefinition(getPagedProfile(dataset, datasetEntity)); dataset.fromDataModel(datasetEntity); @@ -336,6 +328,14 @@ public class DatasetManager { boolean latestVersion = profile.getVersion().toString().equals(datasetEntity.getProfile().getVersion().toString()); dataset.setIsProfileLatestVersion(latestVersion); + eu.eudat.elastic.entities.Dataset datasetElastic; + try { + datasetElastic = datasetRepository.exists() ? + datasetRepository.findDocument(id) : new eu.eudat.elastic.entities.Dataset(); + } catch (Exception ex) { + logger.warn(ex.getMessage()); + datasetElastic = null; + } if (datasetElastic != null && datasetElastic.getTags() != null && !datasetElastic.getTags().isEmpty()) { dataset.setTags(datasetElastic.getTags()); } @@ -1034,14 +1034,6 @@ public class DatasetManager { public DatasetWizardModel datasetUpdateProfile(String id) { DatasetWizardModel dataset = new DatasetWizardModel(); eu.eudat.data.entities.Dataset datasetEntity = databaseRepository.getDatasetDao().find(UUID.fromString(id), HintedModelFactory.getHint(DatasetWizardModel.class)); - eu.eudat.elastic.entities.Dataset datasetElastic; - try { - datasetElastic = datasetRepository.exists() ? - datasetRepository.findDocument(id) : new eu.eudat.elastic.entities.Dataset(); - } catch (Exception ex) { - logger.warn(ex.getMessage()); - datasetElastic = null; - } dataset.setDatasetProfileDefinition(getPagedProfile(dataset, datasetEntity)); dataset.fromDataModel(datasetEntity); @@ -1062,6 +1054,14 @@ public class DatasetManager { // Now at latest version. dataset.setIsProfileLatestVersion(true); + eu.eudat.elastic.entities.Dataset datasetElastic; + try { + datasetElastic = datasetRepository.exists() ? + datasetRepository.findDocument(id) : new eu.eudat.elastic.entities.Dataset(); + } catch (Exception ex) { + logger.warn(ex.getMessage()); + datasetElastic = null; + } if (datasetElastic != null && datasetElastic.getTags() != null && !datasetElastic.getTags().isEmpty()) { dataset.setTags(datasetElastic.getTags()); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java index f6ad1d6fc..59200beb3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java @@ -48,6 +48,9 @@ public class EmailConfirmationManager { // Checks if mail is used by another user. If it is, merges the new the old. Long existingUsers = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).count(); if (existingUsers > 0) { + Credential credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), user)).getSingle(); + credential.setEmail(loginConfirmationEmail.getEmail()); + databaseRepository.getCredentialDao().createOrUpdate(credential); UserInfo oldUser = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).getSingle(); mergeNewUserToOld(user, oldUser); expireUserToken(user); @@ -57,6 +60,12 @@ public class EmailConfirmationManager { user.setEmail(loginConfirmationEmail.getEmail()); databaseRepository.getUserInfoDao().createOrUpdate(user); + Credential credential = databaseRepository.getCredentialDao().asQueryable() + .where((builder, root) -> builder.equal(root.get("userInfo"), user)).getSingle(); + if(credential.getEmail() == null){ + credential.setEmail(user.getEmail()); + databaseRepository.getCredentialDao().createOrUpdate(credential); + } databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java index 5785f1676..cf55ceaf9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java @@ -72,20 +72,7 @@ public class UnlinkEmailConfirmationManager { Credential credential = databaseRepository.getCredentialDao().asQueryable() .where((builder, root) -> builder.and(builder.equal(root.get("email"), emailTobeUnlinked), builder.equal(root.get("provider"), provider))).getSingle(); if(credential != null) { - UserInfo userTobeUnlinked = databaseRepository.getUserInfoDao().asQueryable() - .where((builder, root) -> builder.and(builder.equal(root.get("userStatus"), 1), builder.equal(root.get("name"), credential.getPublicValue()))).getSingle(); - userTobeUnlinked.setEmail(emailTobeUnlinked); - userTobeUnlinked.setUserStatus((short) 0); - databaseRepository.getUserInfoDao().createOrUpdate(userTobeUnlinked); - - credential.setUserInfo(userTobeUnlinked); - databaseRepository.getCredentialDao().createOrUpdate(credential); - - UserToken userToken = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserTokenBuilder.class) - .token(UUID.randomUUID()).user(userTobeUnlinked) - .expiresAt(Timestamp.valueOf(LocalDateTime.now().plusDays(10))).issuedAt(new Date()) - .build(); - apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().createOrUpdate(userToken); + databaseRepository.getCredentialDao().delete(credential); } } From 1a15e1ddde043c0eb41bf5614f12772863b47d82 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Mon, 3 Jul 2023 17:09:15 +0300 Subject: [PATCH 016/110] add missing logger to Prefilling Mapper --- .../eu/eudat/logic/mapper/prefilling/PrefillingMapper.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java index a1fae4005..a6b4d2ea3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java @@ -25,6 +25,8 @@ import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.externaldataset.ExternalAutocompleteFieldModel; import eu.eudat.models.data.license.LicenseModel; import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -34,6 +36,7 @@ import java.util.*; import java.util.stream.Collectors; public class PrefillingMapper { + private static final Logger logger = LoggerFactory.getLogger(PrefillingMapper.class); private static final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); public static DatasetWizardModel mapPrefilledEntityToDatasetWizard(Map prefilledEntity, PrefillingGet prefillingGet, String type, From a8ce14af700a036efbc54a8abb5f00d81037db2b Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Fri, 14 Jul 2023 13:47:01 +0300 Subject: [PATCH 017/110] #8726 - adding openaire prefilling --- .../eu/eudat/controllers/Prefillings.java | 11 +++- .../logic/managers/PrefillingManager.java | 35 ++++++++--- .../mapper/prefilling/PrefillingMapper.java | 13 +++- .../logic/proxy/config/UrlConfiguration.java | 9 +++ .../logic/proxy/fetching/RemoteFetcher.java | 59 +++++++++++++++++++ .../models/data/prefilling/Prefilling.java | 11 ++++ .../resources/externalUrls/ExternalUrls.xml | 48 ++++++++++++++- .../src/app/core/model/dataset/prefilling.ts | 1 + .../app/core/services/prefilling.service.ts | 8 ++- .../prefill-dataset.component.ts | 19 ++++-- 10 files changed, 192 insertions(+), 22 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Prefillings.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Prefillings.java index c6c3335d6..7d39c2630 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Prefillings.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Prefillings.java @@ -11,6 +11,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Map; import java.util.UUID; @RestController @@ -26,8 +27,8 @@ public class Prefillings { } @RequestMapping(method = RequestMethod.GET, value = {"/prefilling/list"}, produces = "application/json") - public ResponseEntity>> getPrefillingList(@RequestParam String like, @RequestParam String configId) { - List prefillingList = prefillingManager.getPrefillings(like, configId); + public ResponseEntity>> getPrefillingList(@RequestParam String like) { + List prefillingList = prefillingManager.getPrefillings(like); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().payload(prefillingList).status(ApiMessageCode.NO_MESSAGE)); } @@ -36,4 +37,10 @@ public class Prefillings { DatasetWizardModel datasetWizardModel = prefillingManager.getPrefilledDataset(id, configId, profileId); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(datasetWizardModel).status(ApiMessageCode.NO_MESSAGE)); } + + @RequestMapping(method = RequestMethod.POST, value = {"/prefilling/generateUsingData"}, produces = "application/json") + public ResponseEntity> getPrefillingDataset(@RequestBody Map data, @RequestParam String configId, @RequestParam UUID profileId) throws Exception { + DatasetWizardModel datasetWizardModel = prefillingManager.getPrefilledDatasetUsingData(data, configId, profileId); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(datasetWizardModel).status(ApiMessageCode.NO_MESSAGE)); + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java index 81d5fe3e0..e234ff300 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java @@ -1,5 +1,6 @@ package eu.eudat.logic.managers; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.DatasetProfile; import eu.eudat.logic.mapper.prefilling.PrefillingMapper; @@ -11,10 +12,7 @@ import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.prefilling.Prefilling; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; +import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @@ -34,17 +32,29 @@ public class PrefillingManager { public PrefillingManager(ApiContext apiContext, ConfigLoader configLoader, DatasetManager datasetManager, LicenseManager licenseManager) { this.apiContext = apiContext; this.configLoader = configLoader; - this.objectMapper = new ObjectMapper(); + this.objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); this.datasetManager = datasetManager; this.licenseManager = licenseManager; } - public List getPrefillings(String like, String configId) { - PrefillingConfig prefillingConfig = configLoader.getExternalUrls().getPrefillings().get(configId); + public List getPrefillings(String like) { ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(); externalUrlCriteria.setLike(like); - List> map = apiContext.getOperationsContext().getRemoteFetcher().getExternalGeneric(externalUrlCriteria, prefillingConfig.getPrefillingSearch()); - return map.stream().map(submap -> objectMapper.convertValue(submap, Prefilling.class)).collect(Collectors.toList()); + List prefillings = new ArrayList<>(); + List> map; + Map prefillingConfigs = configLoader.getExternalUrls().getPrefillings(); + for (PrefillingConfig prefillingConfig: prefillingConfigs.values()) { + map = apiContext.getOperationsContext().getRemoteFetcher().getExternalGeneric(externalUrlCriteria, prefillingConfig.getPrefillingSearch()); + prefillings.addAll(map.stream().map(submap -> objectMapper.convertValue(submap, Prefilling.class)).collect(Collectors.toList())); + if (prefillingConfig.getPrefillingSearch().getUrlConfig().isDataInListing()) { + List> mapData = apiContext.getOperationsContext().getRemoteFetcher().getExternalGenericWithData(externalUrlCriteria, prefillingConfig.getPrefillingSearch()); + for (int i = 0; i < mapData.size(); i++) { + prefillings.get(i).setData(mapData.get(i)); + } + prefillings = prefillings.stream().filter(prefilling -> prefilling.getData() != null).collect(Collectors.toList()); + } + } + return prefillings; } public DatasetWizardModel getPrefilledDataset(String prefillId, String configId, UUID profileId) throws Exception { @@ -55,6 +65,13 @@ public class PrefillingManager { return PrefillingMapper.mapPrefilledEntityToDatasetWizard(prefillingEntity, prefillingGet, prefillingConfig.getType(), datasetProfile, datasetManager, licenseManager); } + public DatasetWizardModel getPrefilledDatasetUsingData(Map data, String configId, UUID profileId) throws Exception { + PrefillingConfig prefillingConfig = configLoader.getExternalUrls().getPrefillings().get(configId); + PrefillingGet prefillingGet = prefillingConfig.getPrefillingGet(); + DatasetProfile datasetProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(profileId); + return PrefillingMapper.mapPrefilledEntityToDatasetWizard(data, prefillingGet, prefillingConfig.getType(), datasetProfile, datasetManager, licenseManager); + } + private Map getSingle(String url, String id) { RestTemplate restTemplate = new RestTemplate(); String parsedUrl = url.replace("{id}", id); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java index a6b4d2ea3..4c3a6653b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java @@ -107,7 +107,11 @@ public class PrefillingMapper { //GK: Tags Special logic if (parsedValue != null && !parsedValue.equals("null") && prefillingMapping.getTarget().equals("tags")) { parsedValue = mapper.valueToTree(parseTags(parsedValue)).toString(); - } else { + } + else if(!parsedValues.isEmpty() && prefillingMapping.getTarget().equals("tags")) { + parsedValue = mapper.valueToTree(parseTags(String.join(", ", parsedValues))).toString(); + } + else { parsedValue = mapper.valueToTree(parsedValue).toString(); } setterMethod.invoke(datasetWizardModel, mapper.readValue(parsedValue, params[0])); @@ -155,7 +159,12 @@ public class PrefillingMapper { } break; case TAGS: - properties.put(id, mapper.valueToTree(parseTags(parsedValue)).toString()); + if(parsedValues.isEmpty()) { + properties.put(id, mapper.valueToTree(parseTags(parsedValue)).toString()); + } + else { + properties.put(id, mapper.valueToTree(parseTags(String.join(", ", parsedValues))).toString()); + } break; case DATASET_IDENTIFIER: JSONObject datasetID = new JSONObject(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java index 232d619d1..50f2093fa 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java @@ -11,6 +11,7 @@ public class UrlConfiguration { private String label; private Integer ordinal; private String url; + private boolean dataInListing; private DataUrlConfiguration data; private String type; private String paginationPath; @@ -47,6 +48,14 @@ public class UrlConfiguration { this.url = url; } + public boolean isDataInListing() { + return dataInListing; + } + @XmlElement(name = "dataInListing") + public void setDataInListing(boolean dataInListing) { + this.dataInListing = dataInListing; + } + public Integer getOrdinal() { return ordinal; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java index 77f05c1fc..c77964083 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java @@ -179,6 +179,10 @@ public class RemoteFetcher { return getAll(urlConfigurations, fetchStrategy, externalUrlCriteria); } + public List> getExternalGenericWithData(ExternalUrlCriteria externalUrlCriteria, GenericUrls genericUrls) { + List urlConfigurations = genericUrls.getUrls(); + return getAllWithData(urlConfigurations, externalUrlCriteria); + } private List> getAll(List urlConfigs, FetchStrategy fetchStrategy, ExternalUrlCriteria externalUrlCriteria) { @@ -213,6 +217,29 @@ public class RemoteFetcher { return results; } + private List> getAllWithData(List urlConfigs, ExternalUrlCriteria externalUrlCriteria) { + + List> results = new LinkedList<>(); + + if (urlConfigs == null || urlConfigs.isEmpty()) { + return results; + } + + urlConfigs.sort(Comparator.comparing(UrlConfiguration::getOrdinal)); + urlConfigs.forEach(urlConfiguration -> { + ifFunderQueryExist(urlConfiguration, externalUrlCriteria); + if (urlConfiguration.getType() == null || urlConfiguration.getType().equals("External")) { + try { + results.addAll(getAllResultsFromUrlWithData(urlConfiguration.getUrl(), urlConfiguration.getData(), externalUrlCriteria, urlConfiguration.getContentType(), urlConfiguration.getFirstpage(), urlConfiguration.getRequestBody(), urlConfiguration.getRequestType(), urlConfiguration.getQueries())); + } catch (Exception e) { + logger.error(e.getLocalizedMessage(), e); + } + } + }); + return results; + + } + private void ifFunderQueryExist(UrlConfiguration urlConfiguration, ExternalUrlCriteria externalUrlCriteria) { if (urlConfiguration.getFunderQuery() != null) { if (externalUrlCriteria.getFunderId() != null && !urlConfiguration.getFunderQuery().startsWith("dmp:")) { @@ -343,6 +370,38 @@ public class RemoteFetcher { } } + private List> getAllResultsFromUrlWithData(String path, final DataUrlConfiguration jsonDataPath, ExternalUrlCriteria externalUrlCriteria, String contentType, String firstPage, String requestBody, String requestType, List queries) { + + String replacedPath = replaceCriteriaOnUrl(path, externalUrlCriteria, firstPage, queries); + String replacedBody = replaceCriteriaOnUrl(requestBody, externalUrlCriteria, firstPage, queries); + + try { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + HttpEntity entity; + ResponseEntity response; + if (contentType != null && !contentType.isEmpty()) { + headers.setAccept(Collections.singletonList(MediaType.valueOf(contentType))); + headers.setContentType(MediaType.valueOf(contentType)); + } + JsonNode jsonBody = new ObjectMapper().readTree(replacedBody); + entity = new HttpEntity<>(jsonBody, headers); + + response = restTemplate.exchange(replacedPath, HttpMethod.resolve(requestType), entity, String.class); + if (response.getStatusCode() == HttpStatus.OK) { + if (response.getHeaders().get("Content-Type").get(0).contains("json")) { + DocumentContext jsonContext = JsonPath.parse(response.getBody()); + return jsonContext.read(jsonDataPath.getPath()); + } + } + } + catch (Exception exception) { + logger.error(exception.getMessage(), exception); + } + + return new LinkedList<>(); + } + protected Results getResultsFromUrl(String urlString, DataUrlConfiguration jsonDataPath, String jsonPaginationPath, String contentType, String requestBody, String requestType) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java index 6c09e6b2e..67babe9de 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java @@ -1,8 +1,11 @@ package eu.eudat.models.data.prefilling; +import java.util.Map; + public class Prefilling { private String pid; private String name; + private Map data; private String tag; public String getPid() { @@ -21,6 +24,14 @@ public class Prefilling { this.name = name; } + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + public String getTag() { return tag; } diff --git a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml index bdedc03a5..95aaac7fa 100644 --- a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml +++ b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml @@ -1203,10 +1203,11 @@ but not zenodo - + 1 External https://zenodo.org/api/records/?page={page}&size={pageSize}&q=title:"{like}" doi:"{like}" conceptdoi:"{like}" + false 1 application/json @@ -1259,6 +1260,51 @@ but not + + + + openaire + + 1 + External + https://services.openaire.eu/search/v2/api/datasets/?q={like}&page={page}&size={pageSize}&format=json + true + 0 + application/json + + $['results'][*]['result']['metadata']['oaf:entity']['oaf:result'] + + 'originalId' + 'title' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dmp-frontend/src/app/core/model/dataset/prefilling.ts b/dmp-frontend/src/app/core/model/dataset/prefilling.ts index cc3e36a4b..1b5b93538 100644 --- a/dmp-frontend/src/app/core/model/dataset/prefilling.ts +++ b/dmp-frontend/src/app/core/model/dataset/prefilling.ts @@ -1,5 +1,6 @@ export interface Prefilling { pid: string; name: string; + data: any; tag: string; } diff --git a/dmp-frontend/src/app/core/services/prefilling.service.ts b/dmp-frontend/src/app/core/services/prefilling.service.ts index 3d5527303..fa940a1f6 100644 --- a/dmp-frontend/src/app/core/services/prefilling.service.ts +++ b/dmp-frontend/src/app/core/services/prefilling.service.ts @@ -15,11 +15,15 @@ export class PrefillingService { this.actionUrl = configurationService.server + 'prefilling/'; } - public getPrefillingList(like: string, configId: string): Observable { - return this.http.get(this.actionUrl + 'list?configId=' + encodeURIComponent(configId) + '&like=' + encodeURIComponent(like), { headers: this.headers }); + public getPrefillingList(like: string): Observable { + return this.http.get(this.actionUrl + 'list?like=' + encodeURIComponent(like), { headers: this.headers }); } public getPrefillingDataset(pid: string, profileId: string, configId: string): Observable { return this.http.get(this.actionUrl + '/generate/' + encodeURIComponent(pid) + '?configId=' + encodeURIComponent(configId) + '&profileId=' + encodeURIComponent(profileId), { headers: this.headers }); } + + public getPrefillingDatasetUsingData(data: any, profileId: string, configId: string): Observable { + return this.http.post(this.actionUrl + '/generateUsingData' + '?configId=' + encodeURIComponent(configId) + '&profileId=' + encodeURIComponent(profileId), data, { headers: this.headers }); + } } diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts index 3d21e286e..e46a2b184 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts @@ -18,7 +18,6 @@ export class PrefillDatasetComponent extends BaseComponent implements OnInit { progressIndication = false; prefillAutoCompleteConfiguration: SingleAutoCompleteConfiguration; - configId: string = "zenodo"; isPrefilled: boolean = false; prefillForm: FormGroup; @@ -56,7 +55,7 @@ export class PrefillDatasetComponent extends BaseComponent implements OnInit { } searchDatasets(query: string): Observable { - return this.prefillingService.getPrefillingList(query, this.configId).pipe(map(prefilling => prefilling.sort((a, b) => { + return this.prefillingService.getPrefillingList(query).pipe(map(prefilling => prefilling.sort((a, b) => { if(a.name > b.name) { return 1; } else if(a.name < b.name) { @@ -69,10 +68,18 @@ export class PrefillDatasetComponent extends BaseComponent implements OnInit { next() { if(this.isPrefilled) { - this.prefillingService.getPrefillingDataset(this.prefillForm.get('prefill').value.pid, this.prefillForm.get('profile').value.id, this.configId).subscribe(wizard => { - wizard.profile = this.prefillForm.get('profile').value; - this.closeDialog(wizard); - }) + if(this.prefillForm.get('prefill').value.data == null) { + this.prefillingService.getPrefillingDataset(this.prefillForm.get('prefill').value.pid, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.tag).subscribe(wizard => { + wizard.profile = this.prefillForm.get('profile').value; + this.closeDialog(wizard); + }); + } + else { + this.prefillingService.getPrefillingDatasetUsingData(this.prefillForm.get('prefill').value.data, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.tag).subscribe(wizard => { + wizard.profile = this.prefillForm.get('profile').value; + this.closeDialog(wizard); + }); + } } else { this.closeDialog(); } From 1715463422e3112b125daece4b90a8858b4f816a Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Fri, 14 Jul 2023 13:56:08 +0300 Subject: [PATCH 018/110] fix bugs in rda json export when rda semantics don't correspond to valid dataset field input type --- .../models/rda/mapper/CostRDAMapper.java | 22 ++++++++++--- .../models/rda/mapper/DatasetIdRDAMapper.java | 12 ++++++- .../models/rda/mapper/DatasetRDAMapper.java | 14 ++++++++- .../rda/mapper/DistributionRDAMapper.java | 13 ++++++-- .../eudat/models/rda/mapper/DmpRDAMapper.java | 1 - .../models/rda/mapper/HostRDAMapper.java | 31 +++++++++++++++---- .../models/rda/mapper/LicenseRDAMapper.java | 4 +++ .../models/rda/mapper/MetadataRDAMapper.java | 3 ++ .../mapper/SecurityAndPrivacyRDAMapper.java | 4 +++ .../mapper/TechnicalResourceRDAMapper.java | 4 +++ 10 files changed, 93 insertions(+), 15 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java index 0c6a340f8..6f31e570e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java @@ -6,6 +6,7 @@ import java.util.stream.Collectors; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.json.JavaToJson; import eu.eudat.models.rda.Cost; import eu.eudat.models.rda.PidSystem; @@ -34,11 +35,14 @@ public class CostRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dmp.cost")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ @@ -64,12 +68,22 @@ public class CostRDAMapper { rdaMap.put(key, rda); } if(rdaProperty.contains("value")){ - rda.setValue(Double.valueOf(rdaValue)); + try { + rda.setValue(Double.valueOf(rdaValue)); + } + catch (NumberFormatException e) { + logger.warn("Dmp cost value " + rdaValue + " is not valid. Cost value will not be set."); + } } else if(rdaProperty.contains("currency_code")){ - HashMap result = - new ObjectMapper().readValue(rdaValue, HashMap.class); - rda.setCurrencyCode(Cost.CurrencyCode.fromValue(result.get("value"))); + try { + HashMap result = + new ObjectMapper().readValue(rdaValue, HashMap.class); + rda.setCurrencyCode(Cost.CurrencyCode.fromValue(result.get("value"))); + } + catch (Exception e) { + logger.warn("Dmp cost currency code is not valid and will not be set."); + } } else if(rdaProperty.contains("title")){ Iterator iter = node.get("value").elements(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java index f3e690e75..50d535348 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java @@ -2,6 +2,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.json.JsonSearcher; import eu.eudat.models.rda.DatasetId; import org.slf4j.Logger; @@ -30,11 +31,14 @@ public class DatasetIdRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.dataset_id")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ @@ -76,7 +80,13 @@ public class DatasetIdRDAMapper { rda.setIdentifier(value); break; case TYPE: - rda.setType(DatasetId.Type.fromValue(value)); + try { + rda.setType(DatasetId.Type.fromValue(value)); + } + catch (IllegalArgumentException e){ + logger.warn("Type " + value + " from semantic rda.dataset.dataset_id.type was not found. Setting type to OTHER."); + rda.setType(DatasetId.Type.OTHER); + } break; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java index 4bcf83017..d7b29e2b3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java @@ -3,6 +3,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.DatasetProfile; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.elastic.criteria.DatasetCriteria; import eu.eudat.elastic.entities.Tag; import eu.eudat.logic.managers.DatasetManager; @@ -74,7 +75,14 @@ public class DatasetRDAMapper { } List languageNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.language"); if (!languageNodes.isEmpty() && !languageNodes.get(0).get("value").asText().isEmpty()) { - rda.setLanguage(Language.fromValue(languageNodes.get(0).get("value").asText())); + String lang = languageNodes.get(0).get("value").asText(); + try { + rda.setLanguage(Language.fromValue(lang)); + } + catch (IllegalArgumentException e){ + logger.warn("Language " + lang + " from semantic rda.dataset.language was not found. Setting '" + dataset.getProfile().getLanguage() +"' as language from the dataset profile."); + rda.setLanguage(LanguageRDAMapper.mapLanguageIsoToRDAIso(dataset.getProfile().getLanguage())); + } } else { rda.setLanguage(LanguageRDAMapper.mapLanguageIsoToRDAIso(dataset.getProfile().getLanguage())); } @@ -188,6 +196,7 @@ public class DatasetRDAMapper { return Collections.singletonList(new Contributor()); } }).flatMap(Collection::stream).collect(Collectors.toList())); + dmp.setContributor(dmp.getContributor().stream().filter(contributor -> contributor.getContributorId() != null && contributor.getName() != null).collect(Collectors.toList())); } List costNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dmp.cost"); if (!costNodes.isEmpty()) { @@ -199,11 +208,14 @@ public class DatasetRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dmp.ethical_issues")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java index 547927c94..046d73d91 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.helpers.MyStringUtils; import eu.eudat.logic.utilities.json.JavaToJson; import eu.eudat.logic.utilities.json.JsonSearcher; @@ -74,8 +75,13 @@ public class DistributionRDAMapper { } break; case DATA_ACCESS: - rda.setDataAccess(Distribution.DataAccess.fromValue(rdaValue)); - rda.setAdditionalProperty(ImportPropertyName.DATA_ACCESS.getName(), node.get("id").asText()); + try { + rda.setDataAccess(Distribution.DataAccess.fromValue(rdaValue)); + rda.setAdditionalProperty(ImportPropertyName.DATA_ACCESS.getName(), node.get("id").asText()); + } + catch (IllegalArgumentException e) { + logger.warn("Distribution data access " + rdaValue + " from semantic distribution.data_access is not valid. Data access will not be set set."); + } break; case BYTE_SIZE: rda.setByteSize(Integer.parseInt(rdaValue)); @@ -376,11 +382,14 @@ public class DistributionRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.distribution")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } return rdaProperty; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java index 2cf81d3bd..2b3a2f61a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java @@ -3,7 +3,6 @@ package eu.eudat.models.rda.mapper; import eu.eudat.data.entities.*; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.utilities.helpers.StreamDistinctBy; -import eu.eudat.models.rda.Cost; import eu.eudat.models.rda.Dmp; import eu.eudat.models.rda.DmpId; import net.minidev.json.JSONObject; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java index ca69c5cfb..74e5c2e64 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java @@ -3,6 +3,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.helpers.MyStringUtils; import eu.eudat.models.rda.Host; import eu.eudat.models.rda.PidSystem; @@ -22,11 +23,14 @@ public class HostRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.distribution.host")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ @@ -55,8 +59,13 @@ public class HostRDAMapper { rda.setAdditionalProperty(ImportPropertyName.BACKUP_TYPE.getName(), node.get("id").asText()); break; case CERTIFIED_WITH: - rda.setCertifiedWith(Host.CertifiedWith.fromValue(rdaValue)); - rda.setAdditionalProperty(ImportPropertyName.CERTIFIED_WITH.getName(), node.get("id").asText()); + try { + rda.setCertifiedWith(Host.CertifiedWith.fromValue(rdaValue)); + rda.setAdditionalProperty(ImportPropertyName.CERTIFIED_WITH.getName(), node.get("id").asText()); + } + catch (IllegalArgumentException e) { + logger.warn("Distribution host certified with " + rdaValue + "from semantic distribution.host.certified_with is not valid. Certified_with will not be set set."); + } break; case DESCRIPTION: rda.setDescription(rdaValue); @@ -70,8 +79,13 @@ public class HostRDAMapper { logger.warn(e.getLocalizedMessage() + ". Try to pass value as is"); } } - rda.setGeoLocation(Host.GeoLocation.fromValue(rdaValue)); - rda.setAdditionalProperty(ImportPropertyName.GEO_LOCATION.getName(), node.get("id").asText()); + try { + rda.setGeoLocation(Host.GeoLocation.fromValue(rdaValue)); + rda.setAdditionalProperty(ImportPropertyName.GEO_LOCATION.getName(), node.get("id").asText()); + } + catch (IllegalArgumentException e) { + logger.warn("Distribution host geo location " + rdaValue + "from semantic distribution.host.geo_location is not valid. Geo location will not be set set."); + } break; case PID_SYSTEM: try{ @@ -101,8 +115,13 @@ public class HostRDAMapper { rda.setAdditionalProperty(ImportPropertyName.STORAGE_TYPE.getName(), node.get("id").asText()); break; case SUPPORT_VERSIONING: - rda.setSupportVersioning(Host.SupportVersioning.fromValue(rdaValue)); - rda.setAdditionalProperty(ImportPropertyName.SUPPORT_VERSIONING.getName(), node.get("id").asText()); + try { + rda.setSupportVersioning(Host.SupportVersioning.fromValue(rdaValue)); + rda.setAdditionalProperty(ImportPropertyName.SUPPORT_VERSIONING.getName(), node.get("id").asText()); + } + catch (IllegalArgumentException e) { + logger.warn("Distribution host support versioning " + rdaValue + "from semantic distribution.host.support_versioning is not valid. Support versioning will not be set set."); + } break; case TITLE: rda.setTitle(rdaValue); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java index 8b2cc84e3..d7e178c14 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java @@ -1,6 +1,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.json.JsonSearcher; import eu.eudat.models.rda.License; import org.slf4j.Logger; @@ -20,11 +21,14 @@ public class LicenseRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.distribution.license")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java index fd9eb1d13..e8c28b7bb 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java @@ -23,11 +23,14 @@ public class MetadataRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.metadata")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java index 85f494917..1d560b91b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java @@ -1,6 +1,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.helpers.MyStringUtils; import eu.eudat.models.rda.SecurityAndPrivacy; import org.slf4j.Logger; @@ -19,11 +20,14 @@ public class SecurityAndPrivacyRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.security_and_privacy")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java index 709ee5ef3..31ad744fe 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java @@ -1,6 +1,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.helpers.MyStringUtils; import eu.eudat.models.rda.TechnicalResource; import org.slf4j.Logger; @@ -19,11 +20,14 @@ public class TechnicalResourceRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.technical_resource")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ From dd6a2a0df70c942271d0be5ea369f502b8768d68 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Mon, 17 Jul 2023 10:29:06 +0300 Subject: [PATCH 019/110] adding key property in the prefilling model as the identifier of the prefilling repository --- .../eu/eudat/logic/proxy/fetching/RemoteFetcher.java | 2 +- .../java/eu/eudat/models/data/prefilling/Prefilling.java | 9 +++++++++ .../web/src/main/resources/externalUrls/ExternalUrls.xml | 4 ++-- dmp-frontend/src/app/core/model/dataset/prefilling.ts | 1 + .../prefill-dataset/prefill-dataset.component.ts | 4 ++-- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java index c77964083..4d228e7b7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java @@ -363,7 +363,7 @@ public class RemoteFetcher { Results remainingResults = optionalResults.orElseGet(Results::new); remainingResults.getResults().addAll(results.getResults()); - return remainingResults.getResults().stream().peek(x -> x.put("tag", tag)).collect(Collectors.toList()); + return remainingResults.getResults().stream().peek(x -> x.put("tag", tag)).peek(x -> x.put("key", key)).collect(Collectors.toList()); } else { return new LinkedList<>(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java index 67babe9de..873c59e34 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java @@ -6,6 +6,7 @@ public class Prefilling { private String pid; private String name; private Map data; + private String key; private String tag; public String getPid() { @@ -32,6 +33,14 @@ public class Prefilling { this.data = data; } + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + public String getTag() { return tag; } diff --git a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml index 95aaac7fa..4281c6d37 100644 --- a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml +++ b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml @@ -1203,7 +1203,7 @@ but not zenodo - + 1 External https://zenodo.org/api/records/?page={page}&size={pageSize}&q=title:"{like}" doi:"{like}" conceptdoi:"{like}" @@ -1264,7 +1264,7 @@ but not openaire - + 1 External https://services.openaire.eu/search/v2/api/datasets/?q={like}&page={page}&size={pageSize}&format=json diff --git a/dmp-frontend/src/app/core/model/dataset/prefilling.ts b/dmp-frontend/src/app/core/model/dataset/prefilling.ts index 1b5b93538..978dfe1eb 100644 --- a/dmp-frontend/src/app/core/model/dataset/prefilling.ts +++ b/dmp-frontend/src/app/core/model/dataset/prefilling.ts @@ -2,5 +2,6 @@ export interface Prefilling { pid: string; name: string; data: any; + key: string; tag: string; } diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts index e46a2b184..999f51668 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.ts @@ -69,13 +69,13 @@ export class PrefillDatasetComponent extends BaseComponent implements OnInit { next() { if(this.isPrefilled) { if(this.prefillForm.get('prefill').value.data == null) { - this.prefillingService.getPrefillingDataset(this.prefillForm.get('prefill').value.pid, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.tag).subscribe(wizard => { + this.prefillingService.getPrefillingDataset(this.prefillForm.get('prefill').value.pid, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.key).subscribe(wizard => { wizard.profile = this.prefillForm.get('profile').value; this.closeDialog(wizard); }); } else { - this.prefillingService.getPrefillingDatasetUsingData(this.prefillForm.get('prefill').value.data, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.tag).subscribe(wizard => { + this.prefillingService.getPrefillingDatasetUsingData(this.prefillForm.get('prefill').value.data, this.prefillForm.get('profile').value.id, this.prefillForm.get('prefill').value.key).subscribe(wizard => { wizard.profile = this.prefillForm.get('profile').value; this.closeDialog(wizard); }); From aec7126fd3e4e44674024c1557893fdf4536a7a6 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Mon, 17 Jul 2023 16:34:43 +0300 Subject: [PATCH 020/110] Add valid condition in progress calculatiion of a form --- .../form-progress-indication.component.ts | 9 +++------ .../components/form-section/form-section.component.ts | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts index 25691b74f..3cf3158d3 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts @@ -51,7 +51,7 @@ export class FormProgressIndicationComponent extends BaseComponent implements On let valueCurent = 0; if (formControl instanceof FormGroup) { if (this.checkFormsIfIsFieldsAndVisible(formControl) && this.checkIfIsRequired((formControl as FormGroup))) { - if (this.haseValue(formControl)) + if (this.hasValue(formControl)) valueCurent++; } if (this.chechFieldIfIsFieldSetAndVisible((formControl as FormGroup)) && this.checkIfIsRequired((formControl as FormGroup))) { @@ -69,11 +69,8 @@ export class FormProgressIndicationComponent extends BaseComponent implements On } return valueCurent; } - private haseValue(formGroup: FormGroup): boolean { - if (formGroup.get('value').value != null && formGroup.get('value').value !== '' && this.visibilityRulesService.checkElementVisibility(formGroup.get('id').value)) { - return true; - } - return false; + private hasValue(formGroup: FormGroup): boolean { + return formGroup.get('value').valid && formGroup.get('value').value != null && formGroup.get('value').value !== '' && this.visibilityRulesService.checkElementVisibility(formGroup.get('id').value); } private compositeFieldsGetChildsForProgress(formGroup: FormGroup): number { diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts index c7ca771b8..f04760f7d 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts @@ -158,7 +158,6 @@ export class FormSectionComponent extends BaseComponent implements OnInit, OnCha const outerRules = (this.visibilityRulesService.getVisibilityDependency(target) as VisibilityRuleSource[]).filter(x => x.sourceControlId === element.id); const updatedRules = outerRules.map(x => { - console.log(idMappings, element); return {...x, sourceControlId: idMappings.find(y => y.old === element.id).new}; }); From 7bc4f4055cd228c5974ccbe3d4fa91e9b6a3c897 Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Mon, 17 Jul 2023 17:38:25 +0300 Subject: [PATCH 021/110] Fix progress indicator in prifilled dataset form. #8764 --- .../form-progress-indication.component.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts index 3cf3158d3..cf953e754 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, Input, OnInit } from '@angular/core'; +import {ChangeDetectorRef, Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core'; import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms'; import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service'; import { BaseComponent } from '@common/base/base.component'; @@ -9,7 +9,7 @@ import { takeUntil } from 'rxjs/operators'; templateUrl: './form-progress-indication.component.html', styleUrls: ['./form-progress-indication.component.scss'] }) -export class FormProgressIndicationComponent extends BaseComponent implements OnInit { +export class FormProgressIndicationComponent extends BaseComponent implements OnInit, OnChanges { @Input() formGroup: FormGroup; @Input() isDmpEditor: boolean; @Input() isDatasetEditor: boolean; @@ -23,6 +23,16 @@ export class FormProgressIndicationComponent extends BaseComponent implements On public value = 0; ngOnInit() { + this.init(); + } + + ngOnChanges(changes: SimpleChanges) { + if(changes.formGroup) { + this.init(); + } + } + + init() { setTimeout(() => {this.calculateValueForProgressbar();}); this.formGroup .valueChanges @@ -143,7 +153,7 @@ export class FormProgressIndicationComponent extends BaseComponent implements On countFormControlsValidForProgress(formControl: AbstractControl): number { let valueCurrent = 0; if (formControl instanceof FormControl) { - if (this.controlRequired(formControl) && this.controlEnabled(formControl) && formControl['nativeElement'] && formControl.valid) { + if (this.controlRequired(formControl) && this.controlEnabled(formControl) && formControl.valid) { valueCurrent++; } } else if (formControl instanceof FormGroup) { @@ -162,7 +172,7 @@ export class FormProgressIndicationComponent extends BaseComponent implements On countFormControlsRequiredFieldsForTotal(formControl: AbstractControl): number { let valueCurrent = 0; if (formControl instanceof FormControl) { - if (this.controlRequired(formControl) && this.controlEnabled(formControl) && formControl['nativeElement']) { + if (this.controlRequired(formControl) && this.controlEnabled(formControl)) { valueCurrent++; } } else if (formControl instanceof FormGroup) { From 77f40570ac191007812c65b0060b6adac8de4c9b Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Mon, 17 Jul 2023 18:04:39 +0300 Subject: [PATCH 022/110] #8834: Home page: Drafts query for both Datasets and DMPs. 1. recent-activity-criteria.ts: Added in RecentActivityCriteria optional field "public status?: Number;" (to get only drafts). 2. drafts.component.ts & drafts.component.html: Updated calls and display to query for both Datasets and DMPs (same as recent-edited-activity, but include only drafts). 4. recent-edited-activity.component.ts: Removed old unnecessary logs. --- .../recent-activity-criteria.ts | 1 + .../ui/dashboard/drafts/drafts.component.html | 236 +++--- .../ui/dashboard/drafts/drafts.component.ts | 751 ++++++++++++------ .../recent-edited-activity.component.ts | 11 - 4 files changed, 630 insertions(+), 369 deletions(-) diff --git a/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts b/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts index 1c21402b9..8b6e134db 100644 --- a/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts +++ b/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts @@ -2,5 +2,6 @@ import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order import { BaseCriteria } from '../base-criteria'; export class RecentActivityCriteria extends BaseCriteria{ + public status?: Number; public order: RecentActivityOrder = RecentActivityOrder.MODIFIED; } diff --git a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html index 752fe315a..565092451 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html @@ -1,4 +1,7 @@ -
+
+ {{'DMP-LISTING.EMPTY-LIST' | translate}} +
+
{{'DMP-LISTING.SORT-BY' | translate}}: @@ -12,118 +15,157 @@ - + search - + {{formGroup.get('like').getError('backendError').message}}
-
+
-
-
- -
-
{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}
-
{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | dateTimeCultureFormatter: "d MMMM y"}}
-
-
{{activity.label}}
-
- {{ roleDisplay(activity.users) }} - . - public{{'DATASET-LISTING.STATES.PUBLIC' | translate}} - done{{ enumUtils.toDmpStatusString(activity.status) }} - create{{ enumUtils.toDmpStatusString(activity.status) }} - . - {{'DATASET-LISTING.COLUMNS.GRANT' | translate}}: {{activity.grant}} -
-
-
{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}} -
{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}
+
+
+
+ + +
+
{{ 'DMP-LISTING.DMP' | translate }}
+
{{ 'DMP-LISTING.EDITED' | translate }}: {{ activity.modified | dateTimeCultureFormatter: "d MMMM y" }}
+
{{ 'DMP-LISTING.PUBLISHED' | translate }}: {{ activity.publishedAt | dateTimeCultureFormatter: "d MMMM y" }}
- -
{{activity.dmp}}
+
{{activity.title}}
+
+ {{ roleDisplay(activity.users) }} + . + create{{ enumUtils.toDmpStatusString(activity.status) }} + . + {{'DMP-LISTING.VERSION' | translate}} {{activity.version}} + . + {{ 'DMP-LISTING.GRANT' | translate }}: {{activity.grant}} +
+
{{'DMP-LISTING.CONTAINED-DATASETS' | translate}}: ({{ getDatasets(activity).length }}) +
+
+
+
{{dataset.label}},
+
{{dataset.label}}
+
+
+ +
{{'GENERAL.ACTIONS.SHOW-MORE' | translate}} + + - -
- open_in_new{{'DATASET-LISTING.ACTIONS.EXPORT' | translate}} - group_add{{'DATASET-LISTING.ACTIONS.INVITE-SHORT' | translate}} - file_copy{{'DATASET-WIZARD.ACTIONS.COPY-DATASET' | translate}} - delete{{ 'DATASET-WIZARD.ACTIONS.DELETE' | translate }} - - + + + + + + + + + + +
- - - - - +
+
+
-
+
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
-
+
- diff --git a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts index be73632c5..81f04cb48 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts @@ -1,6 +1,6 @@ import {Component, OnInit, Input, EventEmitter, Output, ViewChild} from '@angular/core'; import { DatasetService } from '../../../core/services/dataset/dataset.service'; -import { DataTableRequest } from '../../../core/model/data-table/data-table-request'; +import {DataTableMultiTypeRequest, DataTableRequest} from '../../../core/model/data-table/data-table-request'; import { DatasetCriteria } from '../../../core/query/dataset/dataset-criteria'; import { DatasetListingModel } from '../../../core/model/dataset/dataset-listing'; import { AuthService } from '../../../core/services/auth/auth.service'; @@ -9,10 +9,10 @@ import {ActivatedRoute, Router} from '@angular/router'; import { DmpStatus } from '../../../core/common/enum/dmp-status'; import { Principal } from '@app/core/model/auth/principal'; import { TranslateService } from '@ngx-translate/core'; -import { debounceTime, takeUntil } from 'rxjs/operators'; +import {debounceTime, map, takeUntil} from 'rxjs/operators'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { DatasetCopyDialogueComponent } from '@app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component'; -import { FormControl, FormBuilder } from '@angular/forms'; +import {FormControl, FormBuilder, FormGroup} from '@angular/forms'; import { BaseComponent } from '@common/base/base.component'; import { MatDialog } from '@angular/material/dialog'; import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service'; @@ -27,6 +27,21 @@ import { Role } from '@app/core/common/enum/role'; import { LockService } from '@app/core/services/lock/lock.service'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { HttpClient } from '@angular/common/http'; +import {RecentActivityModel} from "@app/core/model/recent-activity/recent-activity.model"; +import {DmpEditorModel} from "@app/ui/dmp/editor/dmp-editor.model"; +import {DmpService} from "@app/core/services/dmp/dmp.service"; +import {DashboardService} from "@app/core/services/dashboard/dashboard.service"; +import {RecentActivityCriteria} from "@app/core/query/recent-activity/recent-activity-criteria"; +import {RecentDmpModel} from "@app/core/model/recent-activity/recent-dmp-activity.model"; +import {DatasetUrlListing} from "@app/core/model/dataset/dataset-url-listing"; +import {RecentDatasetModel} from "@app/core/model/recent-activity/recent-dataset-activity.model"; +import {DmpListingModel} from "@app/core/model/dmp/dmp-listing"; +import {DmpModel} from "@app/core/model/dmp/dmp"; +import {GrantTabModel} from "@app/ui/dmp/editor/grant-tab/grant-tab-model"; +import {ProjectFormModel} from "@app/ui/dmp/editor/grant-tab/project-form-model"; +import {FunderFormModel} from "@app/ui/dmp/editor/grant-tab/funder-form-model"; +import {ExtraPropertiesFormModel} from "@app/ui/dmp/editor/general-tab/extra-properties-form.model"; +import {CloneDialogComponent} from "@app/ui/dmp/clone/clone-dialog/clone-dialog.component"; @Component({ selector: 'app-drafts', @@ -35,39 +50,43 @@ import { HttpClient } from '@angular/common/http'; }) export class DraftsComponent extends BaseComponent implements OnInit { - @Input() routerLink: string; - @Output() totalCountDraftDatasets: EventEmitter = new EventEmitter(); - - @ViewChild("drafts") resultsContainer; - datasetDrafts: DatasetListingModel[]; - datasetDraftsTypeEnum = RecentActivityType; - status: number; + @Output() totalCountRecentEdited: EventEmitter = new EventEmitter(); + @ViewChild("results") resultsContainer; + allRecentActivities: RecentActivityModel[]; + recentActivityTypeEnum = RecentActivityType; + dmpModel: DmpEditorModel; + isDraft: boolean; totalCount: number; startIndex: number = 0; - pageSize: number = 5; + dmpOffset: number = 0; + datasetOffset: number = 0; offsetLess: number = 0; - hasMoreResults:boolean = true; - + pageSize: number = 5; + dmpFormGroup: FormGroup; + hasMoreActivity:boolean = true; public formGroup = new FormBuilder().group({ like: new FormControl(), order: new FormControl() }); + publicMode = false; order = RecentActivityOrder; page: number = 1; @Input() isActive: boolean = false; + constructor( private route: ActivatedRoute, private router: Router, - private datasetService: DatasetService, - private authentication: AuthService, - private language: TranslateService, - public dialog: MatDialog, - private datasetWizardService: DatasetWizardService, public enumUtils: EnumUtils, + private authentication: AuthService, + private dmpService: DmpService, + private dashboardService: DashboardService, + private language: TranslateService, + private dialog: MatDialog, private uiNotificationService: UiNotificationService, + private datasetWizardService: DatasetWizardService, private location: Location, private lockService: LockService, private httpClient: HttpClient, @@ -83,7 +102,8 @@ export class DraftsComponent extends BaseComponent implements OnInit { let page = (params['page'] === undefined) ? 1 : +params['page']; this.page = (page <= 0) ? 1 : page; - this.startIndex = (this.page-1)*this.pageSize; + this.datasetOffset = (this.page-1)*this.pageSize; + this.dmpOffset = (this.page-1)*this.pageSize; if(this.page > 1) { this.offsetLess = (this.page-2)*this.pageSize; } @@ -94,48 +114,57 @@ export class DraftsComponent extends BaseComponent implements OnInit { } this.formGroup.get('order').setValue(order); - let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword']; this.formGroup.get("like").setValue(keyword); this.updateUrl(); } - // else { - // this.page = 1; - // this.formGroup.get('order').setValue(this.order.MODIFIED); - // this.formGroup.get("like").setValue(""); - // } }); - // const fields: Array = []; - // fields.push('-modified'); - if(!this.formGroup.get('order').value) { - this.formGroup.get('order').setValue(this.order.MODIFIED); - } - const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - const dmpDataTableRequest: DataTableRequest = new DataTableRequest(this.startIndex, 5, { fields: fields }); - dmpDataTableRequest.criteria = new DatasetCriteria(); - dmpDataTableRequest.criteria.like = this.formGroup.get('like').value; - dmpDataTableRequest.criteria.status = DmpStatus.Draft; - this.datasetService.getPaged(dmpDataTableRequest) - .pipe(takeUntil(this._destroyed)) - .subscribe(response => { - this.datasetDrafts = response.data; - this.totalCount = response.totalCount; - this.totalCountDraftDatasets.emit(this.datasetDrafts.length); - if(this.totalCount > 0 && this.totalCount <= (this.page-1)*this.pageSize && this.page > 1) { - let queryParams = { type: "drafts", page: 1, order: this.formGroup.get("order").value }; - if(this.formGroup.get("like").value) { - queryParams['keyword'] = this.formGroup.get("like").value; - } - this.router.navigate(["/home"], { queryParams: queryParams }) + if (this.isAuthenticated()) { + if (!this.formGroup.get('order').value) { + this.formGroup.get('order').setValue(this.order.MODIFIED); } - }); - this.formGroup.get('like').valueChanges - .pipe(takeUntil(this._destroyed), debounceTime(500)) - .subscribe(x => this.refresh()); - this.formGroup.get('order').valueChanges - .pipe(takeUntil(this._destroyed)) - .subscribe(x => this.refresh()); + const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; + const allDataTableRequest: DataTableMultiTypeRequest = new DataTableMultiTypeRequest(this.dmpOffset, this.datasetOffset, 5, {fields: fields}); + allDataTableRequest.criteria = new RecentActivityCriteria(); + allDataTableRequest.criteria.like = this.formGroup.get('like').value; + allDataTableRequest.criteria.order = this.formGroup.get('order').value; + allDataTableRequest.criteria.status = 0; + + this.dashboardService + .getRecentActivity(allDataTableRequest) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + this.allRecentActivities = response; + this.allRecentActivities.forEach(recentActivity => { + if (recentActivity.type === RecentActivityType.Dataset) { + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page * this.pageSize; + } else if (recentActivity.type === RecentActivityType.Dmp) { + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page * this.pageSize; + } + }); + this.totalCountRecentEdited.emit(this.allRecentActivities.length); + if (this.allRecentActivities.length == 0 && this.page > 1) { + let queryParams = {type: "recent", page: 1, order: this.formGroup.get("order").value}; + if (this.formGroup.get("like").value) { + queryParams['keyword'] = this.formGroup.get("like").value; + } + this.router.navigate(["/home"], {queryParams: queryParams}) + } + }); + this.formGroup.get('like').valueChanges + .pipe(takeUntil(this._destroyed), debounceTime(500)) + .subscribe(x => { + this.refresh() + }); + this.formGroup.get('order').valueChanges + .pipe(takeUntil(this._destroyed)) + .subscribe(x => { + this.refresh() + }); + } } ngOnChanges() { @@ -152,6 +181,178 @@ export class DraftsComponent extends BaseComponent implements OnInit { this.location.go(this.router.url.split('?')[0]+parameters); } + getDatasets(activity: RecentDmpModel): DatasetUrlListing[] { + return activity.datasets; + } + + getGroupId(activity: RecentDmpModel): string { + return activity.groupId; + } + + getDmp(activity: RecentDatasetModel): String { + return activity.dmp; + } + + getDmpId(activity: RecentDatasetModel): String { + return activity.dmpId; + } + + public isAuthenticated(): boolean { + return !!this.authentication.current(); + } + + isUserOwner(activity: DmpListingModel): boolean { + const principal: Principal = this.authentication.current(); + if (principal) return !!activity.users.find(x => (x.role === Role.Owner) && (principal.id === x.id)); + } + + editClicked(dmp: DmpListingModel) { + this.router.navigate(['/plans/edit/' + dmp.id]); + } + + deleteDmpClicked(dmp: DmpListingModel) { + this.lockService.checkLockStatus(dmp.id).pipe(takeUntil(this._destroyed)) + .subscribe(lockStatus => { + if (!lockStatus) { + this.openDeleteDmpDialog(dmp); + } else { + this.openDmpLockedByUserDialog(); + } + }); + } + + cloneOrNewVersionClicked(dmp: RecentActivityModel, isNewVersion: boolean) { + this.dmpService.getSingle(dmp.id).pipe(map(data => data as DmpModel)) + .pipe(takeUntil(this._destroyed)) + .subscribe(data => { + this.dmpModel = new DmpEditorModel(); + this.dmpModel.grant = new GrantTabModel(); + this.dmpModel.project = new ProjectFormModel(); + this.dmpModel.funder = new FunderFormModel(); + this.dmpModel.extraProperties = new ExtraPropertiesFormModel(); + this.dmpModel.fromModel(data); + this.dmpModel.status = DmpStatus.Draft; + this.dmpFormGroup = this.dmpModel.buildForm(); + if (!isNewVersion) { + this.dmpFormGroup.get('label').setValue(dmp.title + " New"); + } + this.openCloneDialog(isNewVersion); + }); + } + + openCloneDialog(isNewVersion: boolean) { + const dialogRef = this.dialog.open(CloneDialogComponent, { + maxWidth: '700px', + maxHeight: '80vh', + data: { + formGroup: this.dmpFormGroup, + datasets: this.dmpFormGroup.get('datasets').value, + isNewVersion: isNewVersion, + confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.SAVE'), + cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'), + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + if (!isNewVersion) { + this.dmpService.clone(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCloneOrNewVersionCallbackSuccess(complete), + error => this.onCloneOrNewVersionCallbackError(error) + ); + } else if (isNewVersion) { + this.dmpService.newVersion(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCloneOrNewVersionCallbackSuccess(complete), + error => this.onCloneOrNewVersionCallbackError(error) + ); + } + } + }); + } + + openDeleteDmpDialog(dmp: DmpListingModel) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '300px', + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + isDeleteConfirmation: true + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.dmpService.delete(dmp.id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onDeleteCallbackSuccess(), + error => this.onDeleteCallbackError(error) + ); + } + }); + } + + openDmpLockedByUserDialog() { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '400px', + restoreFocus: false, + data: { + message: this.language.instant('DMP-EDITOR.ACTIONS.LOCK') + } + }); + } + + openShareDialog(rowId: any, rowName: any) { + const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { + // height: '250px', + // width: '700px', + autoFocus: false, + restoreFocus: false, + data: { + dmpId: rowId, + dmpName: rowName + } + }); + } + + isDraftDmp(activity: DmpListingModel) { + return activity.status == DmpStatus.Draft; + } + + onCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/plans']); + } + + reloadPage(): void { + const path = this.location.path(); + this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => { + this.router.navigate([path]); + }); + } + + onDeleteCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); + this.reloadPage(); + } + + onDeleteCallbackError(error) { + this.uiNotificationService.snackBarNotification(error.error.message ? this.language.instant(error.error.message) : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); + } + + onCloneOrNewVersionCallbackSuccess(dmpId: String): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/plans/edit/', dmpId]); + } + + onCloneOrNewVersionCallbackError(error: any) { + this.uiNotificationService.snackBarNotification(error.error.message ? this.language.instant(error.error.message) : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-CLONE'), SnackBarNotificationLevel.Error); + } + redirect(id: string, type: RecentActivityType) { switch (type) { case RecentActivityType.Grant: { @@ -159,11 +360,15 @@ export class DraftsComponent extends BaseComponent implements OnInit { return; } case RecentActivityType.Dataset: { - this.router.navigate(["datasets/edit/" + id]); + if (this.isAuthenticated()) { + this.router.navigate(['../datasets/overview/' + id]); + } return; } case RecentActivityType.Dmp: { - this.router.navigate(["plans/edit/" + id]); + if (this.isAuthenticated()) { + this.router.navigate(['../plans/overview/' + id]); + } return; } default: @@ -171,13 +376,28 @@ export class DraftsComponent extends BaseComponent implements OnInit { } } - public isAuthenticated(): boolean { - return !!this.authentication.current(); - } - - navigateToUrl() { - if (!this.isAuthenticated()) { return; } - this.router.navigate(['/datasets'], { queryParams: { status: 0 } }); + navigateToUrl(id: string, type: RecentActivityType): string[] { + switch (type) { + case RecentActivityType.Grant: { + return ["grants/edit/" + id]; + } + case RecentActivityType.Dataset: { + if (this.isAuthenticated()) { + return ['../datasets/overview/' + id]; + } else { + return ['../explore/publicOverview', id]; + } + } + case RecentActivityType.Dmp: { + if (this.isAuthenticated()) { + return ['../plans/overview/' + id]; + } else { + return ['../explore-plans/publicOverview', id]; + } + } + default: + throw new Error("Unsupported Activity Type "); + } } roleDisplay(value: any) { @@ -201,117 +421,68 @@ export class DraftsComponent extends BaseComponent implements OnInit { } } - openDmpSearchDialogue(dataset: DatasetListingModel) { - const formControl = new FormControl(); - const dialogRef = this.dialog.open(DatasetCopyDialogueComponent, { - width: '500px', - restoreFocus: false, - data: { - formControl: formControl, - datasetId: dataset.id, - datasetProfileId: dataset.profile.id, - datasetProfileExist: false, - confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'), - cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL') - } - }); + // dmpProfileDisplay(value: any) { + // if (value != null) { + // return value; + // } + // else { + // return "--"; + // } + // } - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) - .subscribe(result => { - if (result && result.datasetProfileExist) { - const newDmpId = result.formControl.value.id; - this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } }); - // let url = this.router.createUrlTree(['/datasets/copy/', result.datasetId, { newDmpId: newDmpId } ]); - // window.open(url.toString(), '_blank'); - } + downloadXml(id: string) { + this.dmpService.downloadXML(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/xml' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "xml", id); }); } - deleteClicked(id: string) { - this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) - .subscribe(lockStatus => { - if (!lockStatus) { - this.openDeleteDialog(id); - } else { - this.openLockedByUserDialog(); - } + downloadDocx(id: string) { + this.dmpService.downloadDocx(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/msword' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "docx", id); }); } - openDeleteDialog(id: string): void { - const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - maxWidth: '300px', - restoreFocus: false, - data: { - message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), - confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'), - cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), - isDeleteConfirmation: true - } - }); - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - if (result) { - this.datasetWizardService.delete(id) - .pipe(takeUntil(this._destroyed)) - .subscribe( - complete => this.onDeleteCallbackSuccess(), - error => this.onDeleteCallbackError(error) - ); - } - }); + downloadPdf(id: string) { + this.dmpService.downloadPDF(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/pdf' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "pdf", id); + }); } - openLockedByUserDialog() { - const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - maxWidth: '400px', - restoreFocus: false, - data: { - message: this.language.instant('DATASET-WIZARD.ACTIONS.LOCK') - } - }); + downloadJson(id: string) { + this.dmpService.downloadJson(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/json' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "json", id); + }, async error => { + this.onExportCallbackError(error); + }); } - openShareDialog(dmpRowId: any, dmpRowName: any) { - const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { - // height: '250px', - // width: '700px', - autoFocus: false, - restoreFocus: false, - data: { - dmpId: dmpRowId, - dmpName: dmpRowName - } - }); - } - - isUserOwner(activity: DatasetListingModel): boolean { - const principal: Principal = this.authentication.current(); - if (principal) return !!activity.users.find(x => (x.role === Role.Owner) && (principal.id === x.id)); - } - - onCallbackSuccess(id?: String): void { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); - id ? this.router.navigate(['/reload']).then(() => { this.router.navigate(['/datasets', 'edit', id]); }) : this.router.navigate(['/datasets']); - } - - onCallbackError(error: any) { - // this.setErrorModel(error.error); - } - - reloadPage(): void { - const path = this.location.path(); - this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => { - this.router.navigate([path]); - }); - } - - onDeleteCallbackSuccess(): void { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); - this.reloadPage(); - } - - onDeleteCallbackError(error) { - this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); + async onExportCallbackError(error: any) { + const errorJsonText = await error.error.text(); + const errorObj = JSON.parse(errorJsonText); + this.uiNotificationService.snackBarNotification(errorObj.message, SnackBarNotificationLevel.Error); } downloadPDF(dataset: DatasetListingModel): void { @@ -369,119 +540,177 @@ export class DraftsComponent extends BaseComponent implements OnInit { return filename; } - refresh(): void { - this.page = 1; - this.updateUrl(); + viewVersions(rowId: String, rowLabel: String, activity: DmpListingModel) { + if (activity.public && !this.isUserOwner(activity)) { + let url = this.router.createUrlTree(['/explore-plans/versions/', rowId, { groupLabel: rowLabel }]); + window.open(url.toString(), '_blank'); + // this.router.navigate(['/explore-plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } }); + } else { + let url = this.router.createUrlTree(['/plans/versions/', rowId, { groupLabel: rowLabel }]); + window.open(url.toString(), '_blank'); + // this.router.navigate(['/plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } }); + } + } - // const fields: Array = []; - // fields.push('-modified'); - const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - this.startIndex = 0; - const dmpDataTableRequest: DataTableRequest = new DataTableRequest(0, 5, { fields: fields }); - dmpDataTableRequest.criteria = new DatasetCriteria(); - dmpDataTableRequest.criteria.status = DmpStatus.Draft; - dmpDataTableRequest.criteria.like = this.formGroup.get("like").value; - this.datasetService.getPaged(dmpDataTableRequest) - .pipe(takeUntil(this._destroyed)) - .subscribe(response => { - this.datasetDrafts = response.data; - this.totalCount = response.totalCount; - this.totalCountDraftDatasets.emit(this.datasetDrafts.length); - if(response.data.length< this.pageSize) { - this.hasMoreResults = false; - } else { - this.hasMoreResults = true; + openDmpSearchDialogue(dataset: RecentDatasetModel) { + const formControl = new FormControl(); + const dialogRef = this.dialog.open(DatasetCopyDialogueComponent, { + width: '500px', + restoreFocus: false, + data: { + formControl: formControl, + datasetId: dataset.id, + datasetProfileId: dataset.profile.id, + datasetProfileExist: false, + confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'), + cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL') + } + }); + + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) + .subscribe(result => { + if (result && result.datasetProfileExist) { + const newDmpId = result.formControl.value.id; + // let url = this.router.createUrlTree(['/datasets/copy/', result.datasetId, { newDmpId: newDmpId }]); + // window.open(url.toString(), '_blank'); + this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } }); + } + }); + } + + deleteDatasetClicked(id: string) { + this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) + .subscribe(lockStatus => { + if (!lockStatus) { + this.openDeleteDatasetDialog(id); + } else { + this.openDatasetLockedByUserDialog(); + } + }); + } + + openDeleteDatasetDialog(id: string): void { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '300px', + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + isDeleteConfirmation: true + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.datasetWizardService.delete(id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onDeleteCallbackSuccess(), + error => this.onDeleteCallbackError(error) + ); } }); } - public loadNextOrPrevious(more: boolean = true) { - // const fields: Array = ["-modified"]; - const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - let request; - this.startIndex = (this.page)*this.pageSize; - if(this.page > 1) { - this.offsetLess = (this.page-2)*this.pageSize; - } - if(more) { - // this.startIndex = this.startIndex + this.pageSize; - request = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); - } else { - request = new DataTableRequest(this.offsetLess, this.pageSize, {fields: fields}); - } - request.criteria = new DatasetCriteria(); - request.criteria.status = DmpStatus.Draft; - request.criteria.like = this.formGroup.get("like").value;; + openDatasetLockedByUserDialog() { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '400px', + restoreFocus: false, + data: { + message: this.language.instant('DATASET-WIZARD.ACTIONS.LOCK') + } + }); + } - this.datasetService.getPaged(request).pipe(takeUntil(this._destroyed)).subscribe(result => { - if (!result || !result.data || result.data.length == 0) { - this.hasMoreResults = false; + refresh(): void { + this.datasetOffset = 0; + this.dmpOffset = 0; + this.page = 1; + this.updateUrl(); + + const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; + // const fields: Array = ["-modified"]; + this.startIndex = 0; + const allDataTableRequest: DataTableMultiTypeRequest = new DataTableMultiTypeRequest(0, 0, this.pageSize, { fields: fields }); + allDataTableRequest.criteria = new RecentActivityCriteria(); + allDataTableRequest.criteria.like = this.formGroup.get("like").value; + allDataTableRequest.criteria.order = this.formGroup.get("order").value; + allDataTableRequest.criteria.status = 0; + + this.dashboardService + .getRecentActivity(allDataTableRequest) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + this.allRecentActivities = response; + this.allRecentActivities.forEach(recentActivity => { + if (recentActivity.type === RecentActivityType.Dataset) { + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page*this.pageSize; + } else if (recentActivity.type === RecentActivityType.Dmp) { + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page*this.pageSize; + } + }); + + if(response.length< this.pageSize) { + this.hasMoreActivity = false; + } else { + this.hasMoreActivity = true; + } + this.totalCountRecentEdited.emit(this.allRecentActivities.length); + }); + } + + public loadNextOrPrevious(more: boolean = true) { + const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; + // const fields: Array = ["-modified"]; + let request; + if(more) { + request = new DataTableMultiTypeRequest(this.dmpOffset, this.datasetOffset, this.pageSize, {fields: fields}); + } else { + request = new DataTableMultiTypeRequest(this.offsetLess, this.offsetLess, this.pageSize, {fields: fields}); + } + request.criteria = new RecentActivityCriteria(); + request.criteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : ""; + request.criteria.order = this.formGroup.get("order").value; + request.criteria.status = 0; + + this.dashboardService.getRecentActivity(request).pipe(takeUntil(this._destroyed)).subscribe(result => { + if (!result || result.length == 0) { + this.hasMoreActivity = false; // return []; } else { - // this.datasetDrafts = this.datasetDrafts.concat(result.data); - // this.datasetDrafts = this.datasetDrafts.length > 0 ? this.mergeTwoSortedLists(this.datasetDrafts, result.data, this.formGroup.get('order').value) : result.data; this.page = this.page + (more ? 1 : -1); this.updateUrl(); - this.datasetDrafts = result.data; - if(result.data.length < this.pageSize) { - this.hasMoreResults = false; - } else { - this.hasMoreResults = true; + // if(more) { + // result.forEach(recentActivity => { + // if (recentActivity.type === RecentActivityType.Dataset) { + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page * this.pageSize; + // } else if (recentActivity.type === RecentActivityType.Dmp) { + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page * this.pageSize; + // } + // }); + // } + if (this.page > 1) { + this.offsetLess = (this.page - 2) * this.pageSize; } - this.totalCountDraftDatasets.emit(this.datasetDrafts.length); + + if(result.length < this.pageSize) { + this.hasMoreActivity = false; + } else { + this.hasMoreActivity = true; + } + + // this.allRecentActivities = this.allRecentActivities.concat(result); + // this.allRecentActivities = this.allRecentActivities.length > 0 ? this.mergeTwoSortedLists(this.allRecentActivities, result, this.formGroup.get('order').value) : result; + this.allRecentActivities = result; + this.totalCountRecentEdited.emit(this.allRecentActivities.length); if (more) { this.resultsContainer.nativeElement.scrollIntoView(); } } }); } - - private mergeTwoSortedLists(arr1: DatasetListingModel[], arr2: DatasetListingModel[], order: string): DatasetListingModel[] { - let merged = []; - let index1 = 0; - let index2 = 0; - let current = 0; - - while (current < (arr1.length + arr2.length)) { - - let isArr1Depleted = index1 >= arr1.length; - let isArr2Depleted = index2 >= arr2.length; - - if (order === 'modified') { - if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].modified) > new Date(arr2[index2].modified)))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } else if (order === 'created') { - if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].created) > new Date(arr2[index2].created)))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } else if (order === 'label') { - if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].label < arr2[index2].label))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } else if (order === 'status') { - if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].status < arr2[index2].status))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } - current++; - } - return merged; - } } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts index ee7d19c82..0c9e41e52 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts @@ -123,7 +123,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword']; this.formGroup.get("like").setValue(keyword); - console.log("init"); this.updateUrl(); } }); @@ -157,20 +156,17 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn if(this.formGroup.get("like").value) { queryParams['keyword'] = this.formGroup.get("like").value; } - console.log(queryParams); this.router.navigate(["/home"], { queryParams: queryParams }) } }); this.formGroup.get('like').valueChanges .pipe(takeUntil(this._destroyed), debounceTime(500)) .subscribe(x => { - console.log("like changed"); this.refresh() }); this.formGroup.get('order').valueChanges .pipe(takeUntil(this._destroyed)) .subscribe(x => { - console.log("order changed"); this.refresh() }); } else { @@ -199,20 +195,17 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn if(this.formGroup.get("like").value) { queryParams['keyword'] = this.formGroup.get("like").value; } - console.log(queryParams); this.router.navigate(["/home"], { queryParams: queryParams }) } }); this.formGroup.get('like').valueChanges .pipe(takeUntil(this._destroyed), debounceTime(500)) .subscribe(x => { - console.log("like changed 1"); this.refresh() }); this.formGroup.get('order').valueChanges .pipe(takeUntil(this._destroyed)) .subscribe(x => { - console.log("order changed 1"); this.refresh() }); } @@ -220,7 +213,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn ngOnChanges() { if(this.isActive) { - console.log("active"); this.updateUrl(); } } @@ -233,7 +225,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn if(parameters) { parameters = "?type=recent" + parameters; } - console.log(parameters); this.location.go(this.router.url.split('?')[0]+parameters); } @@ -710,7 +701,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn this.datasetOffset = 0; this.dmpOffset = 0; this.page = 1; - console.log("refresh"); this.updateUrl(); const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; @@ -763,7 +753,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn // return []; } else { this.page = this.page + (more ? 1 : -1); - console.log("loadNextOrPrevious"); this.updateUrl(); // if(more) { // result.forEach(recentActivity => { From e878310b72cce77f706c43f1800aff709062de97 Mon Sep 17 00:00:00 2001 From: "konstantina.galouni" Date: Mon, 17 Jul 2023 18:10:49 +0300 Subject: [PATCH 023/110] #8834: Home page: Drafts query for both Datasets and DMPs. 1. RecentActivityCriteria.java: Added in RecentActivityCriteria field "private Integer status;", to be able to get only drafts. 2. DashBoardManager.java: In method "getNewRecentActivity()", add in Dataset and DMP requests status in criteria. --- .../java/eu/eudat/criteria/RecentActivityCriteria.java | 9 +++++++++ .../java/eu/eudat/logic/managers/DashBoardManager.java | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/dmp-backend/web/src/main/java/eu/eudat/criteria/RecentActivityCriteria.java b/dmp-backend/web/src/main/java/eu/eudat/criteria/RecentActivityCriteria.java index 40cf806c1..a7891b49f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/criteria/RecentActivityCriteria.java +++ b/dmp-backend/web/src/main/java/eu/eudat/criteria/RecentActivityCriteria.java @@ -3,6 +3,7 @@ package eu.eudat.criteria; public class RecentActivityCriteria { private String like; private String order; + private Integer status; public String getLike() { return like; @@ -19,4 +20,12 @@ public class RecentActivityCriteria { public void setOrder(String order) { this.order = order; } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java index aded6d599..4f5c76f66 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java @@ -221,11 +221,17 @@ public class DashBoardManager { } DatasetCriteria datasetCriteria = new DatasetCriteria(); datasetCriteria.setLike(tableRequest.getCriteria().getLike()); + if(tableRequest.getCriteria().getStatus() != null) { + datasetCriteria.setStatus(tableRequest.getCriteria().getStatus()); + } datasetCriteria.setAllVersions(false); datasetCriteria.setIsPublic(!isAuthenticated); DataManagementPlanCriteria dataManagementPlanCriteria = new DataManagementPlanCriteria(); dataManagementPlanCriteria.setAllVersions(false); dataManagementPlanCriteria.setLike(tableRequest.getCriteria().getLike()); + if(tableRequest.getCriteria().getStatus() != null) { + dataManagementPlanCriteria.setStatus(tableRequest.getCriteria().getStatus()); + } dataManagementPlanCriteria.setIsPublic(!isAuthenticated); dataManagementPlanCriteria.setOnlyPublic(!isAuthenticated); From 2db9ea613f3beb229b914f383bd277c42f3ba5e3 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Thu, 20 Jul 2023 13:00:24 +0300 Subject: [PATCH 024/110] catch error in prefilling when source mapping does not exist in the api's response --- .../logic/mapper/prefilling/PrefillingMapper.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java index 4c3a6653b..e8758d628 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java @@ -57,7 +57,17 @@ public class PrefillingMapper { sourceValue = ((Map)sourceValue).get(sourceKey); } } - setValue(prefillingMapping, mapper.writeValueAsString(sourceValue), datasetWizardModel, parentNode, properties, type, licenseManager); + try { + setValue(prefillingMapping, mapper.writeValueAsString(sourceValue), datasetWizardModel, parentNode, properties, type, licenseManager); + } + catch (Exception e) { + if (prefillingMapping.getSemanticTarget() != null && !prefillingMapping.getSemanticTarget().isEmpty()) { + logger.warn("Couldn't map " + prefillingMapping.getSemanticTarget()); + } + else if (prefillingMapping.getTarget() != null && !prefillingMapping.getTarget().isEmpty()) { + logger.warn("Couldn't map " + prefillingMapping.getTarget()); + } + } } for (PrefillingFixedMapping fixedMapping: prefillingGet.getFixedMappings()) { setValue(fixedMapping, fixedMapping.getValue(), datasetWizardModel, parentNode, properties, type, licenseManager); From 0918e55ac919dc8438b43f62e6f3714d647c831f Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Thu, 20 Jul 2023 13:07:05 +0300 Subject: [PATCH 025/110] fix bug in dataset template editor when a field is an admin-input api and couldn't fetch results --- .../controllers/DatasetProfileController.java | 8 ++++ .../common/AutoCompleteOptionsLookupItem.java | 19 ++++++++ .../daatset-external-autocomplete-criteria.ts | 5 +- .../dataset-external-autocomplete.service.ts | 14 ++---- ...file-editor-composite-field.component.html | 2 +- ...rofile-editor-composite-field.component.ts | 2 + ...ile-editor-section-fieldset.component.html | 3 +- ...ofile-editor-section-fieldset.component.ts | 2 + .../dataset-profile-editor.component.html | 1 + .../form-field/form-field.component.ts | 48 +++++++++++-------- 10 files changed, 70 insertions(+), 34 deletions(-) create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/helpers/common/AutoCompleteOptionsLookupItem.java diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java index 5f16cb390..d18c3f903 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java @@ -70,4 +70,12 @@ public class DatasetProfileController extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(items); } + @RequestMapping(method = RequestMethod.POST, value = {"/search/autocompleteOptions"}, consumes = "application/json", produces = "application/json") + public ResponseEntity getDataForAutocompleteOptions(@RequestBody RequestItem lookupItem) { + AutoCompleteData data = new AutoCompleteData(); + data.setAutoCompleteSingleDataList(lookupItem.getCriteria().getAutoCompleteSingleDataList()); + List items = this.datasetProfileManager.getAutocomplete(data, lookupItem.getCriteria().getLike()); + return ResponseEntity.status(HttpStatus.OK).body(items); + } + } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/helpers/common/AutoCompleteOptionsLookupItem.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/helpers/common/AutoCompleteOptionsLookupItem.java new file mode 100644 index 000000000..6e3abcc30 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/helpers/common/AutoCompleteOptionsLookupItem.java @@ -0,0 +1,19 @@ +package eu.eudat.models.data.helpers.common; + +import eu.eudat.data.dao.criteria.Criteria; +import eu.eudat.models.data.components.commons.datafield.AutoCompleteData; + +import java.util.List; + +public class AutoCompleteOptionsLookupItem extends Criteria { + + private List autoCompleteSingleDataList; + + public List getAutoCompleteSingleDataList() { + return autoCompleteSingleDataList; + } + public void setAutoCompleteSingleDataList(List autoCompleteSingleDataList) { + this.autoCompleteSingleDataList = autoCompleteSingleDataList; + } + +} diff --git a/dmp-frontend/src/app/core/query/dataset/daatset-external-autocomplete-criteria.ts b/dmp-frontend/src/app/core/query/dataset/daatset-external-autocomplete-criteria.ts index d511e9432..f32a40cd6 100644 --- a/dmp-frontend/src/app/core/query/dataset/daatset-external-autocomplete-criteria.ts +++ b/dmp-frontend/src/app/core/query/dataset/daatset-external-autocomplete-criteria.ts @@ -4,5 +4,8 @@ import { BaseCriteria } from "../base-criteria"; export class DatasetExternalAutocompleteCriteria extends BaseCriteria { public profileID: String; public fieldID: String; - public autocompleteOptions: AutoCompleteSingleData; +} + +export class DatasetExternalAutocompleteOptionsCriteria extends BaseCriteria { + public autoCompleteSingleDataList: AutoCompleteSingleData[]; } \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts b/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts index bcbfd2630..48e7348cf 100644 --- a/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts +++ b/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts @@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { environment } from '../../../../environments/environment'; -import { DatasetExternalAutocompleteCriteria } from '../../query/dataset/daatset-external-autocomplete-criteria'; +import { DatasetExternalAutocompleteCriteria, DatasetExternalAutocompleteOptionsCriteria } from '../../query/dataset/daatset-external-autocomplete-criteria'; import { RequestItem } from '../../query/request-item'; import { DatasetProfileService } from '../dataset-profile/dataset-profile.service'; import { ConfigurationService } from '../configuration/configuration.service'; @@ -17,7 +17,7 @@ export class DatasetExternalAutocompleteService { private httpClient: HttpClient, private datasetProfileService: DatasetProfileService, private configurationService: ConfigurationService) { - this.actionUrl = configurationService.server + 'datasets/'; + this.actionUrl = configurationService.server + '/'; } getDatasetProfileById(datasetProfileID) { @@ -28,14 +28,8 @@ export class DatasetExternalAutocompleteService { return this.httpClient.post(this.configurationService.server + 'search/autocomplete', lookUpItem); } - queryApi(requestItem: RequestItem):Observable{ //TODO - - return of([ - { - label:'Preview not supported yet', - source:'' - } - ]); + queryApi(lookUpItem: RequestItem): Observable{ + return this.httpClient.post(this.configurationService.server + 'search/autocompleteOptions', lookUpItem); } } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html index 72d631d4f..9e415287f 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html @@ -204,7 +204,7 @@
- +
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts index 4f5e7b641..12c3754f6 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts @@ -69,6 +69,8 @@ export class DatasetProfileEditorCompositeFieldComponent extends BaseComponent i @Input() indexPath: string; @Input() viewOnly: boolean; + @Input() datasetProfileId?: string; + @Input() numbering: string; @Input() hasFocus: boolean = false; @ViewChild("inputs") inputs: TransitionGroupComponent; diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.html index 38426a3d6..d57310531 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.html @@ -74,7 +74,8 @@ + [hasFocus]="fieldset.get('id').value === selectedFieldSetId" + [datasetProfileId]="datasetProfileId"> diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.ts index 0e71dcc8c..82c46659a 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.ts @@ -26,6 +26,8 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC // @Input() numbering: string; @Input() tocentry: ToCEntry; + @Input() datasetProfileId?: string; + @Output() selectedEntryId = new EventEmitter(); @Output() dataNeedsRefresh = new EventEmitter (); @Output() removeFieldSet = new EventEmitter(); diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html index c0288f59d..03750188c 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html @@ -290,6 +290,7 @@ { try { return item['source'] ? this.language.instant('DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE-SUBTITLE') + item['source'] : this.language.instant('DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE-NO-SOURCE') } catch { return '' } } } } + if(isNullOrUndefined(this.datasetProfileId)){ + this.autocompleteOptions = this.form.get('data').value.autoCompleteSingleDataList; + } } switch (this.form.get('viewStyle').value.renderStyle) { @@ -385,29 +388,32 @@ export class FormFieldComponent extends BaseComponent implements OnInit { // } searchFromAutocomplete(query: string) { - const autocompleteRequestItem: RequestItem = new RequestItem(); - autocompleteRequestItem.criteria = new DatasetExternalAutocompleteCriteria(); - let parseIdArray: string[] = this.form.get('id').value.split('_'); - if(parseIdArray.length > 1) { - autocompleteRequestItem.criteria.fieldID = parseIdArray[parseIdArray.length - 1]; - } else { - autocompleteRequestItem.criteria.fieldID = this.form.get('id').value; - } - if (typeof this.datasetProfileId === 'string') { - autocompleteRequestItem.criteria.profileID = this.datasetProfileId; - } else if (this.datasetProfileId != null) { - autocompleteRequestItem.criteria.profileID = this.datasetProfileId.id; - } else if (this.autocompleteOptions != null) { - autocompleteRequestItem.criteria.autocompleteOptions = this.autocompleteOptions; - } else { - throw "Could not load autocomplete options."; - } - autocompleteRequestItem.criteria.like = query; if (this.autocompleteOptions) { + const autocompleteRequestItem: RequestItem = new RequestItem(); + autocompleteRequestItem.criteria = new DatasetExternalAutocompleteOptionsCriteria(); + autocompleteRequestItem.criteria.autoCompleteSingleDataList = this.autocompleteOptions; + autocompleteRequestItem.criteria.like = query; return this.datasetExternalAutocompleteService.queryApi(autocompleteRequestItem); } - return this.datasetExternalAutocompleteService.queryAutocomplete(autocompleteRequestItem); + else{ + const autocompleteRequestItem: RequestItem = new RequestItem(); + autocompleteRequestItem.criteria = new DatasetExternalAutocompleteCriteria(); + let parseIdArray: string[] = this.form.get('id').value.split('_'); + if(parseIdArray.length > 1) { + autocompleteRequestItem.criteria.fieldID = parseIdArray[parseIdArray.length - 1]; + } else { + autocompleteRequestItem.criteria.fieldID = this.form.get('id').value; + } + if (typeof this.datasetProfileId === 'string') { + autocompleteRequestItem.criteria.profileID = this.datasetProfileId; + } + else if (this.datasetProfileId != null) { + autocompleteRequestItem.criteria.profileID = this.datasetProfileId.id; + } + autocompleteRequestItem.criteria.like = query; + return this.datasetExternalAutocompleteService.queryAutocomplete(autocompleteRequestItem); + } } searchResearchers(query: string) { From ee90ac37b6011e336fbbd72465bf13055d1a43e8 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Thu, 20 Jul 2023 13:34:56 +0300 Subject: [PATCH 026/110] no message --- .../main/java/eu/eudat/controllers/DatasetProfileController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java index d18c3f903..1c0d56ce1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java @@ -8,6 +8,7 @@ import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.components.commons.datafield.AutoCompleteData; import eu.eudat.models.data.externaldataset.ExternalAutocompleteFieldModel; import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem; +import eu.eudat.models.data.helpers.common.AutoCompleteOptionsLookupItem; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.properties.PropertiesModel; import eu.eudat.models.data.security.Principal; From 3fc307c831a7279c231eade3fff0d858baefa5f0 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Fri, 21 Jul 2023 17:04:41 +0300 Subject: [PATCH 027/110] #8912: adding new metadata/registries api in the configs --- .../resources/externalUrls/ExternalUrls.xml | 36 ++++++++++++++----- .../externalUrls/ExternalUrlsStaging.xml | 36 ++++++++++++++----- ...et-external-references-editor.component.ts | 2 +- .../form-field/form-field.component.ts | 2 +- 4 files changed, 56 insertions(+), 20 deletions(-) diff --git a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml index 4281c6d37..5752ced62 100644 --- a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml +++ b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml @@ -6,22 +6,40 @@ + + + + + + + + + + + + + + + + + + + + - cristin - + rda-metadata-schemes + 1 External - https://eestore.paas2.uninett.no/api/metadataschema/?search={like}&page={page}&size={pageSize} - 1 - application/vnd.api+json; charset=utf-8 + https://rdamsc.bath.ac.uk/api2/m?q={like}&start=1&pageSize=111 + application/json; charset=utf-8 - $['data'][*]['attributes'] + $['data']['items'][*] - 'pid' - 'name' + 'mscid' + 'title' 'uri' 'description' - 'source' $['meta']['pagination']['page','pages','count'] diff --git a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrlsStaging.xml b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrlsStaging.xml index 14c945367..365ea535a 100644 --- a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrlsStaging.xml +++ b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrlsStaging.xml @@ -6,22 +6,40 @@ + + + + + + + + + + + + + + + + + + + + - cristin - + rda-metadata-schemes + 1 External - https://eestore.paas2.uninett.no/api/metadataschema/?search={like}&page={page}&size={pageSize} - 1 - application/vnd.api+json; charset=utf-8 + https://rdamsc.bath.ac.uk/api2/m?q={like}&start=1&pageSize=111 + application/json; charset=utf-8 - $['data'][*]['attributes'] + $['data']['items'][*] - 'pid' - 'name' + 'mscid' + 'title' 'uri' 'description' - 'source' $['meta']['pagination']['page','pages','count'] diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/external-references/dataset-external-references-editor.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/external-references/dataset-external-references-editor.component.ts index fc991bc70..b3cc56cc1 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/external-references/dataset-external-references-editor.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/external-references/dataset-external-references-editor.component.ts @@ -60,7 +60,7 @@ export class DatasetExternalReferencesEditorComponent extends BaseComponent impl initialItems: (type) => this.searchDatasetExternalRegistries('', type), displayFn: (item) => item ? item.name : null, titleFn: (item) => item ? item.name : null, - subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE') + subtitleFn: (item) => item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : item.tag ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.tag : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE') }; dataRepositoriesAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts index b124dfd5a..0bc73c23f 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts @@ -271,7 +271,7 @@ export class FormFieldComponent extends BaseComponent implements OnInit { initialItems: () => this.searchDatasetExternalRegistries(''), displayFn: (item) => { try { return typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name } catch { return '' } }, titleFn: (item) => { try { return typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name } catch { return '' } }, - subtitleFn: (item) => { try { return item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE') } catch { return '' } }, + subtitleFn: (item) => { try { return item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : item.tag ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.tag : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE') } catch { return '' } }, valueAssign: (item) => { try { return typeof (item) == 'string' ? item : JSON.stringify(item) } catch { return '' } } }; break; From a737fec19d48db329b78d5b8444370f589cafb1c Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Tue, 25 Jul 2023 14:48:13 +0300 Subject: [PATCH 028/110] Progress Bar: Add condition for visibillity if a field has id. --- .../form-progress-indication.component.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts index cf953e754..b42dc86b8 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts @@ -176,10 +176,12 @@ export class FormProgressIndicationComponent extends BaseComponent implements On valueCurrent++; } } else if (formControl instanceof FormGroup) { - Object.keys(formControl.controls).forEach(item => { - const control = formControl.get(item); - valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(control); - }); + if(!formControl.get('id')?.value || this.visibilityRulesService.checkElementVisibility(formControl.get('id').value)) { + Object.keys(formControl.controls).forEach(item => { + const control = formControl.get(item); + valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(control); + }); + } } else if (formControl instanceof FormArray) { formControl.controls.forEach(item => { valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(item); From bc279b1610a4b308abfdf69d9274d69e685aec28 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Tue, 25 Jul 2023 15:04:39 +0300 Subject: [PATCH 029/110] #8843 - 1. refactor the DatasetProfile Table to DescriptionTemplate name 2. add scripts for the new DescriptionTemplateType table 3. update english localization + frontend --- .../dao/criteria/DatasetProfileCriteria.java | 6 +- .../DatasetProfileWizardCriteria.java | 4 +- .../DatasetExternalDatasetDaoImpl.java | 1 - .../data/dao/entities/DatasetProfileDao.java | 14 +- .../dao/entities/DatasetProfileDaoImpl.java | 49 ++++--- .../data/dao/entities/DatasetServiceDao.java | 1 - .../dao/entities/DatasetServiceDaoImpl.java | 2 - .../main/java/eu/eudat/data/entities/DMP.java | 6 +- .../java/eu/eudat/data/entities/Dataset.java | 6 +- ...tProfile.java => DescriptionTemplate.java} | 25 ++-- .../data/entities/UserDatasetProfile.java | 12 +- .../DatasetProfileAutocompleteRequest.java | 11 +- ...tasetProfileWizardAutocompleteRequest.java | 8 +- .../DatasetProfileTableRequestItem.java | 10 +- .../main/java/eu/eudat/controllers/Admin.java | 39 +++--- .../controllers/DMPProfileController.java | 3 +- .../controllers/DatasetProfileController.java | 7 +- .../java/eu/eudat/controllers/Datasets.java | 3 +- .../controllers/QuickWizardController.java | 8 +- .../entity/DatasetProfileBuilder.java | 28 ++-- .../eu/eudat/logic/managers/AdminManager.java | 23 +-- .../managers/DataManagementPlanManager.java | 19 ++- .../eudat/logic/managers/DatasetManager.java | 36 ++--- .../logic/managers/DatasetProfileManager.java | 81 +++++------ .../logic/managers/DatasetWizardManager.java | 10 +- .../eudat/logic/managers/MetricsManager.java | 10 +- .../logic/managers/PrefillingManager.java | 6 +- .../eu/eudat/logic/managers/UserManager.java | 9 +- .../mapper/elastic/DatasetTemplateMapper.java | 4 +- .../mapper/prefilling/PrefillingMapper.java | 4 +- .../datasetProfileModel/DatasetProfile.java | 4 +- .../DatasetProfileAutocompleteItem.java | 10 +- .../DatasetProfileListingModel.java | 10 +- .../DatasetProfileOverviewModel.java | 10 +- .../datasetwizard/DatasetWizardModel.java | 2 +- .../models/data/dmp/AssociatedProfile.java | 8 +- .../models/data/dmp/DataManagementPlan.java | 15 +- .../dmp/DataManagementPlanEditorModel.java | 11 +- .../DataManagementPlanOverviewModel.java | 6 +- .../DatasetDescriptionQuickWizardModel.java | 6 +- .../data/quickwizard/DmpQuickWizardModel.java | 13 +- .../models/rda/mapper/DatasetRDAMapper.java | 6 +- .../eudat/models/rda/mapper/DmpRDAMapper.java | 6 +- .../managers/DatasetPublicManager.java | 7 +- .../AssociatedProfilePublicModel.java | 8 +- .../DatasetProfilePublicModel.java | 10 +- .../DataManagementPlanPublicModel.java | 8 +- .../overviewmodels/DatasetPublicModel.java | 2 +- dmp-db-scema/main/data-dump.sql | 4 +- dmp-db-scema/main/dmp-dump.sql | 53 +++++-- ...13_Add_Description_Template_Type_table.sql | 19 +++ ...ame_DatasetProfile_and_add_Type_column.sql | 29 ++++ dmp-frontend/src/app/app-routing.module.ts | 4 +- .../services/utilities/enum-utils.service.ts | 2 +- .../dataset-profile-listing.component.html | 2 +- .../app/ui/dashboard/dashboard.component.html | 14 +- .../ui/dashboard/drafts/drafts.component.html | 6 +- .../recent-edited-activity.component.html | 10 +- ...ent-edited-dataset-activity.component.html | 6 +- .../recent-edited-dmp-activity.component.html | 4 +- .../dataset-wizard.component.html | 4 +- .../listing/dataset-listing.component.html | 6 +- .../dataset-listing-item.component.html | 6 +- .../overview/dataset-overview.component.html | 4 +- .../clone-dialog/clone-dialog.component.html | 6 +- .../app/ui/dmp/clone/dmp-clone.component.html | 8 +- .../available-profiles.component.html | 6 +- .../dataset-info/dataset-info.component.html | 2 +- .../ui/dmp/editor/dmp-editor.component.html | 8 +- .../dmp-listing-item.component.html | 4 +- .../dmp/overview/dmp-overview.component.html | 4 +- .../dmp-wizard-dataset-listing.component.html | 4 +- .../src/app/ui/sidebar/sidebar.component.ts | 9 +- dmp-frontend/src/assets/i18n/en.json | 131 +++++++++++------- 74 files changed, 526 insertions(+), 416 deletions(-) rename dmp-backend/data/src/main/java/eu/eudat/data/entities/{DatasetProfile.java => DescriptionTemplate.java} (86%) create mode 100644 dmp-db-scema/updates/00.00.013_Add_Description_Template_Type_table.sql create mode 100644 dmp-db-scema/updates/00.00.014_Rename_DatasetProfile_and_add_Type_column.sql diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java index de7119428..c859cb2c8 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java @@ -1,13 +1,13 @@ package eu.eudat.data.dao.criteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import java.util.Date; import java.util.List; import java.util.UUID; -public class DatasetProfileCriteria extends Criteria { +public class DatasetProfileCriteria extends Criteria { public enum DatasetProfileFilter { DMPs((short) 0), Datasets((short) 1); @@ -25,7 +25,7 @@ public class DatasetProfileCriteria extends Criteria { case 1: return Datasets; default: - throw new RuntimeException("Unsupported DatasetProfile filter"); + throw new RuntimeException("Unsupported DescriptionTemplate filter"); } } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileWizardCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileWizardCriteria.java index df4978858..9e1d5d9e2 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileWizardCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileWizardCriteria.java @@ -1,11 +1,11 @@ package eu.eudat.data.dao.criteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import java.util.UUID; -public class DatasetProfileWizardCriteria extends Criteria { +public class DatasetProfileWizardCriteria extends Criteria { private UUID id; public UUID getId() { diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetExternalDatasetDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetExternalDatasetDaoImpl.java index ed76b6376..a0f7f6afa 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetExternalDatasetDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetExternalDatasetDaoImpl.java @@ -3,7 +3,6 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccess; import eu.eudat.data.dao.databaselayer.service.DatabaseService; import eu.eudat.data.entities.DatasetExternalDataset; -import eu.eudat.data.entities.DatasetProfile; import eu.eudat.queryable.QueryableList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java index d2b712ea2..5365067fc 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java @@ -2,20 +2,22 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccessLayer; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.queryable.QueryableList; import java.util.List; import java.util.UUID; -public interface DatasetProfileDao extends DatabaseAccessLayer { +public interface DatasetProfileDao extends DatabaseAccessLayer { - QueryableList getWithCriteria(DatasetProfileCriteria criteria); + QueryableList getWithCriteria(DatasetProfileCriteria criteria); - QueryableList getAll(); + QueryableList getAll(); - QueryableList getAuthenticated(QueryableList query, UUID principal, List roles); + QueryableList getAuthenticated(QueryableList query, UUID principal, List roles); - List getAllIds(); + List getAllIds(); + + Long countWithType(UUID id); } \ No newline at end of file diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java index b6cbb445b..eae2be263 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java @@ -3,8 +3,8 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccess; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; import eu.eudat.data.dao.databaselayer.service.DatabaseService; -import eu.eudat.data.entities.DMP; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; +import eu.eudat.data.entities.DescriptionTemplateType; import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.types.FieldSelectionType; import eu.eudat.queryable.types.SelectionField; @@ -21,16 +21,16 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; @Component("datasetProfileDao") -public class DatasetProfileDaoImpl extends DatabaseAccess implements DatasetProfileDao { +public class DatasetProfileDaoImpl extends DatabaseAccess implements DatasetProfileDao { @Autowired - public DatasetProfileDaoImpl(DatabaseService databaseService) { + public DatasetProfileDaoImpl(DatabaseService databaseService) { super(databaseService); } @Override - public QueryableList getWithCriteria(DatasetProfileCriteria criteria) { - QueryableList query = getDatabaseService().getQueryable(DatasetProfile.class); + public QueryableList getWithCriteria(DatasetProfileCriteria criteria) { + QueryableList query = getDatabaseService().getQueryable(DescriptionTemplate.class); if (criteria.getLike() != null && !criteria.getLike().isEmpty()) query.where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + criteria.getLike().toUpperCase() + "%")); if (!criteria.getAllVersions()) @@ -63,9 +63,9 @@ public class DatasetProfileDaoImpl extends DatabaseAccess implem query.where(((builder, root) -> root.get("id").in(criteria.getIds()))); } if (criteria.getFinalized()) { - query.where(((builder, root) -> builder.equal(root.get("status"), DatasetProfile.Status.FINALIZED.getValue()))); + query.where(((builder, root) -> builder.equal(root.get("status"), DescriptionTemplate.Status.FINALIZED.getValue()))); } else { - query.where(((builder, root) -> builder.notEqual(root.get("status"), DatasetProfile.Status.DELETED.getValue()))); + query.where(((builder, root) -> builder.notEqual(root.get("status"), DescriptionTemplate.Status.DELETED.getValue()))); } if (criteria.getPeriodStart() != null) query.where((builder, root) -> builder.greaterThanOrEqualTo(root.get("created"), criteria.getPeriodStart())); @@ -73,48 +73,48 @@ public class DatasetProfileDaoImpl extends DatabaseAccess implem } @Override - public DatasetProfile createOrUpdate(DatasetProfile item) { - return this.getDatabaseService().createOrUpdate(item, DatasetProfile.class); + public DescriptionTemplate createOrUpdate(DescriptionTemplate item) { + return this.getDatabaseService().createOrUpdate(item, DescriptionTemplate.class); } @Override - public DatasetProfile find(UUID id) { - return getDatabaseService().getQueryable(DatasetProfile.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle(); + public DescriptionTemplate find(UUID id) { + return getDatabaseService().getQueryable(DescriptionTemplate.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle(); } @Override - public QueryableList getAll() { - return getDatabaseService().getQueryable(DatasetProfile.class); + public QueryableList getAll() { + return getDatabaseService().getQueryable(DescriptionTemplate.class); } @Override - public List getAllIds(){ - return getDatabaseService().getQueryable(DatasetProfile.class).withFields(Collections.singletonList("id")).toList(); + public List getAllIds(){ + return getDatabaseService().getQueryable(DescriptionTemplate.class).withFields(Collections.singletonList("id")).toList(); } @Override - public void delete(DatasetProfile item) { + public void delete(DescriptionTemplate item) { this.getDatabaseService().delete(item); } @Override - public QueryableList asQueryable() { - return this.getDatabaseService().getQueryable(DatasetProfile.class); + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(DescriptionTemplate.class); } @Async @Override - public CompletableFuture createOrUpdateAsync(DatasetProfile item) { + public CompletableFuture createOrUpdateAsync(DescriptionTemplate item) { return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); } @Override - public DatasetProfile find(UUID id, String hint) { + public DescriptionTemplate find(UUID id, String hint) { throw new UnsupportedOperationException(); } @Override - public QueryableList getAuthenticated(QueryableList query, UUID principal, List roles) { + public QueryableList getAuthenticated(QueryableList query, UUID principal, List roles) { if (roles != null && !roles.isEmpty()) { query.where((builder, root) -> { Join userJoin = root.join("users", JoinType.LEFT); @@ -126,4 +126,9 @@ public class DatasetProfileDaoImpl extends DatabaseAccess implem return query; } + + @Override + public Long countWithType(UUID id) { + return this.getDatabaseService().getQueryable(DescriptionTemplate.class).where((builder, root) -> builder.equal(root.get("type"), id)).count(); + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDao.java index 9af289d34..3666d4014 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDao.java @@ -1,7 +1,6 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccessLayer; -import eu.eudat.data.entities.DatasetProfile; import eu.eudat.data.entities.DatasetService; import java.util.UUID; diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDaoImpl.java index fd40d37ae..2f000f4f8 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDaoImpl.java @@ -2,8 +2,6 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccess; import eu.eudat.data.dao.databaselayer.service.DatabaseService; -import eu.eudat.data.entities.DatasetExternalDataset; -import eu.eudat.data.entities.DatasetProfile; import eu.eudat.data.entities.DatasetService; import eu.eudat.queryable.QueryableList; import org.springframework.beans.factory.annotation.Autowired; diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java index 036069e86..54beaeeb9 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java @@ -117,7 +117,7 @@ public class DMP implements DataEntity { joinColumns = {@JoinColumn(name = "\"dmp\"", referencedColumnName = "\"ID\"")}, inverseJoinColumns = {@JoinColumn(name = "\"datasetprofile\"", referencedColumnName = "\"ID\"")} ) - private Set associatedDmps; + private Set associatedDmps; @ManyToOne(fetch = FetchType.LAZY) @@ -274,10 +274,10 @@ public class DMP implements DataEntity { this.grant = grant; } - public Set getAssociatedDmps() { + public Set getAssociatedDmps() { return associatedDmps; } - public void setAssociatedDmps(Set associatedDmps) { + public void setAssociatedDmps(Set associatedDmps) { this.associatedDmps = associatedDmps; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java index 4692571b0..7456b21d8 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java @@ -110,7 +110,7 @@ public class Dataset implements DataEntity { @ManyToOne(fetch = FetchType.LAZY) //@Cascade(value=org.hibernate.annotations.CascadeType.ALL) @JoinColumn(name = "\"Profile\"") - private DatasetProfile profile; + private DescriptionTemplate profile; @Type(type = "eu.eudat.configurations.typedefinition.XMLType") @Column(name = "\"Reference\"", columnDefinition = "xml") @@ -249,10 +249,10 @@ public class Dataset implements DataEntity { } - public DatasetProfile getProfile() { + public DescriptionTemplate getProfile() { return profile; } - public void setProfile(DatasetProfile profile) { + public void setProfile(DescriptionTemplate profile) { this.profile = profile; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DatasetProfile.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java similarity index 86% rename from dmp-backend/data/src/main/java/eu/eudat/data/entities/DatasetProfile.java rename to dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java index a11316abd..c30018630 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DatasetProfile.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java @@ -14,8 +14,8 @@ import java.util.UUID; @Entity -@Table(name = "\"DatasetProfile\"") -public class DatasetProfile implements DataEntity{ +@Table(name = "\"DescriptionTemplate\"") +public class DescriptionTemplate implements DataEntity{ public enum Status { SAVED((short) 0), FINALIZED((short) 1), DELETED((short) 99); @@ -89,7 +89,11 @@ public class DatasetProfile implements DataEntity{ @Column(name = "\"Language\"", nullable = false) private String language; - @OneToMany(mappedBy = "datasetProfile", fetch = FetchType.LAZY) + @OneToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "\"Type\"", nullable = false) + private DescriptionTemplateType type; + + @OneToMany(mappedBy = "descriptionTemplate", fetch = FetchType.LAZY) private Set users; @@ -156,26 +160,31 @@ public class DatasetProfile implements DataEntity{ public String getLanguage() { return language; } - public void setLanguage(String language) { this.language = language; } + public DescriptionTemplateType getType() { + return type; + } + public void setType(DescriptionTemplateType type) { + this.type = type; + } + public Set getUsers() { return users; } - public void setUsers(Set users) { this.users = users; } @Override public String toString() { - return "DatasetProfileListingModel [id=" + id + ", label=" + label + ", dataset=" + dataset + ", definition=" + definition + ", version=" + version + ", language=" + language + "]"; + return "DatasetProfileListingModel [id=" + id + ", label=" + label + ", dataset=" + dataset + ", definition=" + definition + ", version=" + version + ", language=" + language + ", type=" + type +"]"; } @Override - public void update(DatasetProfile entity) { + public void update(DescriptionTemplate entity) { } @Override @@ -184,7 +193,7 @@ public class DatasetProfile implements DataEntity{ } @Override - public DatasetProfile buildFromTuple(List tuple, List fields, String base) { + public DescriptionTemplate buildFromTuple(List tuple, List fields, String base) { this.id = UUID.fromString((String) tuple.get(0).get(base.isEmpty() ? base + "." + "id" : "id")); return this; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDatasetProfile.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDatasetProfile.java index 8388cdbc3..4af7c2799 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDatasetProfile.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDatasetProfile.java @@ -22,8 +22,8 @@ public class UserDatasetProfile implements DataEntity private UserInfo user; @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "\"datasetProfile\"") - private DatasetProfile datasetProfile; + @JoinColumn(name = "\"descriptionTemplate\"") + private DescriptionTemplate descriptionTemplate; @Column(name = "role") private Integer role; @@ -44,12 +44,12 @@ public class UserDatasetProfile implements DataEntity this.user = user; } - public DatasetProfile getDatasetProfile() { - return datasetProfile; + public DescriptionTemplate getDatasetProfile() { + return descriptionTemplate; } - public void setDatasetProfile(DatasetProfile datasetProfile) { - this.datasetProfile = datasetProfile; + public void setDatasetProfile(DescriptionTemplate descriptionTemplate) { + this.descriptionTemplate = descriptionTemplate; } public Integer getRole() { diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileAutocompleteRequest.java b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileAutocompleteRequest.java index 2cda2c5cd..984d44073 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileAutocompleteRequest.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileAutocompleteRequest.java @@ -1,25 +1,24 @@ package eu.eudat.data.query.items.item.datasetprofile; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.PaginationService; -import eu.eudat.data.query.definition.Query; import eu.eudat.data.query.definition.TableQuery; import eu.eudat.queryable.QueryableList; import java.util.UUID; -public class DatasetProfileAutocompleteRequest extends TableQuery { +public class DatasetProfileAutocompleteRequest extends TableQuery { @Override - public QueryableList applyCriteria() { - QueryableList query = this.getQuery(); + public QueryableList applyCriteria() { + QueryableList query = this.getQuery(); if (this.getCriteria().getLike() != null && !this.getCriteria().getLike().isEmpty()) query.where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + this.getCriteria().getLike().toUpperCase() + "%")); return query; } @Override - public QueryableList applyPaging(QueryableList items) { + public QueryableList applyPaging(QueryableList items) { return PaginationService.applyPaging(items, this); } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileWizardAutocompleteRequest.java b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileWizardAutocompleteRequest.java index 2d7c0b393..c911fe3af 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileWizardAutocompleteRequest.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileWizardAutocompleteRequest.java @@ -1,15 +1,13 @@ package eu.eudat.data.query.items.item.datasetprofile; import eu.eudat.data.dao.criteria.DatasetProfileWizardCriteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.definition.Query; import eu.eudat.queryable.QueryableList; -import java.util.UUID; - -public class DatasetProfileWizardAutocompleteRequest extends Query { +public class DatasetProfileWizardAutocompleteRequest extends Query { @Override - public QueryableList applyCriteria() { + public QueryableList applyCriteria() { return null; } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/datasetprofile/DatasetProfileTableRequestItem.java b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/datasetprofile/DatasetProfileTableRequestItem.java index 1ff6faa88..17ad2a687 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/datasetprofile/DatasetProfileTableRequestItem.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/datasetprofile/DatasetProfileTableRequestItem.java @@ -1,23 +1,23 @@ package eu.eudat.data.query.items.table.datasetprofile; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.definition.TableQuery; import eu.eudat.queryable.QueryableList; import java.util.UUID; -public class DatasetProfileTableRequestItem extends TableQuery { +public class DatasetProfileTableRequestItem extends TableQuery { @Override - public QueryableList applyCriteria() { - QueryableList query = this.getQuery(); + public QueryableList applyCriteria() { + QueryableList query = this.getQuery(); if (this.getCriteria().getLike() != null && !this.getCriteria().getLike().isEmpty()) query.where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + this.getCriteria().getLike().toUpperCase() + "%")); return query; } @Override - public QueryableList applyPaging(QueryableList items) { + public QueryableList applyPaging(QueryableList items) { return null; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java index 7829f2fa9..f9a5cd03b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java @@ -1,5 +1,6 @@ package eu.eudat.controllers; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.UserDatasetProfile; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem; @@ -16,7 +17,6 @@ import eu.eudat.models.data.admin.composite.DatasetProfile; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; -import eu.eudat.models.data.listingmodels.UserInfoListingModel; import eu.eudat.models.data.security.Principal; import eu.eudat.models.data.user.composite.PagedDatasetProfile; import eu.eudat.types.ApiMessageCode; @@ -32,7 +32,6 @@ import javax.validation.Valid; import java.io.IOException; import java.util.List; import java.util.UUID; -import java.util.stream.Collectors; import static eu.eudat.types.Authorities.ADMIN; import static eu.eudat.types.Authorities.DATASET_PROFILE_MANAGER; @@ -61,20 +60,20 @@ public class Admin extends BaseController { public ResponseEntity addDmp(@Valid @RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN ,DATASET_PROFILE_MANAGER}) Principal principal) { //this.getLoggerService().info(principal, "Admin Added Dataset Profile"); DatasetProfile shortenProfile = profile.toShort(); - eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(shortenProfile, getApiContext()); + DescriptionTemplate modelDefinition = AdminManager.generateViewStyleDefinition(shortenProfile, getApiContext()); modelDefinition.setGroupId(UUID.randomUUID()); modelDefinition.setVersion((short) 0); - eu.eudat.data.entities.DatasetProfile datasetProfile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); + DescriptionTemplate descriptionTemplate = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); UserDatasetProfile userDatasetProfile = new UserDatasetProfile(); - userDatasetProfile.setDatasetProfile(datasetProfile); + userDatasetProfile.setDatasetProfile(descriptionTemplate); UserInfo userInfo = getApiContext().getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); userDatasetProfile.setUser(userInfo); userDatasetProfile.setRole(0); getApiContext().getOperationsContext().getDatabaseRepository().getUserDatasetProfileDao().createOrUpdate(userDatasetProfile); - datasetProfileManager.storeDatasetProfileUsers(datasetProfile, profile); + datasetProfileManager.storeDatasetProfileUsers(descriptionTemplate, profile); - metricsManager.increaseValue(MetricNames.DATASET_TEMPLATE, 1, MetricsManager.datasetTemplateStatus.get(datasetProfile.getStatus()) ); + metricsManager.increaseValue(MetricNames.DATASET_TEMPLATE, 1, MetricsManager.datasetTemplateStatus.get(descriptionTemplate.getStatus()) ); return ResponseEntity.status(HttpStatus.OK).body(modelDefinition.getId()); } @@ -82,17 +81,17 @@ public class Admin extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/addDmp/{id}"}, consumes = "application/json", produces = "application/json") public ResponseEntity> updateDmp(@PathVariable String id, @RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) { DatasetProfile shortenProfile = profile.toShort(); - eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(shortenProfile, getApiContext()); - eu.eudat.data.entities.DatasetProfile datasetprofile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + DescriptionTemplate modelDefinition = AdminManager.generateViewStyleDefinition(shortenProfile, getApiContext()); + DescriptionTemplate datasetprofile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); datasetprofile.setDefinition(modelDefinition.getDefinition()); Short oldStatus = datasetprofile.getStatus(); datasetprofile.setStatus(modelDefinition.getStatus()); datasetprofile.setLabel(modelDefinition.getLabel()); datasetprofile.setDescription(modelDefinition.getDescription()); datasetprofile.setLanguage(modelDefinition.getLanguage()); - eu.eudat.data.entities.DatasetProfile datasetProfile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(datasetprofile); - datasetProfileManager.storeDatasetProfileUsers(datasetProfile, profile); - if (datasetProfile.getStatus() == 1 && oldStatus == 0) { + DescriptionTemplate descriptionTemplate = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(datasetprofile); + datasetProfileManager.storeDatasetProfileUsers(descriptionTemplate, profile); + if (descriptionTemplate.getStatus() == 1 && oldStatus == 0) { metricsManager.increaseValue(MetricNames.DATASET_TEMPLATE, 1, MetricNames.ACTIVE); } return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); @@ -102,7 +101,7 @@ public class Admin extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/newVersion/{id}"}, produces = "application/json") public ResponseEntity newVersionDatasetProfile(@PathVariable String id, @RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) throws Exception { try { - eu.eudat.data.entities.DatasetProfile modelDefinition = this.datasetProfileManager.createNewVersionDatasetProfile(id, profile); + DescriptionTemplate modelDefinition = this.datasetProfileManager.createNewVersionDatasetProfile(id, profile); return ResponseEntity.status(HttpStatus.OK).body(modelDefinition.getId()); } catch (DatasetProfileNewVersionException exception) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(exception.getMessage())); @@ -125,7 +124,7 @@ public class Admin extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/preview"}, consumes = "application/json", produces = "application/json") public ResponseEntity> getPreview(@RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) { - eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(profile, getApiContext()); + DescriptionTemplate modelDefinition = AdminManager.generateViewStyleDefinition(profile, getApiContext()); eu.eudat.models.data.user.composite.DatasetProfile datasetProfile = userManager.generateDatasetProfileModel(modelDefinition); PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile(); pagedDatasetProfile.buildPagedDatasetProfile(datasetProfile); @@ -145,7 +144,7 @@ public class Admin extends BaseController { public @ResponseBody ResponseEntity> inactivate(@PathVariable String id, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) { try { - eu.eudat.data.entities.DatasetProfile ret = AdminManager.inactivate(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao(), this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), id); + DescriptionTemplate ret = AdminManager.inactivate(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao(), this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); } catch (DatasetProfileWithDatasetsExeption exception) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.UNSUCCESS_DELETE).message(exception.getMessage())); @@ -156,7 +155,7 @@ public class Admin extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/getXml/{id}"}, produces = "application/json") public ResponseEntity getDatasetProfileXml(@PathVariable String id, @RequestHeader("Content-Type") String contentType, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) throws IllegalAccessException, IOException, InstantiationException { if (contentType.equals("application/xml")) { - eu.eudat.data.entities.DatasetProfile profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + DescriptionTemplate profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); eu.eudat.models.data.user.composite.DatasetProfile datasetProfile = userManager.generateDatasetProfileModel(profile); datasetProfile.setStatus(profile.getStatus()); datasetProfile.setDescription(profile.getDescription()); @@ -173,12 +172,12 @@ public class Admin extends BaseController { @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) throws Exception { eu.eudat.logic.utilities.documents.xml.datasetProfileXml.datasetProfileModel.DatasetProfile datasetProfileModel = this.datasetProfileManager.createDatasetProfileFromXml(file); eu.eudat.models.data.admin.composite.DatasetProfile datasetProfileEntity = datasetProfileModel.toAdminCompositeModel(file.getOriginalFilename()); - eu.eudat.data.entities.DatasetProfile modelDefinition; + DescriptionTemplate modelDefinition; if (id == null) { modelDefinition = AdminManager.generateViewStyleDefinition(datasetProfileEntity, getApiContext()); - eu.eudat.data.entities.DatasetProfile datasetProfile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); + DescriptionTemplate descriptionTemplate = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); UserDatasetProfile userDatasetProfile = new UserDatasetProfile(); - userDatasetProfile.setDatasetProfile(datasetProfile); + userDatasetProfile.setDatasetProfile(descriptionTemplate); UserInfo userInfo = getApiContext().getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); userDatasetProfile.setUser(userInfo); userDatasetProfile.setRole(0); @@ -186,7 +185,7 @@ public class Admin extends BaseController { } else { modelDefinition = datasetProfileManager.createNewVersionDatasetProfile(id, datasetProfileEntity); } - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>() + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>() .status(ApiMessageCode.SUCCESS_MESSAGE).message("")); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java index 1a54587fa..a47a59ce7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java @@ -2,6 +2,7 @@ package eu.eudat.controllers; import eu.eudat.data.dao.criteria.RequestItem; import eu.eudat.data.entities.DMPProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest; import eu.eudat.logic.managers.DataManagementProfileManager; import eu.eudat.logic.security.claims.ClaimedAuthorities; @@ -82,7 +83,7 @@ public class DMPProfileController extends BaseController { eu.eudat.logic.utilities.documents.xml.dmpXml.dmpProfileModel.DmpProfile dmpProfileModel = this.dataManagementProfileManager.createDmpProfileFromXml(file); DataManagementPlanProfileListingModel dataManagementPlan = dmpProfileModel.toDmpProfileCompositeModel(file.getOriginalFilename()); this.dataManagementProfileManager.createOrUpdate(dataManagementPlan, principal); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>() + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>() .status(ApiMessageCode.SUCCESS_MESSAGE).message("")); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java index 5f16cb390..8fbe7c8f2 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java @@ -1,6 +1,7 @@ package eu.eudat.controllers; import eu.eudat.data.dao.criteria.RequestItem; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.managers.AdminManager; import eu.eudat.logic.managers.DatasetProfileManager; import eu.eudat.logic.security.claims.ClaimedAuthorities; @@ -55,7 +56,7 @@ public class DatasetProfileController extends BaseController { @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/datasetprofile/clone/{id}"}, consumes = "application/json", produces = "application/json") public ResponseEntity> clone(@PathVariable String id, @ClaimedAuthorities(claims = {ADMIN})Principal principal) { - eu.eudat.data.entities.DatasetProfile profile = this.datasetProfileManager.clone(id); + DescriptionTemplate profile = this.datasetProfileManager.clone(id); eu.eudat.models.data.admin.composite.DatasetProfile datasetprofile = AdminManager.generateDatasetProfileModel(profile); datasetprofile.setLabel(profile.getLabel() + " new "); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(datasetprofile)); @@ -63,8 +64,8 @@ public class DatasetProfileController extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/search/autocomplete"}, consumes = "application/json", produces = "application/json") public ResponseEntity getDataForAutocomplete(@RequestBody RequestItem lookupItem) throws XPathExpressionException { - eu.eudat.data.entities.DatasetProfile datasetProfile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(lookupItem.getCriteria().getProfileID())); - eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field modelfield = this.datasetProfileManager.queryForField(datasetProfile.getDefinition(), lookupItem.getCriteria().getFieldID()); + DescriptionTemplate descriptionTemplate = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(lookupItem.getCriteria().getProfileID())); + eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field modelfield = this.datasetProfileManager.queryForField(descriptionTemplate.getDefinition(), lookupItem.getCriteria().getFieldID()); AutoCompleteData data = (AutoCompleteData) modelfield.getData(); List items = this.datasetProfileManager.getAutocomplete(data, lookupItem.getCriteria().getLike()); return ResponseEntity.status(HttpStatus.OK).body(items); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java index 4b4a79d1e..5364cf9f0 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java @@ -1,6 +1,7 @@ package eu.eudat.controllers; import eu.eudat.data.entities.Dataset; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.items.item.dataset.DatasetWizardAutocompleteRequest; import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileWizardAutocompleteRequest; import eu.eudat.data.query.items.table.dataset.DatasetPublicTableRequest; @@ -202,7 +203,7 @@ public class Datasets extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/get/{id}"}, produces = "application/json") public ResponseEntity> getSingle(@PathVariable String id) { - eu.eudat.data.entities.DatasetProfile profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + DescriptionTemplate profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); eu.eudat.models.data.user.composite.DatasetProfile datasetprofile = userManager.generateDatasetProfileModel(profile); PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile(); pagedDatasetProfile.buildPagedDatasetProfile(datasetprofile); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java index e80a2c70d..082e9ade7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java @@ -1,8 +1,7 @@ package eu.eudat.controllers; -import eu.eudat.data.entities.Dataset; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.Funder; import eu.eudat.data.entities.Project; import eu.eudat.logic.managers.DatasetManager; @@ -23,7 +22,6 @@ import org.springframework.web.bind.annotation.*; import javax.transaction.Transactional; import javax.validation.Valid; -import java.util.UUID; @RestController @CrossOrigin @@ -88,7 +86,7 @@ public class QuickWizardController extends BaseController { quickWizard.getDmp().setId(dmpEntity.getId()); for (DatasetDescriptionQuickWizardModel dataset : quickWizard.getDatasets().getDatasetsList()) { DataManagementPlan dmp = quickWizard.getDmp().toDataDmp(grantEntity, projectEntity, principal); - DatasetProfile profile = quickWizard.getDmp().getDatasetProfile(); + DescriptionTemplate profile = quickWizard.getDmp().getDatasetProfile(); DatasetWizardModel datasetWizardModel = dataset.toDataModel(dmp, profile); this.datasetManager.createOrUpdate(datasetWizardModel, principal); } @@ -100,7 +98,7 @@ public class QuickWizardController extends BaseController { public @ResponseBody ResponseEntity> addDatasetWizard(@RequestBody DatasetCreateWizardModel datasetCreateWizardModel, Principal principal) throws Exception{ for(DatasetDescriptionQuickWizardModel dataset : datasetCreateWizardModel.getDatasets().getDatasetsList()){ - DatasetProfile profile = new DatasetProfile(); + DescriptionTemplate profile = new DescriptionTemplate(); profile.setId(datasetCreateWizardModel.getDmpMeta().getDatasetProfile().getId()); profile.setLabel(datasetCreateWizardModel.getDmpMeta().getDatasetProfile().getLabel()); this.datasetManager.createOrUpdate(dataset.toDataModel(datasetCreateWizardModel.getDmpMeta().getDmp(), profile), principal); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/DatasetProfileBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/DatasetProfileBuilder.java index add38bb38..59194d62f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/DatasetProfileBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/DatasetProfileBuilder.java @@ -1,8 +1,8 @@ package eu.eudat.logic.builders.entity; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.builders.Builder; import eu.eudat.data.entities.Dataset; -import eu.eudat.data.entities.DatasetProfile; import java.util.Date; import java.util.Set; @@ -11,7 +11,7 @@ import java.util.UUID; /** * Created by ikalyvas on 2/15/2018. */ -public class DatasetProfileBuilder extends Builder { +public class DatasetProfileBuilder extends Builder { private UUID id; @@ -77,17 +77,17 @@ public class DatasetProfileBuilder extends Builder { } @Override - public DatasetProfile build() { - DatasetProfile datasetProfile = new DatasetProfile(); - datasetProfile.setCreated(created); - datasetProfile.setStatus(status); - datasetProfile.setId(id); - datasetProfile.setDataset(dataset); - datasetProfile.setDefinition(definition); - datasetProfile.setDescription(description); - datasetProfile.setModified(modified); - datasetProfile.setLabel(label); - datasetProfile.setLanguage(language); - return datasetProfile; + public DescriptionTemplate build() { + DescriptionTemplate descriptionTemplate = new DescriptionTemplate(); + descriptionTemplate.setCreated(created); + descriptionTemplate.setStatus(status); + descriptionTemplate.setId(id); + descriptionTemplate.setDataset(dataset); + descriptionTemplate.setDefinition(definition); + descriptionTemplate.setDescription(description); + descriptionTemplate.setModified(modified); + descriptionTemplate.setLabel(label); + descriptionTemplate.setLanguage(language); + return descriptionTemplate; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java index 8d4b4382c..a7569ed82 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java @@ -2,6 +2,7 @@ package eu.eudat.logic.managers; import eu.eudat.data.dao.entities.DatasetDao; import eu.eudat.data.dao.entities.DatasetProfileDao; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.exceptions.datasetprofile.DatasetProfileWithDatasetsExeption; import eu.eudat.logic.builders.entity.DatasetProfileBuilder; import eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel; @@ -17,7 +18,7 @@ import java.util.UUID; public class AdminManager { - public static eu.eudat.data.entities.DatasetProfile generateViewStyleDefinition(DatasetProfile profile, ApiContext apiContext) { + public static DescriptionTemplate generateViewStyleDefinition(DatasetProfile profile, ApiContext apiContext) { ViewStyleModel viewStyleModel = new ViewStyleModel(); viewStyleModel.setSections(new ModelBuilder().toViewStyleDefinition(profile.getSections(), eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Section.class)); viewStyleModel.setPages(new ModelBuilder().toViewStyleDefinition(profile.getPages(), eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Page.class)); @@ -34,22 +35,22 @@ public class AdminManager { profile.setLanguage("en"); } - eu.eudat.data.entities.DatasetProfile datasetProfile = apiContext.getOperationsContext().getBuilderFactory().getBuilder(DatasetProfileBuilder.class).definition(xml).label(profile.getLabel()) + DescriptionTemplate descriptionTemplate = apiContext.getOperationsContext().getBuilderFactory().getBuilder(DatasetProfileBuilder.class).definition(xml).label(profile.getLabel()) .status(profile.getStatus()).created(new Date()).description(profile.getDescription()).language(profile.getLanguage()) .build(); - if (datasetProfile.getGroupId() == null) { - datasetProfile.setGroupId(UUID.randomUUID()); + if (descriptionTemplate.getGroupId() == null) { + descriptionTemplate.setGroupId(UUID.randomUUID()); } - if (datasetProfile.getVersion() == null) { - datasetProfile.setVersion((short)1); + if (descriptionTemplate.getVersion() == null) { + descriptionTemplate.setVersion((short)1); } - return datasetProfile; + return descriptionTemplate; } - public static eu.eudat.models.data.admin.composite.DatasetProfile generateDatasetProfileModel(eu.eudat.data.entities.DatasetProfile profile) { + public static eu.eudat.models.data.admin.composite.DatasetProfile generateDatasetProfileModel(DescriptionTemplate profile) { Document viewStyleDoc = XmlBuilder.fromXml(profile.getDefinition()); Element root = viewStyleDoc.getDocumentElement(); eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel viewstyle = new eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel().fromXml(root); @@ -60,12 +61,12 @@ public class AdminManager { } - public static eu.eudat.data.entities.DatasetProfile inactivate(DatasetProfileDao datasetProfileRepository, DatasetDao datasetDao, String id) { + public static DescriptionTemplate inactivate(DatasetProfileDao datasetProfileRepository, DatasetDao datasetDao, String id) { eu.eudat.data.dao.criteria.DatasetCriteria datasetsForThatDatasetProfile = new eu.eudat.data.dao.criteria.DatasetCriteria(); datasetsForThatDatasetProfile.setProfileDatasetId(UUID.fromString(id)); if (datasetDao.getWithCriteria(datasetsForThatDatasetProfile).count() == 0) { - eu.eudat.data.entities.DatasetProfile detasetProfile = datasetProfileRepository.find(UUID.fromString(id)); - detasetProfile.setStatus(eu.eudat.data.entities.DatasetProfile.Status.DELETED.getValue()); + DescriptionTemplate detasetProfile = datasetProfileRepository.find(UUID.fromString(id)); + detasetProfile.setStatus(DescriptionTemplate.Status.DELETED.getValue()); detasetProfile = datasetProfileRepository.createOrUpdate(detasetProfile); return detasetProfile; } else { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index df74d3258..9679bc857 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -25,7 +25,6 @@ import eu.eudat.elastic.entities.Tag; import eu.eudat.exceptions.datamanagementplan.DMPNewVersionException; import eu.eudat.exceptions.datamanagementplan.DMPWithDatasetsDeleteException; import eu.eudat.exceptions.security.ForbiddenException; -import eu.eudat.exceptions.security.NonValidTokenException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.builders.entity.UserInfoBuilder; import eu.eudat.logic.mapper.elastic.DmpMapper; @@ -65,7 +64,6 @@ import eu.eudat.models.data.userinfo.UserListingModel; import eu.eudat.queryable.QueryableList; import eu.eudat.types.Authorities; import eu.eudat.types.MetricNames; -import org.apache.commons.io.IOUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; @@ -87,7 +85,6 @@ import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import java.io.*; import java.math.BigInteger; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -408,7 +405,7 @@ public class DataManagementPlanManager { datasetProfileTableRequestItem.getCriteria().setFilter(DatasetProfileCriteria.DatasetProfileFilter.DMPs.getValue()); datasetProfileTableRequestItem.getCriteria().setUserId(principal.getId()); - QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); + QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); List listingModels = items.select(item -> new DatasetProfileListingModel().fromDataModel(item)); DataTableData data = new DataTableData<>(); @@ -1603,19 +1600,19 @@ public class DataManagementPlanManager { Element profiles = xmlDoc.createElement("profiles"); // Get DatasetProfiles from DMP to add to XML. - for (DatasetProfile datasetProfile : dmp.getAssociatedDmps()) { + for (DescriptionTemplate descriptionTemplate : dmp.getAssociatedDmps()) { Element profile = xmlDoc.createElement("profile"); Element profileId = xmlDoc.createElement("profileId"); - profileId.setTextContent(datasetProfile.getId().toString()); + profileId.setTextContent(descriptionTemplate.getId().toString()); profile.appendChild(profileId); Element profileGroupId = xmlDoc.createElement("profileGroupId"); - profileGroupId.setTextContent(datasetProfile.getGroupId().toString()); + profileGroupId.setTextContent(descriptionTemplate.getGroupId().toString()); profile.appendChild(profileGroupId); Element profileLabel = xmlDoc.createElement("profileLabel"); - profileLabel.setTextContent(datasetProfile.getLabel()); + profileLabel.setTextContent(descriptionTemplate.getLabel()); profile.appendChild(profileLabel); Element profileVersion = xmlDoc.createElement("profileVersion"); - profileVersion.setTextContent(String.valueOf(datasetProfile.getVersion())); + profileVersion.setTextContent(String.valueOf(descriptionTemplate.getVersion())); profile.appendChild(profileVersion); profiles.appendChild(profile); } @@ -1755,7 +1752,7 @@ public class DataManagementPlanManager { List associatedProfiles = new LinkedList<>(); if (profiles != null && profiles.length > 0) { for (String profile : profiles) { - DatasetProfile exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(profile)); + DescriptionTemplate exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(profile)); AssociatedProfile associatedProfile = new AssociatedProfile().fromData(exProfile); associatedProfiles.add(associatedProfile); } @@ -1763,7 +1760,7 @@ public class DataManagementPlanManager { for (AssociatedProfileImportModels a : dataManagementPlans.get(0).getProfilesImportModels()) { try { - DatasetProfile exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(a.getId()); + DescriptionTemplate exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(a.getId()); AssociatedProfile associatedProfile = new AssociatedProfile().fromData(exProfile); associatedProfiles.add(associatedProfile); } catch (Exception ignored) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index 9cc087e02..85a3228e6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -300,7 +300,7 @@ public class DatasetManager { dataset.setDatasetProfileDefinition(getPagedProfile(dataset, datasetEntity)); dataset.fromDataModel(datasetEntity); - // Creates the Criteria to get all version of DatasetProfile in question. + // Creates the Criteria to get all version of DescriptionTemplate in question. DatasetProfileCriteria profileCriteria = new DatasetProfileCriteria(); UUID profileId = datasetEntity.getProfile().getGroupId(); List uuidList = new LinkedList<>(); @@ -308,13 +308,13 @@ public class DatasetManager { profileCriteria.setGroupIds(uuidList); profileCriteria.setAllVersions(true); - List profileVersions = databaseRepository.getDatasetProfileDao().getWithCriteria(profileCriteria) + List profileVersions = databaseRepository.getDatasetProfileDao().getWithCriteria(profileCriteria) .orderBy(((builder, root) -> builder.desc(root.get("version")))) .toList(); - List profileVersionsIncluded = new LinkedList<>(); + List profileVersionsIncluded = new LinkedList<>(); // Iterate through the versions and remove those that are not included in the DMP of the dataset in question. - for (DatasetProfile version : profileVersions) { + for (DescriptionTemplate version : profileVersions) { for (AssociatedProfile p : dataset.getDmp().getProfiles()) { if (version.getId().toString().equals(p.getId().toString())) { profileVersionsIncluded.add(version); @@ -323,14 +323,14 @@ public class DatasetManager { } // Sort the list with the included Versions. - Stream sorted = profileVersionsIncluded.stream().sorted(Comparator.comparing(DatasetProfile::getVersion).reversed()); + Stream sorted = profileVersionsIncluded.stream().sorted(Comparator.comparing(DescriptionTemplate::getVersion).reversed()); // Make the Stream into List and get the first item. - List profiles = sorted.collect(Collectors.toList()); + List profiles = sorted.collect(Collectors.toList()); if (profiles.isEmpty()) throw new NoSuchElementException("No profiles found for the specific Dataset"); - DatasetProfile profile = profiles.get(0); + DescriptionTemplate profile = profiles.get(0); // Check if the dataset is on the latest Version. boolean latestVersion = profile.getVersion().toString().equals(datasetEntity.getProfile().getVersion().toString()); @@ -717,7 +717,7 @@ public class DatasetManager { public String checkDatasetValidation(Dataset dataset) throws Exception { List datasetProfileValidators = new LinkedList<>(); - DatasetProfile profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(dataset.getProfile().getId()); + DescriptionTemplate profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(dataset.getProfile().getId()); DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); Document xmlDocument = builder.parse(new ByteArrayInputStream(profile.getDefinition().getBytes())); @@ -975,9 +975,9 @@ public class DatasetManager { // Checks if XML datasetProfileId GroupId matches the one selected. try { - eu.eudat.data.entities.DatasetProfile importDatasetProfile = databaseRepository.getDatasetProfileDao().find(UUID.fromString(importModel.getDatasetProfileId())); - eu.eudat.data.entities.DatasetProfile latestVersionDatasetProfile = databaseRepository.getDatasetProfileDao().find(UUID.fromString(datasetProfileId)); - if (latestVersionDatasetProfile.getGroupId() != importDatasetProfile.getGroupId()) { + DescriptionTemplate importDescriptionTemplate = databaseRepository.getDatasetProfileDao().find(UUID.fromString(importModel.getDatasetProfileId())); + DescriptionTemplate latestVersionDescriptionTemplate = databaseRepository.getDatasetProfileDao().find(UUID.fromString(datasetProfileId)); + if (latestVersionDescriptionTemplate.getGroupId() != importDescriptionTemplate.getGroupId()) { throw new Exception(); } } catch (Exception e) { @@ -1010,7 +1010,7 @@ public class DatasetManager { entity.setStatus((short) 0); entity.setCreated(new Date()); entity.setModified(new Date()); - DatasetProfile profile = new DatasetProfile(); + DescriptionTemplate profile = new DescriptionTemplate(); profile.setId(UUID.fromString(datasetProfileId)); entity.setProfile(profile); @@ -1045,7 +1045,7 @@ public class DatasetManager { dataset.setDatasetProfileDefinition(getPagedProfile(dataset, datasetEntity)); dataset.fromDataModel(datasetEntity); - // Creates the Criteria to get all version of DatasetProfile in question. + // Creates the Criteria to get all version of DescriptionTemplate in question. DatasetProfileCriteria profileCriteria = new DatasetProfileCriteria(); UUID profileId = datasetEntity.getProfile().getGroupId(); List uuidList = new LinkedList<>(); @@ -1053,7 +1053,7 @@ public class DatasetManager { profileCriteria.setGroupIds(uuidList); // Gets the latest version of the datasetProfile. - eu.eudat.data.entities.DatasetProfile item = databaseRepository.getDatasetProfileDao().getWithCriteria(profileCriteria).getSingle(); + DescriptionTemplate item = databaseRepository.getDatasetProfileDao().getWithCriteria(profileCriteria).getSingle(); // Sets the latest version of dataet Profile to the Dataset in question. dataset.setDatasetProfileDefinition(getLatestDatasetProfile(datasetEntity, item)); @@ -1071,7 +1071,7 @@ public class DatasetManager { return dataset; } - public PagedDatasetProfile getLatestDatasetProfile(Dataset datasetEntity, DatasetProfile profile) { + public PagedDatasetProfile getLatestDatasetProfile(Dataset datasetEntity, DescriptionTemplate profile) { eu.eudat.models.data.user.composite.DatasetProfile datasetprofile = userManager.generateDatasetProfileModel(profile); datasetprofile.setStatus(datasetEntity.getStatus()); if (datasetEntity.getProperties() != null) { @@ -1088,7 +1088,7 @@ public class DatasetManager { datasetProfileTableRequestItem.getCriteria().setFilter(DatasetProfileCriteria.DatasetProfileFilter.Datasets.getValue()); datasetProfileTableRequestItem.getCriteria().setUserId(principal.getId()); - QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); + QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); List listingModels = items.select(item -> new DatasetProfileListingModel().fromDataModel(item)); DataTableData data = new DataTableData<>(); @@ -1183,10 +1183,10 @@ public class DatasetManager { DatasetListingModel listingModel = new DatasetListingModel().fromDataModel(item); /*DatasetProfileCriteria criteria = new DatasetProfileCriteria(); criteria.setGroupIds(Collections.singletonList(item.getProfile().getGroupId())); - List profiles = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).toList(); + List profiles = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).toList(); boolean islast = false; if (!profiles.isEmpty()) { - profiles = profiles.stream().sorted(Comparator.comparing(DatasetProfile::getVersion)).collect(Collectors.toList()); + profiles = profiles.stream().sorted(Comparator.comparing(DescriptionTemplate::getVersion)).collect(Collectors.toList()); islast = profiles.get(0).getId().equals(item.getProfile().getId()); } listingModel.setProfileLatestVersion(islast);*/ diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java index 3786dddb2..faf184cf8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java @@ -3,7 +3,7 @@ package eu.eudat.logic.managers; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.UserDatasetProfile; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileAutocompleteRequest; @@ -82,11 +82,12 @@ public class DatasetProfileManager { @Transactional public eu.eudat.models.data.admin.composite.DatasetProfile getDatasetProfile(String id) { - eu.eudat.data.entities.DatasetProfile profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + DescriptionTemplate profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); eu.eudat.models.data.admin.composite.DatasetProfile datasetprofile = AdminManager.generateDatasetProfileModel(profile); datasetprofile.setLabel(profile.getLabel()); datasetprofile.setStatus(profile.getStatus()); datasetprofile.setDescription(profile.getDescription()); + datasetprofile.setType(profile.getType().getName()); datasetprofile.setLanguage(profile.getLanguage()); datasetprofile.setUsers(new ArrayList<>()); retrieveUsers(profile, datasetprofile); @@ -94,35 +95,35 @@ public class DatasetProfileManager { } public List getWithCriteria(DatasetProfileAutocompleteRequest datasetProfileAutocompleteRequest) throws IllegalAccessException, InstantiationException { - QueryableList items = databaseRepository.getDatasetProfileDao().getWithCriteria(datasetProfileAutocompleteRequest.getCriteria()); - QueryableList pagedItems = datasetProfileAutocompleteRequest.applyPaging(items); + QueryableList items = databaseRepository.getDatasetProfileDao().getWithCriteria(datasetProfileAutocompleteRequest.getCriteria()); + QueryableList pagedItems = datasetProfileAutocompleteRequest.applyPaging(items); List datasetProfiles = pagedItems.select(item -> new DatasetProfileAutocompleteItem().fromDataModel(item)); return datasetProfiles; } - public DatasetProfile clone(String id) { - DatasetProfile profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + public DescriptionTemplate clone(String id) { + DescriptionTemplate profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); apiContext.getOperationsContext().getDatabaseRepository().detachEntity(profile); profile.setId(null); return profile; } public DataTableData getPaged(DatasetProfileTableRequestItem datasetProfileTableRequestItem, Principal principal) throws Exception { - QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); - QueryableList authItems = null; + QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); + QueryableList authItems = null; if (principal.getAuthz().contains(Authorities.ADMIN)) { authItems = items; } else if (principal.getAuthz().contains(Authorities.DATASET_PROFILE_MANAGER)) { List roles = Arrays.asList(0, 1); authItems = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getAuthenticated(items, principal.getId(), roles); } - QueryableList pagedItems = PaginationManager.applyPaging(authItems, datasetProfileTableRequestItem); + QueryableList pagedItems = PaginationManager.applyPaging(authItems, datasetProfileTableRequestItem); List datasetProfiles = pagedItems.select(item -> new DatasetProfileListingModel().fromDataModel(item)); return apiContext.getOperationsContext().getBuilderFactory().getBuilder(DataTableDataBuilder.class).data(datasetProfiles).totalCount(items.count()).build(); } public List getAll(DatasetProfileTableRequestItem tableRequestItem) throws IllegalAccessException, InstantiationException { - QueryableList items = databaseRepository.getDatasetProfileDao().getWithCriteria(tableRequestItem.getCriteria()); + QueryableList items = databaseRepository.getDatasetProfileDao().getWithCriteria(tableRequestItem.getCriteria()); List datasetProfiles = items.select(item -> new DatasetProfileListingModel().fromDataModel(item)); return datasetProfiles; @@ -276,36 +277,36 @@ public class DatasetProfileManager { return convFile; } - public eu.eudat.data.entities.DatasetProfile createNewVersionDatasetProfile(String id, eu.eudat.models.data.admin.composite.DatasetProfile profile) throws Exception { - // Getting the DatasetProfile which we will create its new version. - eu.eudat.data.entities.DatasetProfile oldDatasetProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + public DescriptionTemplate createNewVersionDatasetProfile(String id, eu.eudat.models.data.admin.composite.DatasetProfile profile) throws Exception { + // Getting the DescriptionTemplate which we will create its new version. + DescriptionTemplate oldDescriptionTemplate = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); - // Getting the DatasetProfile with the latest Version. + // Getting the DescriptionTemplate with the latest Version. DatasetProfileCriteria criteria = new DatasetProfileCriteria(); LinkedList list = new LinkedList<>(); - list.push(oldDatasetProfile.getGroupId()); + list.push(oldDescriptionTemplate.getGroupId()); criteria.setGroupIds(list); criteria.setAllVersions(false); - QueryableList datasetProfileQueryableList = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria); - eu.eudat.data.entities.DatasetProfile latestVersionDatasetProfile = datasetProfileQueryableList.getSingle(); + QueryableList datasetProfileQueryableList = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria); + DescriptionTemplate latestVersionDescriptionTemplate = datasetProfileQueryableList.getSingle(); - if (latestVersionDatasetProfile.getVersion().equals(oldDatasetProfile.getVersion())){ + if (latestVersionDescriptionTemplate.getVersion().equals(oldDescriptionTemplate.getVersion())){ eu.eudat.models.data.admin.composite.DatasetProfile sortedProfile = profile.toShort(); - eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(sortedProfile, apiContext); -// modelDefinition.setLabel(oldDatasetProfile.getLabel()); - modelDefinition.setVersion((short) (oldDatasetProfile.getVersion() + 1)); - modelDefinition.setGroupId(oldDatasetProfile.getGroupId()); -// modelDefinition.setLanguage(oldDatasetProfile.getLanguage()); + DescriptionTemplate modelDefinition = AdminManager.generateViewStyleDefinition(sortedProfile, apiContext); +// modelDefinition.setLabel(oldDescriptionTemplate.getLabel()); + modelDefinition.setVersion((short) (oldDescriptionTemplate.getVersion() + 1)); + modelDefinition.setGroupId(oldDescriptionTemplate.getGroupId()); +// modelDefinition.setLanguage(oldDescriptionTemplate.getLanguage()); apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); - eu.eudat.data.entities.DatasetProfile datasetProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); - this.storeDatasetProfileUsers(datasetProfile, profile); + DescriptionTemplate descriptionTemplate = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); + this.storeDatasetProfileUsers(descriptionTemplate, profile); return modelDefinition; } else { throw new DatasetProfileNewVersionException("Version to update not the latest."); } } - public void storeDatasetProfileUsers(DatasetProfile entity, eu.eudat.models.data.admin.composite.DatasetProfile model) { + public void storeDatasetProfileUsers(DescriptionTemplate entity, eu.eudat.models.data.admin.composite.DatasetProfile model) { if (model.getUsers() != null && !model.getUsers().isEmpty()) { if (entity.getUsers() == null) { entity.setUsers(new HashSet<>()); @@ -340,7 +341,7 @@ public class DatasetProfileManager { } @Transactional - public void retrieveUsers(DatasetProfile entity, eu.eudat.models.data.admin.composite.DatasetProfile model) { + public void retrieveUsers(DescriptionTemplate entity, eu.eudat.models.data.admin.composite.DatasetProfile model) { if (entity.getUsers() != null && !entity.getUsers().isEmpty()) { model.setUsers(entity.getUsers().stream().filter(userDatasetProfile -> userDatasetProfile.getRole() < 2).map(userDatasetProfile -> { UserInfoListingModel userInfoListingModel = new UserInfoListingModel(); @@ -381,10 +382,10 @@ public class DatasetProfileManager { } public void addSemanticsInDatasetProfiles() throws XPathExpressionException { - List ids = this.databaseRepository.getDatasetProfileDao().getAllIds(); - for(DatasetProfile dp: ids){ - DatasetProfile datasetProfile = this.databaseRepository.getDatasetProfileDao().find(dp.getId()); - Document document = XmlBuilder.fromXml(datasetProfile.getDefinition()); + List ids = this.databaseRepository.getDatasetProfileDao().getAllIds(); + for(DescriptionTemplate dp: ids){ + DescriptionTemplate descriptionTemplate = this.databaseRepository.getDatasetProfileDao().find(dp.getId()); + Document document = XmlBuilder.fromXml(descriptionTemplate.getDefinition()); XPathFactory xpathFactory = XPathFactory.newInstance(); XPath xpath = xpathFactory.newXPath(); XPathExpression expr = xpath.compile("//rdaCommonStandard"); @@ -402,15 +403,15 @@ public class DatasetProfileManager { fieldParent.insertBefore(schematics, rdaPropertyNode); fieldParent.removeChild(rdaPropertyNode); } - this.updateDatasetProfileXml(document, datasetProfile); + this.updateDatasetProfileXml(document, descriptionTemplate); } } public void addRdaInSemanticsInDatasetProfiles() throws XPathExpressionException { - List ids = this.databaseRepository.getDatasetProfileDao().getAllIds(); - for(DatasetProfile dp: ids){ - DatasetProfile datasetProfile = this.databaseRepository.getDatasetProfileDao().find(dp.getId()); - Document document = XmlBuilder.fromXml(datasetProfile.getDefinition()); + List ids = this.databaseRepository.getDatasetProfileDao().getAllIds(); + for(DescriptionTemplate dp: ids){ + DescriptionTemplate descriptionTemplate = this.databaseRepository.getDatasetProfileDao().find(dp.getId()); + Document document = XmlBuilder.fromXml(descriptionTemplate.getDefinition()); XPathFactory xpathFactory = XPathFactory.newInstance(); XPath xpath = xpathFactory.newXPath(); XPathExpression expr = xpath.compile("//schematic"); @@ -422,11 +423,11 @@ public class DatasetProfileManager { schematicNode.setTextContent("rda." + schematicRda); } } - this.updateDatasetProfileXml(document, datasetProfile); + this.updateDatasetProfileXml(document, descriptionTemplate); } } - private void updateDatasetProfileXml(Document document, DatasetProfile datasetProfile) { + private void updateDatasetProfileXml(Document document, DescriptionTemplate descriptionTemplate) { try { DOMSource domSource = new DOMSource(document); StringWriter writer = new StringWriter(); @@ -437,8 +438,8 @@ public class DatasetProfileManager { transformer.transform(domSource, result); String newDefinition = writer.toString(); if(newDefinition != null){ - datasetProfile.setDefinition(newDefinition); - this.databaseRepository.getDatasetProfileDao().createOrUpdate(datasetProfile); + descriptionTemplate.setDefinition(newDefinition); + this.databaseRepository.getDatasetProfileDao().createOrUpdate(descriptionTemplate); } } catch(TransformerException ex) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java index c3c347bcb..20cb2dc9c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java @@ -5,7 +5,7 @@ import eu.eudat.data.dao.entities.DMPDao; import eu.eudat.data.dao.entities.DatasetProfileDao; import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.Dataset; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.query.items.item.dataset.DatasetWizardAutocompleteRequest; import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileWizardAutocompleteRequest; @@ -41,11 +41,11 @@ public class DatasetWizardManager { } DatasetProfileCriteria criteria = new DatasetProfileCriteria(); criteria.setIds(dataManagementPlan.getProfiles().stream().map(AssociatedProfile::getId).collect(Collectors.toList())); - List datasetProfiles = profileDao.getWithCriteria(criteria).toList(); + List descriptionTemplates = profileDao.getWithCriteria(criteria).toList(); criteria.setIds(null); - criteria.setGroupIds(datasetProfiles.stream().map(DatasetProfile::getGroupId).collect(Collectors.toList())); - datasetProfiles = profileDao.getWithCriteria(criteria).toList(); - List profiles = datasetProfiles.stream().map(profile -> new AssociatedProfile().fromData(profile)).collect(Collectors.toList()); + criteria.setGroupIds(descriptionTemplates.stream().map(DescriptionTemplate::getGroupId).collect(Collectors.toList())); + descriptionTemplates = profileDao.getWithCriteria(criteria).toList(); + List profiles = descriptionTemplates.stream().map(profile -> new AssociatedProfile().fromData(profile)).collect(Collectors.toList()); return profiles; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java index b39aebd6d..ba691c1fc 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java @@ -1,7 +1,7 @@ package eu.eudat.logic.managers; import eu.eudat.data.dao.criteria.*; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.services.ApiContext; import eu.eudat.types.MetricNames; import io.micrometer.prometheus.PrometheusMeterRegistry; @@ -33,8 +33,8 @@ public class MetricsManager { private final Map gauges; public static final Map datasetTemplateStatus = Stream.of(new Object[][] { - { DatasetProfile.Status.SAVED.getValue(), MetricNames.DRAFT }, - { DatasetProfile.Status.FINALIZED.getValue(), MetricNames.ACTIVE }, + { DescriptionTemplate.Status.SAVED.getValue(), MetricNames.DRAFT }, + { DescriptionTemplate.Status.FINALIZED.getValue(), MetricNames.ACTIVE }, }).collect(Collectors.toMap(data -> (Short) data[0], data -> (String) data[1])); public void increaseValue(String name, int amount, String label) { @@ -404,9 +404,9 @@ public class MetricsManager { criteria.setStatus(1); criteria.setAllVersions(false); if (countNexus) criteria.setPeriodStart(getNexusDate()); - List datasetProfiles = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).withFields(Collections.singletonList("id")).toList(); + List descriptionTemplates = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).withFields(Collections.singletonList("id")).toList(); DatasetCriteria datasetCriteria = new DatasetCriteria(); - datasetCriteria.setDatasetTemplates(datasetProfiles.stream().map(DatasetProfile::getId).collect(Collectors.toList())); + datasetCriteria.setDatasetTemplates(descriptionTemplates.stream().map(DescriptionTemplate::getId).collect(Collectors.toList())); return apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getWithCriteria(datasetCriteria).select(root -> root.getProfile().getId()).stream().distinct().count(); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java index 81d5fe3e0..10aef32fa 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java @@ -1,7 +1,7 @@ package eu.eudat.logic.managers; import com.fasterxml.jackson.databind.ObjectMapper; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.mapper.prefilling.PrefillingMapper; import eu.eudat.logic.proxy.config.ExternalUrlCriteria; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; @@ -51,8 +51,8 @@ public class PrefillingManager { PrefillingConfig prefillingConfig = configLoader.getExternalUrls().getPrefillings().get(configId); PrefillingGet prefillingGet = prefillingConfig.getPrefillingGet(); Map prefillingEntity = getSingle(prefillingGet.getUrl(), prefillId); - DatasetProfile datasetProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(profileId); - return PrefillingMapper.mapPrefilledEntityToDatasetWizard(prefillingEntity, prefillingGet, prefillingConfig.getType(), datasetProfile, datasetManager, licenseManager); + DescriptionTemplate descriptionTemplate = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(profileId); + return PrefillingMapper.mapPrefilledEntityToDatasetWizard(prefillingEntity, prefillingGet, prefillingConfig.getType(), descriptionTemplate, datasetManager, licenseManager); } private Map getSingle(String url, String id) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java index 3820bdfa7..138730ef4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java @@ -3,13 +3,8 @@ package eu.eudat.logic.managers; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.dao.criteria.DataManagementPlanCriteria; import eu.eudat.data.dao.entities.UserInfoDao; -import eu.eudat.data.entities.Credential; -import eu.eudat.data.entities.DMP; -import eu.eudat.data.entities.UserInfo; -import eu.eudat.data.entities.UserRole; +import eu.eudat.data.entities.*; import eu.eudat.data.query.items.table.userinfo.UserInfoTableRequestItem; -import eu.eudat.exceptions.security.ExpiredTokenException; -import eu.eudat.exceptions.security.NonValidTokenException; import eu.eudat.exceptions.security.NullEmailException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.builders.entity.UserRoleBuilder; @@ -72,7 +67,7 @@ public class UserManager { this.environment = environment; } - public eu.eudat.models.data.user.composite.DatasetProfile generateDatasetProfileModel(eu.eudat.data.entities.DatasetProfile profile) { + public eu.eudat.models.data.user.composite.DatasetProfile generateDatasetProfileModel(DescriptionTemplate profile) { Document viewStyleDoc = XmlBuilder.fromXml(profile.getDefinition()); Element root = (Element) viewStyleDoc.getDocumentElement(); eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel viewstyle = new eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel().fromXml(root); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java index 6545bb32b..65cd3f598 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java @@ -1,11 +1,11 @@ package eu.eudat.logic.mapper.elastic; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.elastic.entities.DatasetTempalate; public class DatasetTemplateMapper { - public static DatasetTempalate toElastic(DatasetProfile profile) { + public static DatasetTempalate toElastic(DescriptionTemplate profile) { DatasetTempalate elastic = new DatasetTempalate(); elastic.setId(profile.getId()); elastic.setName(profile.getLabel()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java index 9efc1e713..cb5054938 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.Dataset; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.elastic.entities.Tag; import eu.eudat.logic.managers.DatasetManager; import eu.eudat.logic.managers.DatasetProfileManager; @@ -37,7 +37,7 @@ public class PrefillingMapper { private static final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); public static DatasetWizardModel mapPrefilledEntityToDatasetWizard(Map prefilledEntity, PrefillingGet prefillingGet, String type, - DatasetProfile profile, DatasetManager datasetManager, LicenseManager licenseManager) throws Exception { + DescriptionTemplate profile, DatasetManager datasetManager, LicenseManager licenseManager) throws Exception { DatasetWizardModel datasetWizardModel = new DatasetWizardModel(); datasetWizardModel.setProfile(new DatasetProfileOverviewModel().fromDataModel(profile)); Dataset dataset = new Dataset(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/DatasetProfile.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/DatasetProfile.java index 2ae1a2d34..a7d29e30e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/DatasetProfile.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/DatasetProfile.java @@ -1,6 +1,8 @@ package eu.eudat.logic.utilities.documents.xml.datasetProfileXml.datasetProfileModel; +import eu.eudat.data.entities.DescriptionTemplate; + import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @@ -45,7 +47,7 @@ public class DatasetProfile { public eu.eudat.models.data.admin.composite.DatasetProfile toAdminCompositeModel(String label){ eu.eudat.models.data.admin.composite.DatasetProfile newDatasetEntityProfile = new eu.eudat.models.data.admin.composite.DatasetProfile(); newDatasetEntityProfile.setLabel(label); - newDatasetEntityProfile.setStatus(eu.eudat.data.entities.DatasetProfile.Status.SAVED.getValue()); + newDatasetEntityProfile.setStatus(DescriptionTemplate.Status.SAVED.getValue()); newDatasetEntityProfile.setDescription(description); newDatasetEntityProfile.setLanguage(language); List pagesDatasetEntity = new LinkedList<>(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetprofile/DatasetProfileAutocompleteItem.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetprofile/DatasetProfileAutocompleteItem.java index 34eac149e..e359c41b6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetprofile/DatasetProfileAutocompleteItem.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetprofile/DatasetProfileAutocompleteItem.java @@ -1,12 +1,12 @@ package eu.eudat.models.data.datasetprofile; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.models.DataModel; import java.util.UUID; -public class DatasetProfileAutocompleteItem implements DataModel { +public class DatasetProfileAutocompleteItem implements DataModel { private UUID id; private String label; @@ -34,7 +34,7 @@ public class DatasetProfileAutocompleteItem implements DataModel { +public class DatasetProfileListingModel implements DataModel { private UUID id; private String label; @@ -66,7 +66,7 @@ public class DatasetProfileListingModel implements DataModel { +public class DatasetProfileOverviewModel implements DataModel { private UUID id; private String label; @@ -24,15 +24,15 @@ public class DatasetProfileOverviewModel implements DataModel { return this; } - public DatasetProfile toData() { - DatasetProfile profile = new DatasetProfile(); + public DescriptionTemplate toData() { + DescriptionTemplate profile = new DescriptionTemplate(); profile.setId(this.id); profile.setLabel(this.label); return profile; } - public AssociatedProfile fromData(DatasetProfile entity) { + public AssociatedProfile fromData(DescriptionTemplate entity) { this.id = entity.getId(); this.label = entity.getLabel(); return this; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java index 6c4018f81..f86cea599 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java @@ -9,7 +9,6 @@ import eu.eudat.models.data.dynamicfields.DynamicFieldWithValue; import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile; import eu.eudat.models.data.funder.Funder; import eu.eudat.models.data.helpermodels.Tuple; -import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.listingmodels.UserInfoListingModel; import eu.eudat.models.data.grant.Grant; import eu.eudat.models.data.project.Project; @@ -259,8 +258,8 @@ public class DataManagementPlan implements DataModel { if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) { this.profiles = new LinkedList<>(); - for (DatasetProfile datasetProfile: entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(datasetProfile); + for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate); this.profiles.add(associatedProfile); } } @@ -321,11 +320,11 @@ public class DataManagementPlan implements DataModel { dataManagementPlanEntity.setProject(this.project.toDataModel()); } if (this.profiles != null) { - Set datasetProfiles = new HashSet<>(); + Set descriptionTemplates = new HashSet<>(); for (AssociatedProfile profile : this.profiles) { - datasetProfiles.add(profile.toData()); + descriptionTemplates.add(profile.toData()); } - dataManagementPlanEntity.setAssociatedDmps(datasetProfiles); + dataManagementPlanEntity.setAssociatedDmps(descriptionTemplates); } dataManagementPlanEntity.setProperties(this.properties != null ? JSONObject.toJSONString(this.properties) : null); dataManagementPlanEntity.setGroupId(this.groupId != null ? this.groupId : UUID.randomUUID()); @@ -366,8 +365,8 @@ public class DataManagementPlan implements DataModel { if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) { this.profiles = new LinkedList<>(); - for (DatasetProfile datasetProfile: entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(datasetProfile); + for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate); this.profiles.add(associatedProfile); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java index 1eca8b81c..fc1cd7f84 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java @@ -8,7 +8,6 @@ import eu.eudat.models.data.dynamicfields.DynamicFieldWithValue; import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile; import eu.eudat.models.data.funder.FunderDMPEditorModel; import eu.eudat.models.data.helpermodels.Tuple; -import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.listingmodels.UserInfoListingModel; import eu.eudat.models.data.grant.GrantDMPEditorModel; import eu.eudat.models.data.project.ProjectDMPEditorModel; @@ -250,8 +249,8 @@ public class DataManagementPlanEditorModel implements DataModel(); - for (DatasetProfile datasetProfile: entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(datasetProfile); + for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate); this.profiles.add(associatedProfile); } } @@ -359,11 +358,11 @@ public class DataManagementPlanEditorModel implements DataModel datasetProfiles = new HashSet<>(); + Set descriptionTemplates = new HashSet<>(); for (AssociatedProfile profile : this.profiles) { - datasetProfiles.add(profile.toData()); + descriptionTemplates.add(profile.toData()); } - dataManagementPlanEntity.setAssociatedDmps(datasetProfiles); + dataManagementPlanEntity.setAssociatedDmps(descriptionTemplates); } dataManagementPlanEntity.setProperties(this.properties != null ? JSONObject.toJSONString(this.properties) : null); dataManagementPlanEntity.setGroupId(this.groupId != null ? this.groupId : UUID.randomUUID()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java index c207ab1fb..98d491343 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java @@ -2,7 +2,7 @@ package eu.eudat.models.data.listingmodels; import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.Dataset; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.models.DataModel; import eu.eudat.models.data.dataset.DatasetOverviewModel; import eu.eudat.models.data.dmp.AssociatedProfile; @@ -205,8 +205,8 @@ public class DataManagementPlanOverviewModel implements DataModel(); - for (DatasetProfile datasetProfile : entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(datasetProfile); + for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate); this.associatedProfiles.add(associatedProfile); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DatasetDescriptionQuickWizardModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DatasetDescriptionQuickWizardModel.java index 5b3392689..1806e1eb7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DatasetDescriptionQuickWizardModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DatasetDescriptionQuickWizardModel.java @@ -1,15 +1,13 @@ package eu.eudat.models.data.quickwizard; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.models.data.datasetprofile.DatasetProfileOverviewModel; import eu.eudat.models.data.dmp.DataManagementPlan; -import eu.eudat.data.entities.Dataset; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.user.composite.PagedDatasetProfile; import java.util.Date; -import java.util.UUID; public class DatasetDescriptionQuickWizardModel extends PagedDatasetProfile { @@ -24,7 +22,7 @@ public class DatasetDescriptionQuickWizardModel extends PagedDatasetProfile { } - public DatasetWizardModel toDataModel(DataManagementPlan dmp, DatasetProfile profile){ + public DatasetWizardModel toDataModel(DataManagementPlan dmp, DescriptionTemplate profile){ DatasetWizardModel newDataset = new DatasetWizardModel(); newDataset.setLabel(datasetLabel); newDataset.setCreated(new Date()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java index d67f9724b..427172351 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java @@ -1,5 +1,6 @@ package eu.eudat.models.data.quickwizard; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.Grant; import eu.eudat.data.entities.Project; import eu.eudat.models.data.dmp.AssociatedProfile; @@ -107,12 +108,12 @@ public class DmpQuickWizardModel { } - public eu.eudat.data.entities.DatasetProfile getDatasetProfile() { - eu.eudat.data.entities.DatasetProfile datasetProfile = new eu.eudat.data.entities.DatasetProfile(); - datasetProfile.setDefinition(this.datasetProfile.getLabel()); - datasetProfile.setLabel(this.datasetProfile.getLabel()); - datasetProfile.setId(this.datasetProfile.getId()); - return datasetProfile; + public DescriptionTemplate getDatasetProfile() { + DescriptionTemplate descriptionTemplate = new DescriptionTemplate(); + descriptionTemplate.setDefinition(this.datasetProfile.getLabel()); + descriptionTemplate.setLabel(this.datasetProfile.getLabel()); + descriptionTemplate.setId(this.datasetProfile.getId()); + return descriptionTemplate; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java index 4bcf83017..9beede1b5 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java @@ -2,7 +2,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.elastic.criteria.DatasetCriteria; import eu.eudat.elastic.entities.Tag; import eu.eudat.logic.managers.DatasetManager; @@ -268,12 +268,12 @@ public class DatasetRDAMapper { } - public eu.eudat.data.entities.Dataset toEntity(Dataset rda, DatasetProfile defaultProfile) { + public eu.eudat.data.entities.Dataset toEntity(Dataset rda, DescriptionTemplate defaultProfile) { eu.eudat.data.entities.Dataset entity = new eu.eudat.data.entities.Dataset(); entity.setLabel(rda.getTitle()); entity.setDescription(rda.getDescription()); try { - DatasetProfile profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(rda.getAdditionalProperties().get("template").toString())); + DescriptionTemplate profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(rda.getAdditionalProperties().get("template").toString())); entity.setProfile(profile); }catch(Exception e) { logger.warn(e.getMessage(), e); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java index 2cf81d3bd..5272cc6cd 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java @@ -133,7 +133,7 @@ public class DmpRDAMapper { } if (profiles != null) { for (String profile : profiles) { - DatasetProfile exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(profile)); + DescriptionTemplate exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(profile)); entity.getAssociatedDmps().add(exProfile); } } @@ -143,7 +143,7 @@ public class DmpRDAMapper { entity.setCreated(rda.getCreated()); entity.setModified(rda.getModified()); entity.setDescription(rda.getDescription()); - DatasetProfile defaultProfile = ((DatasetProfile)entity.getAssociatedDmps().toArray()[0]); + DescriptionTemplate defaultProfile = ((DescriptionTemplate)entity.getAssociatedDmps().toArray()[0]); entity.setDataset(rda.getDataset().stream().map(rda1 -> datasetRDAMapper.toEntity(rda1, defaultProfile)).collect(Collectors.toSet())); if (rda.getProject().size() > 0) { Map result = ProjectRDAMapper.toEntity(rda.getProject().get(0), apiContext); @@ -159,7 +159,7 @@ public class DmpRDAMapper { return entity; } - private DatasetProfile getProfile(String id) { + private DescriptionTemplate getProfile(String id) { return apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().asQueryable().where(((builder, root) -> builder.equal(root.get("id"), UUID.fromString(id)))).getSingleOrDefault(); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java index e94db3db8..7e88973c0 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java @@ -1,6 +1,7 @@ package eu.eudat.publicapi.managers; import eu.eudat.data.entities.Dataset; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.definition.helpers.ColumnOrderings; import eu.eudat.elastic.criteria.DatasetCriteria; import eu.eudat.elastic.repository.DatasetRepository; @@ -139,10 +140,10 @@ public class DatasetPublicManager { DatasetPublicListingModel listingPublicModel = new DatasetPublicListingModel().fromDataModel(item); /*DatasetProfileCriteria criteria = new DatasetProfileCriteria(); criteria.setGroupIds(Collections.singletonList(item.getProfile().getGroupId())); - List profiles = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).toList(); + List profiles = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).toList(); boolean islast = false; if (!profiles.isEmpty()) { - profiles = profiles.stream().sorted(Comparator.comparing(DatasetProfile::getVersion)).collect(Collectors.toList()); + profiles = profiles.stream().sorted(Comparator.comparing(DescriptionTemplate::getVersion)).collect(Collectors.toList()); islast = profiles.get(0).getId().equals(item.getProfile().getId()); } listingModel.setProfileLatestVersion(islast);*/ @@ -162,7 +163,7 @@ public class DatasetPublicManager { return pagedDatasetProfile; } - private eu.eudat.models.data.user.composite.DatasetProfile generateDatasetProfileModel(eu.eudat.data.entities.DatasetProfile profile) { + private eu.eudat.models.data.user.composite.DatasetProfile generateDatasetProfileModel(DescriptionTemplate profile) { Document viewStyleDoc = XmlBuilder.fromXml(profile.getDefinition()); Element root = (Element) viewStyleDoc.getDocumentElement(); eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel viewstyle = new eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel().fromXml(root); diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java index 10edac3ca..d2783e56a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java @@ -1,6 +1,6 @@ package eu.eudat.publicapi.models.associatedprofile; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.utilities.interfaces.XmlSerializable; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -42,14 +42,14 @@ public class AssociatedProfilePublicModel implements XmlSerializable { +public class DatasetProfilePublicModel implements DataModel { private UUID id; private String label; @@ -24,15 +24,15 @@ public class DatasetProfilePublicModel implements DataModel(); - for (DatasetProfile datasetProfile : entity.getAssociatedDmps()) { - AssociatedProfilePublicModel associatedProfile = new AssociatedProfilePublicModel().fromData(datasetProfile); + for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) { + AssociatedProfilePublicModel associatedProfile = new AssociatedProfilePublicModel().fromData(descriptionTemplate); this.associatedProfiles.add(associatedProfile); } } @@ -217,7 +217,7 @@ public class DataManagementPlanPublicModel implements DataModel import('./ui/dataset/dataset.module').then(m => m.DatasetModule), data: { breadcrumb: true, - title: 'GENERAL.TITLES.DATASETS' + title: 'GENERAL.TITLES.DESCRIPTIONS' } }, { @@ -80,7 +80,7 @@ const appRoutes: Routes = [ loadChildren: () => import('./ui/admin/dmp-profile/dmp-profile.module').then(m => m.DmpProfileModule), data: { breadcrumb: true, - title: 'GENERAL.TITLES.DMP-PROFILES' + title: 'GENERAL.TITLES.DMP-BLUEPRINTS' } }, { diff --git a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts index 94e9ca3dc..b33a781c5 100644 --- a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts +++ b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts @@ -30,7 +30,7 @@ export class EnumUtils { case AppRole.Admin: return this.language.instant('TYPES.APP-ROLE.ADMIN'); case AppRole.User: return this.language.instant('TYPES.APP-ROLE.USER'); case AppRole.Manager: return this.language.instant('TYPES.APP-ROLE.MANAGER'); - case AppRole.DatasetTemplateEditor: return this.language.instant('TYPES.APP-ROLE.DATASET-TEMPLATE-EDITOR'); + case AppRole.DatasetTemplateEditor: return this.language.instant('TYPES.APP-ROLE.DESCRIPTION-TEMPLATE-EDITOR'); } } diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html index c1036626b..adb990e47 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html @@ -8,7 +8,7 @@
- +
diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html index 795ff063d..18fa44347 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html @@ -22,7 +22,7 @@
- +
@@ -49,13 +49,13 @@
{{'DASHBOARD.EMPTY-LIST' | translate}}
- - + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
@@ -69,7 +69,7 @@
0
{{'DASHBOARD.DMPS' | translate}}
0
- {{'DASHBOARD.DATASET-DESCRIPTIONS' | translate}} + {{'DASHBOARD.DESCRIPTIONS' | translate}}
0
{{'DASHBOARD.GRANTS' | translate}}
0
@@ -83,7 +83,7 @@ {{'DASHBOARD.DMPS' | translate}}
{{dashboardStatisticsData?.totalDataSetCount}}
- {{'DASHBOARD.DATASET-DESCRIPTIONS' | translate}} + {{'DASHBOARD.DESCRIPTIONS' | translate}}
{{dashboardStatisticsData?.totalGrantCount}}
{{'DASHBOARD.GRANTS' | translate}} @@ -147,7 +147,7 @@
{{'DASHBOARD.EMPTY-LIST' | translate}}
diff --git a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html index 752fe315a..47e21aab6 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html @@ -26,7 +26,7 @@
-
{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}
+
{{'DATASET-LISTING.DESCRIPTION' | translate}}
{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | dateTimeCultureFormatter: "d MMMM y"}}
{{activity.label}}
@@ -50,7 +50,7 @@
-
{{'DMP-LISTING.CONTAINED-DATASETS' | translate}}: ({{ getDatasets(activity).length }}) +
{{'DMP-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ getDatasets(activity).length }})
@@ -61,7 +61,7 @@
open_in_new{{'DMP-LISTING.ACTIONS.EXPORT' | translate}} - add{{'DMP-LISTING.ACTIONS.ADD-DATASET-SHORT' | translate}} + add{{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}} group_add{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}} filter_none{{'DMP-LISTING.ACTIONS.CLONE' | translate}} library_books{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}} @@ -106,7 +106,7 @@
-
{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}
+
{{'DATASET-LISTING.DESCRIPTION' | translate}}
{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | dateTimeCultureFormatter: "d MMMM y"}}
{{'DATASET-LISTING.STATES.PUBLISHED' | translate}}: {{activity.publishedAt | dateTimeCultureFormatter: "d MMMM y"}}
@@ -132,7 +132,7 @@
-
{{'DMP-LISTING.CONTAINED-DATASETS' | translate}}: ({{ activity.datasets.length }}) +
{{'DMP-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ activity.datasets.length }})
@@ -55,7 +55,7 @@
open_in_new{{'DMP-LISTING.ACTIONS.EXPORT' | translate}} - add{{'DMP-LISTING.ACTIONS.ADD-DATASET-SHORT' | translate}} + add{{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}} group_add{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}} filter_none{{'DMP-LISTING.ACTIONS.CLONE' | translate}} library_books{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}} diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html index a33d78874..d6c8feb05 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html @@ -10,7 +10,7 @@
{{'DMP-EDITOR.TITLE.ADD-DATASET' | translate}}
-
{{'DMP-EDITOR.TITLE.EDIT-DATASET' | translate}}
+
{{'DMP-EDITOR.TITLE.EDIT-DESCRIPTION' | translate}}
{{ formGroup.get('label').value }} ({{'DMP-EDITOR.CHANGES' | translate}})
@@ -183,7 +183,7 @@
-

{{(isPublic ? 'GENERAL.TITLES.EXPLORE' : 'GENERAL.TITLES.DATASETS') | translate}}

+

{{(isPublic ? 'GENERAL.TITLES.EXPLORE' : 'GENERAL.TITLES.DESCRIPTIONS') | translate}}

diff --git a/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.html b/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.html index b5bea4415..a6ab5e51f 100644 --- a/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.html +++ b/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.html @@ -1,7 +1,7 @@
-
{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}
+
{{'DATASET-LISTING.DESCRIPTION' | translate}}
{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{dataset.modified | dateTimeCultureFormatter: "d MMMM y"}}
{{'DATASET-LISTING.STATES.PUBLISHED' | translate}}: {{dataset.dmpPublishedAt | dateTimeCultureFormatter: "d MMMM y"}}
@@ -27,7 +27,7 @@
+
diff --git a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html b/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html index bd09b9352..491cb45f0 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html @@ -6,7 +6,7 @@
-
4.1 {{'DMP-EDITOR.STEPPER.DATASET-INFO' | translate}}*
+
4.1 {{'DMP-EDITOR.STEPPER.DESCRIPTION-INFO' | translate}}*
{{'DMP-EDITOR.DATASET-INFO.HINT' | translate}}
info {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}
diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html index 37a0be5d1..0210e3819 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html @@ -76,8 +76,8 @@
  • {{'DMP-EDITOR.STEPPER.LICENSE-INFO' | translate}}
  • -
  • {{'DMP-EDITOR.STEPPER.DATASET-INFO' | translate}} (1)
  • -
  • {{'DMP-EDITOR.STEPPER.DATASET-INFO' | translate}} (done)
  • +
  • {{'DMP-EDITOR.STEPPER.DESCRIPTION-INFO' | translate}} (1)
  • +
  • {{'DMP-EDITOR.STEPPER.DESCRIPTION-INFO' | translate}} (done)
  • @@ -91,7 +91,7 @@ @@ -108,7 +108,7 @@
  • diff --git a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html index e83c9cb4d..495dc022a 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html +++ b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html @@ -17,7 +17,7 @@ . {{ 'DMP-LISTING.GRANT' | translate }}: {{dmp.grant}}
    -
    {{'DMP-LISTING.CONTAINED-DATASETS' | translate}}: ({{ dmp.datasets.length }}) +
    {{'DMP-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ dmp.datasets.length }})
    @@ -29,7 +29,7 @@
    open_in_new{{'DMP-LISTING.ACTIONS.EXPORT' | translate}} - add{{'DMP-LISTING.ACTIONS.ADD-DATASET-SHORT' | translate}} + add{{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}} group_add{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}} filter_none{{'DMP-LISTING.ACTIONS.CLONE' | translate}} library_books{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}} diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html index 0d69b4b3a..f64512914 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html @@ -87,7 +87,7 @@
    horizontal_rule
    -
    {{'DMP-OVERVIEW.DATASETS-USED' | translate}}
    +
    {{'DMP-OVERVIEW.DESCRIPTIONS-USED' | translate}}
    diff --git a/dmp-frontend/src/app/ui/dmp/wizard/listing/dmp-wizard-dataset-listing.component.html b/dmp-frontend/src/app/ui/dmp/wizard/listing/dmp-wizard-dataset-listing.component.html index b9e9cafb4..989e43042 100644 --- a/dmp-frontend/src/app/ui/dmp/wizard/listing/dmp-wizard-dataset-listing.component.html +++ b/dmp-frontend/src/app/ui/dmp/wizard/listing/dmp-wizard-dataset-listing.component.html @@ -1,6 +1,6 @@
    -
    {{'DATASET-LISTING.SELECT-DATASETS-TO-CLONE' | translate}} {{titlePrefix}}
    +
    {{'DATASET-LISTING.SELECT-DESCRIPTIONS-TO-CLONE' | translate}} {{titlePrefix}}
    @@ -10,6 +10,6 @@
    -
    {{'DATASET-LISTING.SELECT-DATASETS-NONE' | translate}}
    +
    {{'DATASET-LISTING.SELECT-DESCRIPTIONS-NONE' | translate}}
    diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts index c417425b2..48bccf255 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts @@ -31,7 +31,7 @@ export const GENERAL_ROUTES: RouteInfo[] = [ ]; export const DMP_ROUTES: RouteInfo[] = [ { path: '/plans', title: 'SIDE-BAR.MY-DMPS', icon: 'library_books' }, - { path: '/datasets', title: 'SIDE-BAR.MY-DATASETS', icon: 'dns' }, + { path: '/datasets', title: 'SIDE-BAR.MY-DESCRIPTIONS', icon: 'dns' }, // { path: '/quick-wizard', title: 'SIDE-BAR.QUICK-WIZARD', icon: 'play_circle_outline' }, // { path: '/plans/new', title: 'SIDE-BAR.ADD-EXPERT', icon: 'playlist_add' } ]; @@ -51,15 +51,16 @@ export const PUBLIC_ROUTES: RouteInfo[] = [ // ]; export const ADMIN_ROUTES: RouteInfo[] = [ - { path: '/dmp-profiles', title: 'SIDE-BAR.DMP-TEMPLATES', icon: 'library_books' }, - { path: '/dataset-profiles', title: 'SIDE-BAR.DATASET-TEMPLATES', icon: 'library_books' }, + { path: '/dmp-profiles', title: 'SIDE-BAR.DMP-BLUEPRINTS', icon: 'library_books' }, + { path: '/dataset-profiles', title: 'SIDE-BAR.DESCRIPTION-TEMPLATES', icon: 'library_books' }, + { path: '/description-types', title: 'SIDE-BAR.DESCRIPTION-TEMPLATE-TYPES', icon: 'library_books' }, { path: '/users', title: 'SIDE-BAR.USERS', icon: 'people' }, { path: '/language-editor', title: 'SIDE-BAR.LANGUAGE-EDITOR', icon: 'language' }, { path: '/user-guide-editor', title: 'SIDE-BAR.GUIDE-EDITOR', icon: 'import_contacts' } ]; export const DATASET_TEMPLATE_ROUTES: RouteInfo[] = [ - { path: '/dataset-profiles', title: 'SIDE-BAR.DATASET-TEMPLATES', icon: 'library_books' } + { path: '/dataset-profiles', title: 'SIDE-BAR.DESCRIPTION-TEMPLATES', icon: 'library_books' } ]; export const INFO_ROUTES: RouteInfo[] = [ diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index a608c8ca0..228e900f1 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -28,6 +28,8 @@ "UNSUCCESSFUL-LOGIN": "Unsuccessful Login", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Successful Delete", "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "This template can not deleted, because Datasets are associated with it", + "SUCCESSFUL-DESCRIPTION-TEMPLATE-TYPE-DELETE": "Successful Delete", + "UNSUCCESSFUL-DESCRIPTION-TEMPLATE-TYPE-DELETE": "This type can not deleted, because Descriptions are associated with it", "SUCCESSFUL-DELETE": "Successful Delete", "UNSUCCESSFUL-DELETE": "Unsuccessful Delete", "UNSUCCESSFUL-EMAIL-SEND": "Failed sending email", @@ -133,12 +135,13 @@ "QUICK-WIZARD": "New DMP (Wizard)", "PLANS-NEW": "New DMP (Expert)", "DMP-NEW": "New DMP", - "DATASETS": "My Datasets", - "EXPLORE": "Published Datasets", + "DESCRIPTIONS": "My Descriptions", + "EXPLORE": "Published Descriptions", "DATASETCREATEWIZARD": "Add Dataset (Wizard)", "GRANTS": "My Grants", - "DMP-PROFILES": "DMP Templates", + "DMP-BLUEPRINTS": "DMP Blueprints", "DATASET-PROFILES": "Dataset Templates", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Users", "PROFILE": "My Profile", "LOGIN": "Login", @@ -151,10 +154,12 @@ "DATASET-NEW": "New Dataset", "GRANT-NEW": "New Grant", "GRANT-EDIT": "View/Edit Grant", - "DMP-PROFILE-NEW": "New DMP Template", - "DMP-PROFILE-EDIT": "Edit DMP Template", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", "DATASET-PROFILES-NEW": "New Dataset Template", "DATASET-PROFILES-EDIT": "Edit Dataset Template", + "DESCRIPTION-TYPE-NEW": "New Description Type", + "DESCRIPTION-TYPE-EDIT": "Edit Description Type", "EXPLORE-PLANS-OVERVIEW": "Published DMP Overview", "DATASET-PUBLIC-EDIT": "View Published Dataset", "DMP-PUBLIC-EDIT": "View Published DMP", @@ -219,11 +224,11 @@ "DMPS": "DMPs", "MY-DMPS": "MY DMPs", "DATASETS": "Datasets", - "DATASET": "Dataset", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "Explore {{ APP_NAME_CAPS }}", "USERS": "Users", "DATASETS-ADMIN": "Dataset Templates", - "DMP-PROFILES": "DMP Templates", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "About", "MY-DATASET-DESCRIPTIONS": "MY DATASETS", "DATASET-DESCRIPTION-WIZARD": "Dataset wizard", @@ -233,7 +238,7 @@ "DMP-WIZARD": "DMP Wizard", "DATASET-TEMPLATES": "DATASET TEMPLATES", "TEMPLATE": "TEMPLATE", - "DMP-TEMPLATES": "DMP TEMPLATES", + "DMP-BLUEPRINTS-CAPS": "DMP BLUEPRINTS", "USERS-BREADCRUMB": "USERS", "START-NEW-DMP": "Start new DMP", "START-NEW-DMP-TXT": "Start fresh or continue work in {{ APP_NAME }}! Create a new DMP or upload an existing DMP to {{ APP_NAME }}", @@ -259,18 +264,19 @@ "QUICK-WIZARD-DATASET": "Add Dataset (Wizard)", "ADD-EXPERT": "New DMP (Expert)", "MY-DATASET-DESC": "My Dataset Desc.", - "MY-DATASETS": "My Datasets", + "MY-DESCRIPTIONS": "My Descriptions", "MY-GRANTS": "My Grants", "HISTORY": "HISTORY", "HISTORY-VISITED": "LAST VISITED", "HISTORY-EDITED": "LAST EDITED", "PUBLIC": "PUBLISHED", "PUBLIC-DMPS": "Public DMPs", - "PUBLIC-DESC": "Public Dataset Desc.", + "PUBLIC-DESC": "Public Descriptions", "ACCOUNT": "ACCOUNT", "ADMIN": "ADMIN", - "DATASET-TEMPLATES": "Dataset Templates", - "DMP-TEMPLATES": "DMP Templates", + "DESCRIPTION-TEMPLATES": "Description Templates", + "DESCRIPTION-TEMPLATE-TYPES": "Description Types", + "DMP-BLUEPRINTS": "DMP Blueprints", "USERS": "Users", "LANGUAGE-EDITOR": "Language Editor", "GUIDE-EDITOR": "User Guide Editor", @@ -281,23 +287,25 @@ "DATASET-PROFILE-EDITOR": { "TITLE": { "NEW": "New API Client", - "NEW-PROFILE": "New Dataset Template", + "NEW-PROFILE": "New Description Template", "NEW-PROFILE-VERSION": "New Version Of ", "NEW-PROFILE-CLONE": "New Clone Of " }, "FIELDS": { - "DATASET-TITLE": "Dataset Template Name", + "DATASET-TITLE": "Description Template Name", "DATASET-DESCRIPTION": "Description", "ROLES": "Roles" }, "STEPS": { "GENERAL-INFO": { "TITLE": "General Info", - "DATASET-TEMPLATE-NAME": "Dataset template name", - "DATASET-TEMPLATE-NAME-HINT": "A title that determines the Dataset template.", + "DATASET-TEMPLATE-NAME": "Description template name", + "DATASET-TEMPLATE-NAME-HINT": "A title that determines the Description template.", "DATASET-TEMPLATE-DESCRIPTION": "Description", "DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Dataset is about, it's scope and objectives.", - "DATASET-TEMPLATE-LANGUAGE": "Dataset template language", + "DESCRIPTION-TEMPLATE-TYPE": "Description template type", + "DESCRIPTION-TEMPLATE-SELECT-TYPE": "Select a type", + "DATASET-TEMPLATE-LANGUAGE": "Description template language", "DATASET-TEMPLATE-SELECT-LANGUAGE": "Select a language", "DATASET-TEMPLATE-USERS": "Editors", "DATASET-TEMPLATE-USERS-HINT": "Add editors and save changes to notify them.", @@ -314,7 +322,7 @@ }, "PAGE-INFO": { "PAGE-NAME": "Chapter Name", - "PAGE-NAME-HINT": "Set a name for the dataset chapter.", + "PAGE-NAME-HINT": "Set a name for the desciption chapter.", "PAGE-DESCRIPTION": "Description", "PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the chapter is about.", "ACTIONS": { @@ -615,7 +623,7 @@ "FINALIZED": "Finalized", "PUBLISHED": "Published", "VERSION": "Version", - "CONTAINED-DATASETS": "Contained Datasets", + "CONTAINED-DESCRIPTIONS": "Contained Descriptions", "TEXT-INFO": "Information in a DMP show how datasets have been collected and/or generated, how they have been processed and analysed, i.e. using which tools, standards, methodologies etc, but also where and how datasets are backed up, published and preserved, including any costs associated with personnel dedicated for data curation/ stewardship activities or costs for acquiring or building data management services.", "TEXT-INFO-QUESTION": "Not sure how a DMP looks in practice? Browse Public DMPs and", "LINK-ZENODO": "LIBER community in Zenodo", @@ -642,8 +650,7 @@ "INVITE-AUTHORS": "Invite authors", "INVITE-SHORT": "Invite", "ADD-DATASET": "Add Dataset To DMP", - "ADD-DATASET-DESCRIPTION": "Add dataset", - "ADD-DATASET-SHORT": "Add Dataset", + "ADD-DESCRIPTION-SHORT": "Add Description", "DATASETS": "List All DMP Datasets", "NEW-VERSION": "New Version", "START-NEW-VERSION": "Start New Version", @@ -745,7 +752,7 @@ "DOWNLOAD-PDF": "Download PDF", "DOWNLOAD-XML": "Download XML", "DOWNLOAD-DOCX": "Download DOCX", - "COPY-DATASET": "Copy Dataset", + "COPY-DESCRIPTION": "Copy Description", "UPDATE-DATASET-PROFILE": "Update Template", "VALIDATE":"Validate", "UNDO-FINALIZATION-QUESTION" :"Undo finalization?", @@ -794,7 +801,7 @@ "GRANT": "Grant", "DMP-AUTHORS": "DΜP Authors", "RESEARCHERS": "Researchers", - "DATASETS-USED": "Datasets used", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Collaborators", "PUBLIC": "Public", "PRIVATE": "Private", @@ -829,7 +836,7 @@ } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Dataset authors", + "DESCRIPTION-AUTHORS": "Description authors", "ERROR": { "DELETED-DATASET": "The requested dataset is deleted", "FORBIDEN-DATASET": "You are not allowed to access this dataset" @@ -846,9 +853,9 @@ }, "DATASET-LISTING": { "TITLE": "Datasets", - "DATASET-DESCRIPTION": "Dataset", - "SELECT-DATASETS-TO-CLONE": "Select which datasets to include in the new DMP. Selected datasets will be editable.", - "SELECT-DATASETS-NONE": "Not available Datasets for this DMP.", + "DESCRIPTION": "Description", + "SELECT-DESCRIPTIONS-TO-CLONE": "Select which descriptions to include in the new DMP. Selected descriptions will be editable.", + "SELECT-DESCRIPTIONS-NONE": "Not available Descriptions for this DMP.", "TEXT-INFO": "Datasets are documented following pre-defined templates which set the content of dataset descriptions. In {{ APP_NAME }}, a DMP can contain as many dataset descriptions as the datasets it documents. Browse ", "TEXT-INFO-REST": " for a look at datasets described in {{ APP_NAME }} DMPs", "LINK-PUBLIC-DATASETS": "Public Datasets", @@ -913,7 +920,7 @@ "EMPTY-LIST": "Nothing here yet." }, "DATASET-PROFILE-LISTING": { - "TITLE": "Dataset Templates", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "Name", "REFERNCE": "Reference", @@ -941,9 +948,20 @@ "CLONE": "Clone", "NEW-VERSION": "New Version", "NEW-VERSION-FROM-FILE": "New Version from File", - "VIEW-VERSIONS": "All Dataset Template Versions", + "VIEW-VERSIONS": "All Description Template Versions", "DELETE": "Delete", - "CREATE-DATASET-TEMPLATE": "Create Dataset Template" + "CREATE-DESCRIPTION-TEMPLATE": "Create Description Template" + } + }, + "DESCRIPTION-TYPES-LISTING": { + "TITLE": "Description Types", + "CREATE-TYPE": "Create Description Type", + "COLUMNS": { + "NAME": "Name", + "STATUS": "Status" + }, + "ACTIONS": { + "DELETE": "Delete" } }, "DATASET-UPLOAD": { @@ -962,9 +980,19 @@ "UNSUCCESSFUL": "Something went wrong" } }, + "DESCRIPTION-TYPE-EDITOR": { + "NEW": "New Description Type", + "FIELDS": { + "LABEL": "Name" + }, + "ACTIONS": { + "SAVE": "Save", + "CANCEL": "Cancel" + } + }, "DMP-PROFILE-EDITOR": { "TITLE": { - "NEW": "New DMP Template", + "NEW": "New DMP Blueprint", "EDIT": "Edit" }, "FIELDS": { @@ -1024,7 +1052,7 @@ "EDIT": "Edit", "EDIT-DMP": "Editing DMP", "ADD-DATASET": "Adding dataset", - "EDIT-DATASET": "Editing Dataset", + "EDIT-DESCRIPTION": "Editing Description", "CLONE-DMP": "Clone", "NEW-VERSION": "New Version", "CREATE-DATASET": "Creating Dataset", @@ -1044,7 +1072,7 @@ "TEMPLATES": "Templates", "TEMPLATE": "DMP Template", "DATASET-TEMPLATES": "Related Dataset Templates", - "SELECT-TEMPLATE": "Select a template to describe your dataset", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "DMP Template", "PROJECT": "Project", "GRANT": "Grant", @@ -1065,7 +1093,7 @@ "PUBLICATION": "Publication Date", "CONTACT": "Contact", "COST": "Costs", - "DATASETS": "Datasets" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "Go To DMP Grant", @@ -1094,9 +1122,9 @@ "SUCCESSFUL-DOI": "Successful DOI creation", "UNSUCCESSFUL-FINALIZE": "Unsuccessful DMP finalization" }, - "DATASET-TEMPLATE-LIST": { - "TITLE": "Available Dataset Templates", - "TEXT": "Dataset Profiles selected: ", + "DESCRIPTION-TEMPLATE-LIST": { + "TITLE": "Available Description Templates", + "TEXT": "Descriptions selected: ", "OK": "OK" }, "VISIBILITY": { @@ -1108,7 +1136,7 @@ "MAIN-INFO": "Main info", "FUNDING-INFO": "Funding", "DATASET-SELECTION": "Dataset selection", - "DATASET-INFO": "Dataset info", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "License", "DATASET": "Dataset", "PREVIOUS": "Previous", @@ -1138,7 +1166,7 @@ "INTRO": "A DMP in {{ APP_NAME }} consists of key information about research, such as purpose, objectives and researchers involved, but also about documentation of research datasets that highlight the steps followed and the means used across data management activities.", "SECOND-INTRO": "Datasets are documented following pre-defined templates which set the content of dataset descriptions. In {{ APP_NAME }}, a DMP can contain as many dataset descriptions as the datasets it documents.", "FIND": "Couldn't find a suitable one?", - "HINT": "Select a template to describe your datasets. You may select more than one template." + "HINT": "Select a template to describe your descriptions. You may select more than one template." }, "LICENSE-INFO": { "INTRO": "Each DMP can contain specific license informatation over how much open and available it is, that way you can determine who can see your dataset and for how long that data will be private", @@ -1160,8 +1188,8 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "DMP Templates", - "CREATE-DMP-TEMPLATE": "Create DMP Template", + "TITLE": "DMP Blueprints", + "CREATE-DMP-BLUEPRINT": "Create DMP Blueprint", "COLUMNS": { "NAME": "Name", "STATUS": "Status", @@ -1218,8 +1246,8 @@ "NONE": "-", "TAGS": "Tags", "SELECT-TAGS": "Select Tags", - "LIKE": "Search Datasets", - "DRAFT-LIKE": "Search Draft Datasets", + "LIKE": "Search Descriptions", + "DRAFT-LIKE": "Search Draft Descriptions", "SELECT-GRANTS": "Select Grants", "ROLE": "Role", "ORGANIZATION": "Organization", @@ -1255,12 +1283,12 @@ "TITLE": { "NEW": "New Data Management Plan", "EDIT": "Edit", - "INTRO": "You are using the Dataset editor. Answer here questions that describe your data management activities.", - "INTRO-TIP": "Tip: Add new datasets to describe different types of data or disciplinary data to avoid mixing information." + "INTRO": "You are using the Description editor. Answer here questions that describe your data management activities.", + "INTRO-TIP": "Tip: Add new descriptions to describe different types of data or disciplinary data to avoid mixing information." }, "FIELDS": { "NAME": "Name of the Dataset", - "TITLE": "Title of Dataset", + "TITLE": "Title of Description", "DESCRIPTION": "Description", "PROFILE": "Template", "URI": "Uri", @@ -1298,7 +1326,7 @@ "EXTERNAL-LINK": "Provide an external URL link" }, "HINT": { - "DESCRIPTION": "Briefly describe the context and purpose of the Dataset", + "DESCRIPTION": "Briefly describe the context and purpose of the Description", "TITLE": "A brief description of what the ", "TITLE-REST": " is about it’s scope and objectives." }, @@ -1370,7 +1398,7 @@ "ADMIN": "Admin", "USER": "User", "MANAGER": "Manager", - "DATASET-TEMPLATE-EDITOR": "Dataset Template Editor" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1648,7 +1676,7 @@ "DATA-MANAGEMENT-PLANS": "DATA MANAGEMENT PLANS", "PERSONAL-USAGE": "Personal Usage", "PUBLIC-USAGE": "Public Usage", - "DATASET-DESCRIPTIONS": "Datasets", + "DESCRIPTIONS": "Descriptions", "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Datasets", "PUBLIC-DMPS": "Public DMPs", "PUBLIC-DATASETS": "Public Datasets", @@ -1661,8 +1689,7 @@ "DMP-ABOUT-END": ", that highlight the steps followed and the means used across data management activities.", "SELECT-DMP": "Select a DMP for your Dataset", "ACTIONS": { - "ADD-DATASET-DESCRIPTION": "Add Dataset", - "ADD-DATASET": "Add Dataset", + "ADD-DESCRIPTION": "Add Description", "ADD-DMP-DESCRIPTION": "Add DMP Description" }, "TOUR-GUIDE": { @@ -1693,7 +1720,7 @@ }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", From 128b47d9c355f39a65b3e07b8adb43f985588153 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Tue, 25 Jul 2023 15:27:15 +0300 Subject: [PATCH 030/110] #8845 - #8846: adding description template types, creation of description template type field in the dataset template editor, [wip] creation of admin page for creation/editing/deleting of description template types --- .../entities/DescriptionTemplateTypeDao.java | 10 ++ .../DescriptionTemplateTypeDaoImpl.java | 61 +++++++ .../entities/DescriptionTemplateType.java | 52 ++++++ .../main/java/eu/eudat/controllers/Admin.java | 1 + .../DescriptionTemplateTypeController.java | 64 ++++++++ ...DescriptionTemplatesWithTypeException.java | 9 ++ .../DescriptionTemplateTypeManager.java | 61 +++++++ .../operations/DatabaseRepository.java | 2 + .../operations/DatabaseRepositoryImpl.java | 11 ++ .../data/admin/composite/DatasetProfile.java | 9 ++ dmp-frontend/src/app/app-routing.module.ts | 8 + .../src/app/core/core-service.module.ts | 4 +- .../admin/dataset-profile/dataset-profile.ts | 1 + .../description-template-type.ts | 4 + .../description-template-type.service.ts | 30 ++++ .../editor/dataset-profile-editor-model.ts | 3 + .../dataset-profile-editor.component.html | 19 ++- .../dataset-profile-editor.component.ts | 15 +- .../description-types.module.ts | 19 +++ .../description-types.routing.ts | 17 ++ .../description-type-editor.component.html | 36 +++++ .../description-type-editor.component.scss | 24 +++ .../description-type-editor.component.ts | 85 ++++++++++ .../listing/description-types.component.html | 51 ++++++ .../listing/description-types.component.scss | 71 ++++++++ .../listing/description-types.component.ts | 153 ++++++++++++++++++ .../src/assets/resources/skipDisable.json | 1 + 27 files changed, 816 insertions(+), 5 deletions(-) create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDao.java create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDaoImpl.java create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplateType.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionTemplateTypeController.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/exceptions/descriptiontemplate/DescriptionTemplatesWithTypeException.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/logic/managers/DescriptionTemplateTypeManager.java create mode 100644 dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts create mode 100644 dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts create mode 100644 dmp-frontend/src/app/ui/admin/description-types/description-types.module.ts create mode 100644 dmp-frontend/src/app/ui/admin/description-types/description-types.routing.ts create mode 100644 dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.html create mode 100644 dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.scss create mode 100644 dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts create mode 100644 dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html create mode 100644 dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.scss create mode 100644 dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDao.java new file mode 100644 index 000000000..764bf32e0 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDao.java @@ -0,0 +1,10 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccessLayer; +import eu.eudat.data.entities.DescriptionTemplateType; + +import java.util.UUID; + +public interface DescriptionTemplateTypeDao extends DatabaseAccessLayer { + DescriptionTemplateType findFromName(String name); +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDaoImpl.java new file mode 100644 index 000000000..2f0cac2f2 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDaoImpl.java @@ -0,0 +1,61 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccess; +import eu.eudat.data.dao.databaselayer.service.DatabaseService; +import eu.eudat.data.entities.DescriptionTemplateType; +import eu.eudat.data.entities.EntityDoi; +import eu.eudat.queryable.QueryableList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import javax.transaction.Transactional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Component("descriptionTemplateTypeDao") +public class DescriptionTemplateTypeDaoImpl extends DatabaseAccess implements DescriptionTemplateTypeDao { + + @Autowired + public DescriptionTemplateTypeDaoImpl(DatabaseService databaseService) { + super(databaseService); + } + + @Override + public DescriptionTemplateType findFromName(String name){ + return this.getDatabaseService().getQueryable(DescriptionTemplateType.class).where((builder, root) -> builder.equal(root.get("name"), name)).getSingle(); + } + + @Override + @Transactional + public DescriptionTemplateType createOrUpdate(DescriptionTemplateType item) { + return this.getDatabaseService().createOrUpdate(item, DescriptionTemplateType.class); + } + + @Override + public DescriptionTemplateType find(UUID id) { + return getDatabaseService().getQueryable(DescriptionTemplateType.class).where((builder, root) -> builder.equal((root.get("id")), id)).getSingle(); + } + + @Override + public void delete(DescriptionTemplateType item) { + this.getDatabaseService().delete(item); + } + + @Override + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(DescriptionTemplateType.class); + } + + @Async + @Override + public CompletableFuture createOrUpdateAsync(DescriptionTemplateType item) { + return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); + } + + @Override + public DescriptionTemplateType find(UUID id, String hint) { + throw new UnsupportedOperationException(); + } + +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplateType.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplateType.java new file mode 100644 index 000000000..e4d8d6257 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplateType.java @@ -0,0 +1,52 @@ +package eu.eudat.data.entities; + +import eu.eudat.queryable.queryableentity.DataEntity; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import java.util.List; +import java.util.UUID; + +@Entity +@Table(name = "\"DescriptionTemplateType\"") +public class DescriptionTemplateType implements DataEntity { + + @Id + @GeneratedValue + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID id; + + @Column(name = "\"Name\"", nullable = false) + private String name; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + @Override + public void update(DescriptionTemplateType entity) { + this.name = entity.name; + } + + @Override + public UUID getKeys() { + return this.id; + } + + @Override + public DescriptionTemplateType buildFromTuple(List tuple, List fields, String base) { + this.id = UUID.fromString((String) tuple.get(0).get(!base.isEmpty() ? base + "." + "id" : "id")); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java index f9a5cd03b..b8604c456 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java @@ -61,6 +61,7 @@ public class Admin extends BaseController { //this.getLoggerService().info(principal, "Admin Added Dataset Profile"); DatasetProfile shortenProfile = profile.toShort(); DescriptionTemplate modelDefinition = AdminManager.generateViewStyleDefinition(shortenProfile, getApiContext()); + modelDefinition.setType(getApiContext().getOperationsContext().getDatabaseRepository().getDescriptionTemplateTypeDao().findFromName(profile.getType())); modelDefinition.setGroupId(UUID.randomUUID()); modelDefinition.setVersion((short) 0); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionTemplateTypeController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionTemplateTypeController.java new file mode 100644 index 000000000..f48b98f10 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionTemplateTypeController.java @@ -0,0 +1,64 @@ +package eu.eudat.controllers; + +import eu.eudat.data.entities.DescriptionTemplateType; +import eu.eudat.exceptions.descriptiontemplate.DescriptionTemplatesWithTypeException; +import eu.eudat.logic.managers.DescriptionTemplateTypeManager; +import eu.eudat.logic.security.claims.ClaimedAuthorities; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.models.data.helpers.common.DataTableData; +import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.models.data.security.Principal; +import eu.eudat.types.ApiMessageCode; +import eu.eudat.types.Authorities; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.transaction.Transactional; +import java.util.UUID; + +import static eu.eudat.types.Authorities.ADMIN; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/descriptionTemplateType/"}) +public class DescriptionTemplateTypeController extends BaseController { + + private DescriptionTemplateTypeManager descriptionTemplateTypeManager; + + @Autowired + public DescriptionTemplateTypeController(ApiContext apiContext, DescriptionTemplateTypeManager descriptionTemplateTypeManager){ + super(apiContext); + this.descriptionTemplateTypeManager = descriptionTemplateTypeManager; + } + + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"create"}, produces = "application/json") + public @ResponseBody + ResponseEntity> createOrUpdate(@RequestBody String type, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + this.descriptionTemplateTypeManager.create(type); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created")); + } + + @RequestMapping(method = RequestMethod.GET, value = {"get"}, produces = "application/json") + public @ResponseBody + ResponseEntity>> get(@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { + DataTableData dataTable = this.descriptionTemplateTypeManager.get(); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); + } + + @Transactional + @RequestMapping(method = RequestMethod.DELETE, value = {"/delete/{id}"}, produces = "application/json") + public @ResponseBody + ResponseEntity> delete(@PathVariable(value = "id") UUID id, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + try{ + this.descriptionTemplateTypeManager.delete(id); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Deleted")); + } + catch(DescriptionTemplatesWithTypeException e){ + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.UNSUCCESS_DELETE).message(e.getMessage())); + } + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/exceptions/descriptiontemplate/DescriptionTemplatesWithTypeException.java b/dmp-backend/web/src/main/java/eu/eudat/exceptions/descriptiontemplate/DescriptionTemplatesWithTypeException.java new file mode 100644 index 000000000..2c6484b05 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/exceptions/descriptiontemplate/DescriptionTemplatesWithTypeException.java @@ -0,0 +1,9 @@ +package eu.eudat.exceptions.descriptiontemplate; + +public class DescriptionTemplatesWithTypeException extends RuntimeException { + + public DescriptionTemplatesWithTypeException(String message) { + super(message); + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DescriptionTemplateTypeManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DescriptionTemplateTypeManager.java new file mode 100644 index 000000000..046c7bebd --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DescriptionTemplateTypeManager.java @@ -0,0 +1,61 @@ +package eu.eudat.logic.managers; + +import eu.eudat.data.entities.DescriptionTemplateType; +import eu.eudat.exceptions.descriptiontemplate.DescriptionTemplatesWithTypeException; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.logic.services.operations.DatabaseRepository; +import eu.eudat.models.data.helpers.common.DataTableData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.UUID; + +@Component +public class DescriptionTemplateTypeManager { + private static final Logger logger = LoggerFactory.getLogger(DescriptionTemplateTypeManager.class); + + private ApiContext apiContext; + private DatabaseRepository databaseRepository; + + + @Autowired + public DescriptionTemplateTypeManager(ApiContext apiContext, DatabaseRepository databaseRepository) { + this.apiContext = apiContext; + this.databaseRepository = databaseRepository; + } + + public DataTableData get() { + List types = this.databaseRepository.getDescriptionTemplateTypeDao().asQueryable().toList(); + DataTableData dataTableData = new DataTableData<>(); + dataTableData.setData(types); + dataTableData.setTotalCount((long) types.size()); + return dataTableData; + } + + public DescriptionTemplateType create(String name) { + DescriptionTemplateType type = this.databaseRepository.getDescriptionTemplateTypeDao().findFromName(name); + if (type == null) { + type = new DescriptionTemplateType(); + type.setId(UUID.randomUUID()); + type.setName(name); + this.databaseRepository.getDescriptionTemplateTypeDao().createOrUpdate(type); + } + return type; + } + + public void delete(UUID id) throws DescriptionTemplatesWithTypeException { + DescriptionTemplateType type = this.databaseRepository.getDescriptionTemplateTypeDao().find(id); + if (type != null) { + Long descriptionsWithType = this.databaseRepository.getDatasetProfileDao().countWithType(type.getId()); + if(descriptionsWithType == 0) { + this.databaseRepository.getDescriptionTemplateTypeDao().delete(type); + } + else{ + throw new DescriptionTemplatesWithTypeException("This type can not deleted, because Descriptions are associated with it"); + } + } + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java index 99e088a1c..b10ecaa0e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java @@ -62,5 +62,7 @@ public interface DatabaseRepository { EntityDoiDao getEntityDoiDao(); + DescriptionTemplateTypeDao getDescriptionTemplateTypeDao(); + void detachEntity(T entity); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java index 2e2dd4c63..c72baec18 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java @@ -40,6 +40,7 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { private NotificationDao notificationDao; private FileUploadDao fileUploadDao; private EntityDoiDao entityDoiDao; + private DescriptionTemplateTypeDao descriptionTemplateTypeDao; private EntityManager entityManager; @@ -328,6 +329,16 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { this.entityDoiDao = entityDoiDao; } + @Override + public DescriptionTemplateTypeDao getDescriptionTemplateTypeDao() { + return descriptionTemplateTypeDao; + } + + @Autowired + public void setDescriptionTemplateTypeDao(DescriptionTemplateTypeDao descriptionTemplateTypeDao) { + this.descriptionTemplateTypeDao = descriptionTemplateTypeDao; + } + public void detachEntity(T entity) { this.entityManager.detach(entity); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/composite/DatasetProfile.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/composite/DatasetProfile.java index cbc23c2f4..146a4acc5 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/composite/DatasetProfile.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/composite/DatasetProfile.java @@ -13,6 +13,7 @@ import java.util.List; public class DatasetProfile { private String label; private String description; + private String type; private List pages; private List
    sections; private Short status; @@ -35,6 +36,13 @@ public class DatasetProfile { this.description = description; } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public List getPages() { return pages; } @@ -80,6 +88,7 @@ public class DatasetProfile { DatasetProfile shortProfile = new DatasetProfile(); shortProfile.setLabel(this.label); shortProfile.setDescription(this.description); + shortProfile.setType(this.type); List
    shortSection = new LinkedList<>(); for (Section toshortSection : this.getSections()) { shortSection.add(toshortSection.toShort()); diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts index 0d2ac80a2..e13c1e00b 100644 --- a/dmp-frontend/src/app/app-routing.module.ts +++ b/dmp-frontend/src/app/app-routing.module.ts @@ -99,6 +99,14 @@ const appRoutes: Routes = [ title: 'GENERAL.TITLES.DATASET-PROFILES' } }, + { + path: 'description-types', + loadChildren: () => import('./ui/admin/description-types/description-types.module').then(m => m.DescriptionTypesModule), + data: { + breadcrumb: true, + title: 'GENERAL.TITLES.DESCRIPTION-TYPES' + } + }, { path: 'contact-support', loadChildren: () => import('./ui/contact/contact.module').then(m => m.ContactModule), diff --git a/dmp-frontend/src/app/core/core-service.module.ts b/dmp-frontend/src/app/core/core-service.module.ts index 5186586e6..bbe2356b9 100644 --- a/dmp-frontend/src/app/core/core-service.module.ts +++ b/dmp-frontend/src/app/core/core-service.module.ts @@ -52,6 +52,7 @@ import { FaqService } from './services/faq/faq.service'; import { GlossaryService } from './services/glossary/glossary.service'; import { TermsOfServiceService } from './services/terms-of-service/terms-of-service.service'; import { UnlinkAccountEmailConfirmationService } from './services/unlink-account-email-confirmation/unlink-account-email-confirmation.service'; +import { DescriptionTemplateTypeService } from './services/description-template-type/description-template-type.service'; // // // This is shared module that provides all the services. Its imported only once on the AppModule. @@ -132,7 +133,8 @@ export class CoreServiceModule { multi: true }, LanguageInfoService, - PrefillingService + PrefillingService, + DescriptionTemplateTypeService ], }; } diff --git a/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts b/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts index 8f8ec30d7..68b0d64db 100644 --- a/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts +++ b/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts @@ -3,6 +3,7 @@ import { UserInfoListingModel } from "../../user/user-info-listing"; export interface DatasetProfile { label: string; + type: string; sections: Section[]; pages: Page[]; status: number; diff --git a/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts b/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts new file mode 100644 index 000000000..08f9df8a8 --- /dev/null +++ b/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts @@ -0,0 +1,4 @@ +export interface DescriptionTemplateType { + id: string; + name: string; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts b/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts new file mode 100644 index 000000000..dc6859f30 --- /dev/null +++ b/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts @@ -0,0 +1,30 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { ConfigurationService } from '../configuration/configuration.service'; +import { BaseHttpService } from '../http/base-http.service'; +import { Observable } from 'rxjs'; +import { DataTableData } from '@app/core/model/data-table/data-table-data'; +import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; + +@Injectable() +export class DescriptionTemplateTypeService { + + private actionUrl: string; + private headers = new HttpHeaders(); + + constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) { + this.actionUrl = configurationService.server + 'descriptionTemplateType/'; + } + + getTypes(): Observable> { + return this.http.get>(this.actionUrl + 'get', { headers: this.headers }); + } + + createType(name: string): Observable { + return this.http.post(this.actionUrl + 'create', name, { headers: this.headers }); + } + + deleteType(id: string): Observable { + return this.http.delete(this.actionUrl + 'delete/' + id, { headers: this.headers }); + } +} diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor-model.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor-model.ts index d3cf2775e..059a1feb0 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor-model.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor-model.ts @@ -15,6 +15,7 @@ export class DatasetProfileEditorModel extends BaseFormModel { public status: number; public version: number; private description: string; + private type: string; private language: string; private users: UserInfoListingModel[] = []; @@ -22,6 +23,7 @@ export class DatasetProfileEditorModel extends BaseFormModel { if (item.sections) { this.sections = item.sections.map(x => new SectionEditorModel().fromModel(x)); } if (item.pages) { this.pages = item.pages.map(x => new PageEditorModel().fromModel(x)); } this.label = item.label; + this.type = item.type; this.status = item.status; this.version = item.version; this.description = item.description; @@ -34,6 +36,7 @@ export class DatasetProfileEditorModel extends BaseFormModel { const formGroup: FormGroup = new FormBuilder().group({ label: [{ value: this.label, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.label')) }, [Validators.required]], description: [{ value: this.description, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.description')) }, [Validators.required]], + type: [{ value: this.type, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.type')) }, [Validators.required]], language: [{ value: this.language, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.language')) }, [Validators.required]], status: [{ value: this.status, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.status')) }], version: [{ value: this.version, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.version')) }], diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html index c0288f59d..31bfbd1ea 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html @@ -142,8 +142,21 @@
    - -
    1.3 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-LANGUAGE'| translate}} *
    +
    1.3 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-TYPE'| translate}} *
    + + + + {{ type.name }} + + + {{'GENERAL.VALIDATION.REQUIRED' | + translate}} + + +
    +
    + +
    1.4 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-LANGUAGE'| translate}} *
    @@ -157,7 +170,7 @@
    -
    1.4 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}
    +
    1.5 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}
    {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS-HINT'| translate}}
    diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts index be47cb207..7892340cc 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts @@ -45,6 +45,8 @@ import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profil import { UserService } from '@app/core/services/user/user.service'; import { MatInput } from '@angular/material/input'; import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate.component'; +import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; +import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; const skipDisable: any[] = require('../../../../../assets/resources/skipDisable.json'); @@ -80,6 +82,7 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent tocEntryEnumValues = ToCEntryType; public userChipList:any[] = []; displayedColumns: String[] = ['name', 'email', 'button']; + descriptionTemplateTypes: DescriptionTemplateType[] = []; colorizeInvalid:boolean = false; inputUserState: 'untriggered'| 'triggered' = 'untriggered'; @@ -112,7 +115,8 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent private visibilityRulesService: VisibilityRulesService, private fb: FormBuilder, private sidenavService: SideNavService, - private userService: UserService + private userService: UserService, + private descriptionTemplateTypeService: DescriptionTemplateTypeService ) { super(); // this.profileID = route.snapshot.params['id']; @@ -227,6 +231,7 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent } }); + this.getDescriptionTemplateTypes(); combineLatest(this._inputUserButton$.asObservable(),this._inputUserField$.asObservable()) .pipe(takeUntil(this._destroyed)) @@ -600,6 +605,14 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent return filename; } + getDescriptionTemplateTypes(): DescriptionTemplateType[] { + this.descriptionTemplateTypeService.getTypes().pipe(takeUntil(this._destroyed)) + .subscribe(types => { + this.descriptionTemplateTypes = types.data; + }); + return this.descriptionTemplateTypes; + } + getLanguageInfos(): LanguageInfo[] { return this.languageInfoService.getLanguageInfoValues(); } diff --git a/dmp-frontend/src/app/ui/admin/description-types/description-types.module.ts b/dmp-frontend/src/app/ui/admin/description-types/description-types.module.ts new file mode 100644 index 000000000..1a91c9cee --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/description-types.module.ts @@ -0,0 +1,19 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { DescriptionTypesRoutingModule } from './description-types.routing'; +import { DescriptionTypesComponent } from './listing/description-types.component'; +import { CommonUiModule } from '@common/ui/common-ui.module'; +import { DescriptionTypeEditorComponent } from './editor/description-type-editor.component'; + +@NgModule({ + declarations: [ + DescriptionTypesComponent, + DescriptionTypeEditorComponent + ], + imports: [ + CommonModule, + CommonUiModule, + DescriptionTypesRoutingModule + ] +}) +export class DescriptionTypesModule { } diff --git a/dmp-frontend/src/app/ui/admin/description-types/description-types.routing.ts b/dmp-frontend/src/app/ui/admin/description-types/description-types.routing.ts new file mode 100644 index 000000000..fea0e116d --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/description-types.routing.ts @@ -0,0 +1,17 @@ +import { NgModule } from "@angular/core"; +import { RouterModule, Routes } from "@angular/router"; +import { AdminAuthGuard } from "@app/core/admin-auth-guard.service"; +import { DescriptionTypeEditorComponent } from './editor/description-type-editor.component'; +import { DescriptionTypesComponent } from "./listing/description-types.component"; + +const routes: Routes = [ + { path: '', component: DescriptionTypesComponent, canActivate: [AdminAuthGuard] }, + { path: 'new', component: DescriptionTypeEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DESCRIPTION-TYPE-NEW' } }, + { path: ':id', component: DescriptionTypeEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DESCRIPTION-TYPE-EDIT' } } +] + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class DescriptionTypesRoutingModule { } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.html b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.html new file mode 100644 index 000000000..d55b295fc --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.html @@ -0,0 +1,36 @@ +
    +
    +
    +
    +

    {{'DESCRIPTION-TYPE-EDITOR.NEW' | translate}}

    +
    +
    +
    + + +
    + + + + {{formGroup.get('name').getError('backendError').message}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    +
    diff --git a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.scss b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.scss new file mode 100644 index 000000000..93d519a62 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.scss @@ -0,0 +1,24 @@ +.description-type-editor { + margin-top: 1.3rem; + margin-left: 1em; + margin-right: 3em; +} + +.action-btn { + border-radius: 30px; + background-color: var(--secondary-color); + border: 1px solid transparent; + padding-left: 2em; + padding-right: 2em; + box-shadow: 0px 3px 6px #1E202029; + + transition-property: background-color, color; + transition-duration: 200ms; + transition-delay: 50ms; + transition-timing-function: ease-in-out; + &:disabled{ + background-color: #CBCBCB; + color: #FFF; + border: 0px; + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts new file mode 100644 index 000000000..118a226df --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts @@ -0,0 +1,85 @@ +import { AfterViewInit, Component } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; +import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { BaseComponent } from '@common/base/base.component'; +import { FormService } from '@common/forms/form-service'; +import { TranslateService } from '@ngx-translate/core'; +import { takeUntil } from 'rxjs/operators'; + +@Component({ + selector: 'app-description-type-editor', + templateUrl: './description-type-editor.component.html', + styleUrls: ['./description-type-editor.component.scss'] +}) +export class DescriptionTypeEditorComponent extends BaseComponent implements AfterViewInit { + + formGroup: FormGroup = null; + descriptionTypeModel: DescriptionTypeEditorModel + + constructor( + private descriptionTemplateTypeService: DescriptionTemplateTypeService, + private formService: FormService, + private uiNotificationService: UiNotificationService, + private language: TranslateService, + private router: Router + ) { + super(); + } + + ngAfterViewInit(): void { + this.descriptionTypeModel = new DescriptionTypeEditorModel(); + setTimeout(() => { + this.formGroup = this.descriptionTypeModel.buildForm(); + }); + } + + formSubmit(): void { + this.formService.touchAllFormFields(this.formGroup); + if (!this.isFormValid()) { return; } + this.onSubmit(); + } + + public isFormValid() { + return this.formGroup.valid; + } + + onSubmit(): void { + console.log(this.formGroup.value); + this.descriptionTemplateTypeService.createType(this.formGroup.value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(), + error => this.onCallbackError(error) + ); + } + + onCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION'), SnackBarNotificationLevel.Success); + this.router.navigate(['/description-types']); + } + + onCallbackError(errorResponse: any) { + // this.setErrorModel(errorResponse.error); + // this.formService.validateAllFormFields(this.formGroup); + } + + public cancel(): void { + this.router.navigate(['/description-types']); + } + +} + +export class DescriptionTypeEditorModel { + public id: string; + public name: string; + + buildForm(): FormGroup { + const formGroup = new FormBuilder().group({ + id: [this.id], + name: [this.name, Validators.required], + }); + return formGroup; + } +} diff --git a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html new file mode 100644 index 000000000..bebfd44bc --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html @@ -0,0 +1,51 @@ +
    +
    +
    +
    +

    {{'DESCRIPTION-TYPES-LISTING.TITLE' | translate}}

    +
    +
    +
    + +
    +
    + + +
    + + + + + + {{'DESCRIPTION-TYPES-LISTING.COLUMNS.NAME' | translate}} + {{row.name}} + + + + {{'DESCRIPTION-TYPES-LISTING.COLUMNS.STATUS' | + translate}} +
    {{ 'DATASET-PROFILE-STATUS.FINALIZED' | translate}}
    +
    + + + + + + + + + + + +
    + + +
    +
    +
    \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.scss b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.scss new file mode 100644 index 000000000..245b6aa81 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.scss @@ -0,0 +1,71 @@ +.mat-table { + margin-top: 47px; + border-radius: 4px; +} +.description-types-listing { + margin-top: 1.3rem; + margin-left: 1rem; + margin-right: 2rem; + + .mat-header-row{ + background: #f3f5f8; + } + .mat-card { + margin: 16px 0; + padding: 0px; + } + + .mat-row { + cursor: pointer; + min-height: 4.5em; + } + + mat-row:hover { + background-color: #eef5f6; + } + .mat-fab-bottom-right { + float: right; + z-index: 5; + } +} +// PAGINATOR +:host ::ng-deep .mat-paginator-container { + flex-direction: row-reverse !important; + justify-content: space-between !important; + background-color: #f6f6f6; + align-items: center; +} +.create-btn { + border-radius: 30px; + background-color: var(--secondary-color); + padding-left: 2em; + padding-right: 2em; + // color: #000; + + .button-text{ + display: inline-block; + } +} + +.dlt-btn { + color: rgba(0, 0, 0, 0.54); +} + +.status-chip{ + + border-radius: 20px; + padding-left: 1em; + padding-right: 1em; + padding-top: 0.2em; + font-size: .8em; +} + +.status-chip-finalized{ + color: #568b5a; + background: #9dd1a1 0% 0% no-repeat padding-box; +} + +.status-chip-draft{ + color: #00c4ff; + background: #d3f5ff 0% 0% no-repeat padding-box; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts new file mode 100644 index 000000000..d86fbbac9 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts @@ -0,0 +1,153 @@ +import { DataSource } from '@angular/cdk/table'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { BaseComponent } from '@common/base/base.component'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { TranslateService } from '@ngx-translate/core'; +import { merge as observableMerge, Observable, of } from 'rxjs'; +import { map, startWith, switchMap, takeUntil } from 'rxjs/operators'; + +@Component({ + selector: 'app-description-types', + templateUrl: './description-types.component.html', + styleUrls: ['./description-types.component.scss'] +}) +export class DescriptionTypesComponent extends BaseComponent implements OnInit { + + @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; + @ViewChild(MatSort, { static: true }) sort: MatSort; + + dataSource: DescriptionTypesDataSource | null; + displayedColumns: String[] = ['label', 'status', 'delete']; + + constructor( + private descriptionTemplateTypeService: DescriptionTemplateTypeService, + private dialog: MatDialog, + private language: TranslateService, + private uiNotificationService: UiNotificationService + ) { + super(); + } + + ngOnInit(): void { + this.refresh(); + } + + refresh() { + this.dataSource = new DescriptionTypesDataSource(this.descriptionTemplateTypeService, this._paginator, this.sort/*, this.criteria*/); + } + + deleteTemplate(id: string){ + if(id){ + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + isDeleteConfirmation: true + } + }); + + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + // this.descriptionTemplateTypeService.deleteType(id) + // .pipe(takeUntil(this._destroyed)) + // .subscribe( + // complete => { + // this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Success); + // this.refresh(); + // }, + // error => { + // this.onCallbackError(error); + // if (error.error.statusCode == 674) { + // this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Error); + // } else { + // this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); + // } + // } + // ); + + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DESCRIPTION-TEMPLATE-TYPE-DELETE'), SnackBarNotificationLevel.Error); + this.refresh(); + } + }); + + } + } + + onCallbackError(errorResponse: HttpErrorResponse) { + this.uiNotificationService.snackBarNotification(errorResponse.message, SnackBarNotificationLevel.Warning); + } + + getStatusClass(status: number): string { + + if(status == 1){ + return 'status-chip-finalized' + } + + return 'status-chip-draft'; + } + +} + +export interface DescriptionTemplateTypeListingModel { + id: string; + name: string; + status: number; +} + +export class DescriptionTypesDataSource extends DataSource { + + totalCount = 0; + + constructor( + private _service: DescriptionTemplateTypeService, + private _paginator: MatPaginator, + private _sort: MatSort//, + //private _criteria: DmpProfileCriteriaComponent + ) { + super(); + + } + + connect(): Observable { + const displayDataChanges = [ + this._paginator.page + //this._sort.matSortChange + ]; + + // return observableMerge(...displayDataChanges).pipe( + // startWith(null), + // switchMap(() => { + // // const startIndex = this._paginator.pageIndex * this._paginator.pageSize; + // // let fields: Array = new Array(); + // // if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; } + // // const request = new DataTableRequest(startIndex, this._paginator.pageSize, { fields: fields }); + // // request.criteria = this._criteria.criteria; + // // return this._service.getPaged(request); + + // return this._service.getTypes(); + // }), + // map(result => { + // return result; + // }), + // map(result => { + // // if (!result) { return []; } + // // if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } + // // return result.data; + // return result; + // })); + + return of([{id: '1234', name: 'Dataset', status: 0}]); + } + + disconnect() { + // No-op + } +} diff --git a/dmp-frontend/src/assets/resources/skipDisable.json b/dmp-frontend/src/assets/resources/skipDisable.json index b0d92f82e..c791c76b3 100644 --- a/dmp-frontend/src/assets/resources/skipDisable.json +++ b/dmp-frontend/src/assets/resources/skipDisable.json @@ -1,5 +1,6 @@ [ "DatasetProfileEditorModel.description", + "DatasetProfileEditorModel.type", "DatasetProfileEditorModel.label", "SectionEditorModel.title", "SectionEditorModel.description", From 09d6528f8f1fde3fa5a6e08fd3c338d79756f5d9 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Tue, 25 Jul 2023 15:51:29 +0300 Subject: [PATCH 031/110] #8855 - #8856 - #8901 - #8902 [wip] implementing dmp blueprints --- .../DataManagementPlanBlueprintCriteria.java | 6 + .../data/dao/entities/DMPProfileDao.java | 3 + .../data/dao/entities/DMPProfileDaoImpl.java | 10 + ...taManagementPlanBlueprintTableRequest.java | 25 + .../controllers/DMPProfileController.java | 24 + .../DataManagementProfileManager.java | 28 + .../DataManagementPlanBlueprint.java | 50 ++ .../DescriptionTemplate.java | 72 ++ .../dmpprofiledefinition/ExtraField.java | 93 +++ .../dmpprofiledefinition/Section.java | 140 ++++ .../dmpprofiledefinition/SystemField.java | 94 +++ .../types/ExtraFieldType.java | 30 + .../types/SystemFieldType.java | 58 ++ ...taManagementPlanBlueprintListingModel.java | 93 +++ .../dmp-blueprint/dmp-blueprint-listing.ts | 10 + .../model/dmp/dmp-blueprint/dmp-blueprint.ts | 72 ++ .../core/query/dmp/dmp-blueprint-criteria.ts | 5 + .../core/services/dmp/dmp-profile.service.ts | 15 + .../admin/dmp-profile/dmp-profile.routing.ts | 4 +- .../editor/dmp-blueprint-editor.model.ts | 192 +++++ .../editor/dmp-profile-editor.component.html | 226 ++++- .../editor/dmp-profile-editor.component.scss | 58 ++ .../editor/dmp-profile-editor.component.ts | 327 +++++++- .../dmp-profile-listing.component.html | 2 +- .../listing/dmp-profile-listing.component.ts | 2 +- .../dmp-editor-blueprint.component.html | 271 ++++++ .../dmp-editor-blueprint.component.scss | 378 +++++++++ .../dmp-editor-blueprint.component.ts | 777 ++++++++++++++++++ dmp-frontend/src/app/ui/dmp/dmp.module.ts | 4 +- dmp-frontend/src/app/ui/dmp/dmp.routing.ts | 13 +- .../funding-info/funding-info.component.html | 63 +- .../funding-info/funding-info.component.ts | 4 +- .../misc/navigation/navigation.component.html | 2 +- .../src/app/ui/navbar/navbar.component.html | 2 +- 34 files changed, 3102 insertions(+), 51 deletions(-) create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanBlueprintCriteria.java create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/query/items/dmpblueprint/DataManagementPlanBlueprintTableRequest.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DataManagementPlanBlueprint.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DescriptionTemplate.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/ExtraField.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/Section.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/SystemField.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/ExtraFieldType.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/SystemFieldType.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanBlueprintListingModel.java create mode 100644 dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing.ts create mode 100644 dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint.ts create mode 100644 dmp-frontend/src/app/core/query/dmp/dmp-blueprint-criteria.ts create mode 100644 dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model.ts create mode 100644 dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html create mode 100644 dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss create mode 100644 dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanBlueprintCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanBlueprintCriteria.java new file mode 100644 index 000000000..c7f21914c --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanBlueprintCriteria.java @@ -0,0 +1,6 @@ +package eu.eudat.data.dao.criteria; + +import eu.eudat.data.entities.DMPProfile; + +public class DataManagementPlanBlueprintCriteria extends Criteria { +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDao.java index 52eae6a2a..36fc58752 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDao.java @@ -1,6 +1,7 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccessLayer; +import eu.eudat.data.dao.criteria.DataManagementPlanBlueprintCriteria; import eu.eudat.data.dao.criteria.DataManagementPlanProfileCriteria; import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.DMPProfile; @@ -15,4 +16,6 @@ public interface DMPProfileDao extends DatabaseAccessLayer { QueryableList getWithCriteria(DataManagementPlanProfileCriteria criteria); + QueryableList getWithCriteriaBlueprint(DataManagementPlanBlueprintCriteria criteria); + } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDaoImpl.java index b5198d86d..671fc8b67 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDaoImpl.java @@ -1,6 +1,7 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccess; +import eu.eudat.data.dao.criteria.DataManagementPlanBlueprintCriteria; import eu.eudat.data.dao.criteria.DataManagementPlanProfileCriteria; import eu.eudat.data.dao.databaselayer.service.DatabaseService; import eu.eudat.data.entities.DMPProfile; @@ -65,4 +66,13 @@ public class DMPProfileDaoImpl extends DatabaseAccess implements DMP query.where(((builder, root) -> builder.notEqual(root.get("status"), DMPProfile.Status.DELETED.getValue()))); return query; } + + @Override + public QueryableList getWithCriteriaBlueprint(DataManagementPlanBlueprintCriteria criteria){ + QueryableList query = getDatabaseService().getQueryable(DMPProfile.class); + if (criteria.getLike() != null && !criteria.getLike().isEmpty()) + query.where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + criteria.getLike().toUpperCase() + "%")); + query.where(((builder, root) -> builder.notEqual(root.get("status"), DMPProfile.Status.DELETED.getValue()))); + return query; + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/dmpblueprint/DataManagementPlanBlueprintTableRequest.java b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/dmpblueprint/DataManagementPlanBlueprintTableRequest.java new file mode 100644 index 000000000..b1b83e5d6 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/dmpblueprint/DataManagementPlanBlueprintTableRequest.java @@ -0,0 +1,25 @@ +package eu.eudat.data.query.items.dmpblueprint; + +import eu.eudat.data.dao.criteria.DataManagementPlanBlueprintCriteria; +import eu.eudat.data.entities.DMPProfile; +import eu.eudat.data.query.PaginationService; +import eu.eudat.data.query.definition.TableQuery; +import eu.eudat.queryable.QueryableList; + +import java.util.UUID; + +public class DataManagementPlanBlueprintTableRequest extends TableQuery { + + @Override + public QueryableList applyCriteria() { + QueryableList query = this.getQuery(); + if (this.getCriteria().getLike() != null && !this.getCriteria().getLike().isEmpty()) + query.where((builder, root) -> builder.like(root.get("label"), "%" + this.getCriteria().getLike() + "%")); + return query; + } + + @Override + public QueryableList applyPaging(QueryableList items) { + return PaginationService.applyPaging(items, this); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java index a47a59ce7..b307538d7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java @@ -3,6 +3,7 @@ package eu.eudat.controllers; import eu.eudat.data.dao.criteria.RequestItem; import eu.eudat.data.entities.DMPProfile; import eu.eudat.data.entities.DescriptionTemplate; +import eu.eudat.data.query.items.dmpblueprint.DataManagementPlanBlueprintTableRequest; import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest; import eu.eudat.logic.managers.DataManagementProfileManager; import eu.eudat.logic.security.claims.ClaimedAuthorities; @@ -11,6 +12,7 @@ import eu.eudat.models.data.helpermodels.Tuple; import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel; import eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel; import eu.eudat.models.data.security.Principal; import eu.eudat.types.ApiMessageCode; @@ -52,6 +54,14 @@ public class DMPProfileController extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created")); } + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"/blueprint"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity> createOrUpdateBlueprint(@RequestBody DataManagementPlanBlueprintListingModel dataManagementPlan, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + this.dataManagementProfileManager.createOrUpdateBlueprint(dataManagementPlan, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created")); + } + @RequestMapping(method = RequestMethod.GET, value = {"/getSingle/{id}"}, produces = "application/json") public @ResponseBody ResponseEntity> getSingle(@PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException { @@ -59,6 +69,13 @@ public class DMPProfileController extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlanProfileListingModel)); } + @RequestMapping(method = RequestMethod.GET, value = {"/getSingleBlueprint/{id}"}, produces = "application/json") + public @ResponseBody + ResponseEntity> getSingleBlueprint(@PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException { + DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel = this.dataManagementProfileManager.getSingleBlueprint(id, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlanBlueprintListingModel)); + } + @RequestMapping(method = RequestMethod.POST, value = {"/getPaged"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity>> getPaged(@Valid @RequestBody DataManagementPlanProfileTableRequest dataManagementPlanProfileTableRequest, Principal principal) throws Exception { @@ -66,6 +83,13 @@ public class DMPProfileController extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); } + @RequestMapping(method = RequestMethod.POST, value = {"/getPagedBlueprint"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity>> getPagedBlueprint(@Valid @RequestBody DataManagementPlanBlueprintTableRequest dataManagementPlanBlueprintTableRequest, Principal principal) throws Exception { + DataTableData dataTable = this.dataManagementProfileManager.getPagedBlueprint(dataManagementPlanBlueprintTableRequest, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); + } + @RequestMapping(method = RequestMethod.GET, value = {"/getXml/{id}"}, produces = "application/json") public @ResponseBody ResponseEntity getXml( @RequestHeader("Content-Type") String contentType, @PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException, IOException { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java index 031bab7e7..667dbbd2e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java @@ -5,6 +5,7 @@ import com.jayway.jsonpath.JsonPath; import eu.eudat.data.dao.criteria.RequestItem; import eu.eudat.data.dao.entities.DMPProfileDao; import eu.eudat.data.entities.DMPProfile; +import eu.eudat.data.query.items.dmpblueprint.DataManagementPlanBlueprintTableRequest; import eu.eudat.data.query.items.item.dmpprofile.DataManagementPlanProfileCriteriaRequest; import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest; import eu.eudat.logic.services.operations.DatabaseRepository; @@ -17,6 +18,7 @@ import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Field; import eu.eudat.models.data.helpermodels.Tuple; import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem; import eu.eudat.models.data.helpers.common.DataTableData; +import eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel; import eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel; import eu.eudat.models.data.security.Principal; import eu.eudat.queryable.QueryableList; @@ -78,6 +80,20 @@ public class DataManagementProfileManager { return dataTable; } + public DataTableData getPagedBlueprint(DataManagementPlanBlueprintTableRequest dataManagementPlanBlueprintTableRequest, Principal principal) throws Exception { + + QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().getWithCriteriaBlueprint(dataManagementPlanBlueprintTableRequest.getCriteria()); + QueryableList pagedItems = PaginationManager.applyPaging(items, dataManagementPlanBlueprintTableRequest); + + DataTableData dataTable = new DataTableData<>(); + + CompletableFuture itemsFuture = pagedItems + .selectAsync(item -> new DataManagementPlanBlueprintListingModel().fromDataModel(item)).whenComplete((resultList, throwable) -> dataTable.setData(resultList)); + CompletableFuture countFuture = items.countAsync().whenComplete((count, throwable) -> dataTable.setTotalCount(count)); + CompletableFuture.allOf(itemsFuture, countFuture).join(); + return dataTable; + } + public DataManagementPlanProfileListingModel getSingle(String id, Principal principal) throws InstantiationException, IllegalAccessException { DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id)); DataManagementPlanProfileListingModel dataManagementPlanProfileListingModel = new DataManagementPlanProfileListingModel(); @@ -85,6 +101,13 @@ public class DataManagementProfileManager { return dataManagementPlanProfileListingModel; } + public DataManagementPlanBlueprintListingModel getSingleBlueprint(String id, Principal principal) throws InstantiationException, IllegalAccessException { + DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id)); + DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel = new DataManagementPlanBlueprintListingModel(); + dataManagementPlanBlueprintListingModel.fromDataModel(dmpProfile); + return dataManagementPlanBlueprintListingModel; + } + public List getWithCriteria(DataManagementPlanProfileCriteriaRequest dataManagementPlanProfileCriteriaRequest) throws IllegalAccessException, InstantiationException { QueryableList items = databaseRepository.getDmpProfileDao().getWithCriteria(dataManagementPlanProfileCriteriaRequest.getCriteria()); List datamanagementPlans = items.select(item -> new DataManagementPlanProfileListingModel().fromDataModel(item)); @@ -96,6 +119,11 @@ public class DataManagementProfileManager { apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile); } + public void createOrUpdateBlueprint(DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel, Principal principal) throws Exception { + DMPProfile dmpProfile = dataManagementPlanBlueprintListingModel.toDataModel(); + apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile); + } + public ResponseEntity getDocument(DataManagementPlanProfileListingModel dmpProfile, String label) throws IllegalAccessException, IOException, InstantiationException { FileEnvelope envelope = getXmlDocument(dmpProfile, label); InputStream resource = new FileInputStream(envelope.getFile()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DataManagementPlanBlueprint.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DataManagementPlanBlueprint.java new file mode 100644 index 000000000..9b1d57fbd --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DataManagementPlanBlueprint.java @@ -0,0 +1,50 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.logic.utilities.builders.XmlBuilder; +import eu.eudat.logic.utilities.interfaces.XmlSerializable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.LinkedList; +import java.util.List; + +public class DataManagementPlanBlueprint implements XmlSerializable { + + private List
    sections; + + public List
    getSections() { + return sections; + } + public void setSections(List
    sections) { + this.sections = sections; + } + + @Override + public Element toXml(Document doc) { + Element root = doc.createElement("root"); + Element sections = doc.createElement("sections"); + for (Section section : this.sections) { + sections.appendChild(section.toXml(doc)); + } + root.appendChild(sections); + return root; + } + + @Override + public DataManagementPlanBlueprint fromXml(Element item) { + this.sections = new LinkedList<>(); + Element sections = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "sections"); + if (sections != null) { + NodeList sectionElements = sections.getChildNodes(); + for (int temp = 0; temp < sectionElements.getLength(); temp++) { + Node sectionElement = sectionElements.item(temp); + if (sectionElement.getNodeType() == Node.ELEMENT_NODE) { + this.sections.add(new Section().fromXml((Element) sectionElement)); + } + } + } + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DescriptionTemplate.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DescriptionTemplate.java new file mode 100644 index 000000000..bec34133b --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DescriptionTemplate.java @@ -0,0 +1,72 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.logic.utilities.interfaces.XmlSerializable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.util.UUID; + +public class DescriptionTemplate implements XmlSerializable { + + private UUID id; + private UUID descriptionTemplateId; + private String label; + private Integer minMultiplicity; + private Integer maxMultiplicity; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public UUID getDescriptionTemplateId() { + return descriptionTemplateId; + } + public void setDescriptionTemplateId(UUID descriptionTemplateId) { + this.descriptionTemplateId = descriptionTemplateId; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public Integer getMinMultiplicity() { + return minMultiplicity; + } + public void setMinMultiplicity(Integer minMultiplicity) { + this.minMultiplicity = minMultiplicity; + } + + public Integer getMaxMultiplicity() { + return maxMultiplicity; + } + public void setMaxMultiplicity(Integer maxMultiplicity) { + this.maxMultiplicity = maxMultiplicity; + } + + @Override + public Element toXml(Document doc) { + Element rootElement = doc.createElement("descriptionTemplate"); + rootElement.setAttribute("id", this.getId().toString()); + rootElement.setAttribute("descriptionTemplateId", this.getDescriptionTemplateId().toString()); + rootElement.setAttribute("label", this.label); + rootElement.setAttribute("minMultiplicity", String.valueOf(this.minMultiplicity)); + rootElement.setAttribute("maxMultiplicity", String.valueOf(this.maxMultiplicity)); + return rootElement; + } + + @Override + public DescriptionTemplate fromXml(Element item) { + this.id = UUID.fromString(item.getAttribute("id")); + this.descriptionTemplateId = UUID.fromString(item.getAttribute("descriptionTemplateId")); + this.label = item.getAttribute("label"); + this.minMultiplicity = Integer.valueOf(item.getAttribute("minMultiplicity")); + this.maxMultiplicity = Integer.valueOf(item.getAttribute("maxMultiplicity")); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/ExtraField.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/ExtraField.java new file mode 100644 index 000000000..f3ab20c59 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/ExtraField.java @@ -0,0 +1,93 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.logic.utilities.interfaces.XmlSerializable; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.ExtraFieldType; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.util.UUID; + +public class ExtraField implements XmlSerializable { + + private UUID id; + private String label; + private String description; + private String placeholder; + private ExtraFieldType type; + private Boolean required; + private Integer ordinal; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public String getPlaceholder() { + return placeholder; + } + public void setPlaceholder(String placeholder) { + this.placeholder = placeholder; + } + + public ExtraFieldType getType() { + return type; + } + public void setType(ExtraFieldType type) { + this.type = type; + } + + public Boolean getRequired() { + return required; + } + public void setRequired(Boolean required) { + this.required = required; + } + + public Integer getOrdinal() { + return ordinal; + } + public void setOrdinal(Integer ordinal) { + this.ordinal = ordinal; + } + + @Override + public Element toXml(Document doc) { + Element rootElement = doc.createElement("extraField"); + rootElement.setAttribute("id", this.getId().toString()); + rootElement.setAttribute("label", this.label); + rootElement.setAttribute("description", this.description); + rootElement.setAttribute("placeholder", this.placeholder); + rootElement.setAttribute("type", String.valueOf(this.type.getValue())); + rootElement.setAttribute("required", String.valueOf(this.required)); + rootElement.setAttribute("ordinal", String.valueOf(this.ordinal)); + return rootElement; + } + + @Override + public ExtraField fromXml(Element item) { + this.id = UUID.fromString(item.getAttribute("id")); + this.label = item.getAttribute("label"); + this.description = item.getAttribute("description"); + this.placeholder = item.getAttribute("placeholder"); + this.type = ExtraFieldType.fromInteger(Integer.parseInt(item.getAttribute("type"))); + this.required = Boolean.parseBoolean(item.getAttribute("required")); + this.ordinal = Integer.valueOf(item.getAttribute("ordinal")); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/Section.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/Section.java new file mode 100644 index 000000000..2ed95c937 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/Section.java @@ -0,0 +1,140 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.logic.utilities.builders.XmlBuilder; +import eu.eudat.logic.utilities.interfaces.XmlSerializable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +public class Section implements XmlSerializable
    { + + private UUID id; + private String label; + private String description; + private Integer ordinal; + private List systemFields; + private List descriptionTemplates; + private List extraFields; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public Integer getOrdinal() { + return ordinal; + } + public void setOrdinal(Integer ordinal) { + this.ordinal = ordinal; + } + + public List getSystemFields() { + return systemFields; + } + public void setSystemFields(List systemFields) { + this.systemFields = systemFields; + } + + public List getDescriptionTemplates() { + return descriptionTemplates; + } + public void setDescriptionTemplates(List descriptionTemplates) { + this.descriptionTemplates = descriptionTemplates; + } + + public List getExtraFields() { + return extraFields; + } + public void setExtraFields(List extraFields) { + this.extraFields = extraFields; + } + + @Override + public Element toXml(Document doc) { + Element rootElement = doc.createElement("section"); + rootElement.setAttribute("id", this.getId().toString()); + rootElement.setAttribute("label", this.label); + rootElement.setAttribute("description", this.description); + rootElement.setAttribute("ordinal", String.valueOf(this.ordinal)); + Element systemFields = doc.createElement("systemFields"); + for (SystemField systemField : this.systemFields) { + systemFields.appendChild(systemField.toXml(doc)); + } + rootElement.appendChild(systemFields); + Element descriptionTemplates = doc.createElement("descriptionTemplates"); + for (DescriptionTemplate descriptionTemplate : this.descriptionTemplates) { + descriptionTemplates.appendChild(descriptionTemplate.toXml(doc)); + } + rootElement.appendChild(descriptionTemplates); + Element extraFields = doc.createElement("extraFields"); + for (ExtraField extraField : this.extraFields) { + extraFields.appendChild(extraField.toXml(doc)); + } + rootElement.appendChild(extraFields); + + return rootElement; + } + + @Override + public Section fromXml(Element item) { + this.id = UUID.fromString(item.getAttribute("id")); + this.label = item.getAttribute("label"); + this.description = item.getAttribute("description"); + this.ordinal = Integer.valueOf(item.getAttribute("ordinal")); + this.systemFields = new LinkedList<>(); + Element systemFields = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "systemFields"); + if (systemFields != null) { + NodeList systemFieldElements = systemFields.getChildNodes(); + for (int temp = 0; temp < systemFieldElements.getLength(); temp++) { + Node systemFieldElement = systemFieldElements.item(temp); + if (systemFieldElement.getNodeType() == Node.ELEMENT_NODE) { + this.systemFields.add(new SystemField().fromXml((Element) systemFieldElement)); + } + } + } + this.descriptionTemplates = new LinkedList<>(); + Element descriptionTemplates = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "descriptionTemplates"); + if (descriptionTemplates != null) { + NodeList descriptionTemplateElements = descriptionTemplates.getChildNodes(); + for (int temp = 0; temp < descriptionTemplateElements.getLength(); temp++) { + Node descriptionTemplateElement = descriptionTemplateElements.item(temp); + if (descriptionTemplateElement.getNodeType() == Node.ELEMENT_NODE) { + this.descriptionTemplates.add(new DescriptionTemplate().fromXml((Element) descriptionTemplateElement)); + } + } + } + this.extraFields = new LinkedList<>(); + Element extraFields = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "extraFields"); + if (extraFields != null) { + NodeList extraFieldElements = extraFields.getChildNodes(); + for (int temp = 0; temp < extraFieldElements.getLength(); temp++) { + Node extraFieldElement = extraFieldElements.item(temp); + if (extraFieldElement.getNodeType() == Node.ELEMENT_NODE) { + this.extraFields.add(new ExtraField().fromXml((Element) extraFieldElement)); + } + } + } + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/SystemField.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/SystemField.java new file mode 100644 index 000000000..419a9ccd9 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/SystemField.java @@ -0,0 +1,94 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.logic.utilities.interfaces.XmlSerializable; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.SystemFieldType; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.util.UUID; + +public class SystemField implements XmlSerializable { + + private UUID id; + private SystemFieldType type; + private String label; + private String placeholder; + private String description; + private boolean required; + private Integer ordinal; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public SystemFieldType getType() { + return type; + } + public void setType(SystemFieldType type) { + this.type = type; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public String getPlaceholder() { + return placeholder; + } + public void setPlaceholder(String placeholder) { + this.placeholder = placeholder; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public boolean isRequired() { + return required; + } + public void setRequired(boolean required) { + this.required = required; + } + + public Integer getOrdinal() { + return ordinal; + } + public void setOrdinal(Integer ordinal) { + this.ordinal = ordinal; + } + + + @Override + public Element toXml(Document doc) { + Element rootElement = doc.createElement("systemField"); + rootElement.setAttribute("id", this.getId().toString()); + rootElement.setAttribute("type", String.valueOf(this.type.getType())); + rootElement.setAttribute("label", this.label); + rootElement.setAttribute("placeholder", this.placeholder); + rootElement.setAttribute("description", this.description); + rootElement.setAttribute("required", String.valueOf(this.required)); + rootElement.setAttribute("ordinal", String.valueOf(this.ordinal)); + return rootElement; + } + + @Override + public SystemField fromXml(Element item) { + this.id = UUID.fromString(item.getAttribute("id")); + this.type = SystemFieldType.fromInteger(Integer.parseInt(item.getAttribute("type"))); + this.label = item.getAttribute("label"); + this.placeholder = item.getAttribute("placeholder"); + this.description = item.getAttribute("description"); + this.required = Boolean.parseBoolean(item.getAttribute("required")); + this.ordinal = Integer.valueOf(item.getAttribute("ordinal")); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/ExtraFieldType.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/ExtraFieldType.java new file mode 100644 index 000000000..6aa7fc24e --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/ExtraFieldType.java @@ -0,0 +1,30 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types; + +public enum ExtraFieldType { + TEXT(0), RICH_TEXT(1), DATE(2), NUMBER(3); + + private Integer value; + + private ExtraFieldType(Integer value) { + this.value = value; + } + + public Integer getValue() { + return value; + } + + public static ExtraFieldType fromInteger(Integer value) { + switch (value) { + case 0: + return TEXT; + case 1: + return RICH_TEXT; + case 2: + return DATE; + case 3: + return NUMBER; + default: + throw new RuntimeException("Unsupported ExtraFieldType Type"); + } + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/SystemFieldType.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/SystemFieldType.java new file mode 100644 index 000000000..852680213 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/SystemFieldType.java @@ -0,0 +1,58 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types; + +public enum SystemFieldType { + + TEXT(0), + HTML_TEXT(1), + RESEARCHERS(2), + ORGANIZATIONS(3), + LANGUAGE(4), + CONTACT(5), + FUNDER(6), + GRANT(7), + PROJECT(8), + LICENSE(9), + ACCESS_RIGHTS(10), + DESCRIPTION_TEMPLATES(11); + + private int type; + + SystemFieldType(int type) { + this.type = type; + } + + public int getType() { + return type; + } + + public static SystemFieldType fromInteger(int type) { + switch (type) { + case 0: + return TEXT; + case 1: + return HTML_TEXT; + case 2: + return RESEARCHERS; + case 3: + return ORGANIZATIONS; + case 4: + return LANGUAGE; + case 5: + return CONTACT; + case 6: + return FUNDER; + case 7: + return GRANT; + case 8: + return PROJECT; + case 9: + return LICENSE; + case 10: + return ACCESS_RIGHTS; + case 11: + return DESCRIPTION_TEMPLATES; + default: + throw new RuntimeException("Unsupported System Field Type"); + } + } +} \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanBlueprintListingModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanBlueprintListingModel.java new file mode 100644 index 000000000..d0788c1af --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanBlueprintListingModel.java @@ -0,0 +1,93 @@ +package eu.eudat.models.data.listingmodels; + +import eu.eudat.data.entities.DMPProfile; +import eu.eudat.logic.utilities.builders.XmlBuilder; +import eu.eudat.models.DataModel; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanBlueprint; +import org.w3c.dom.Document; + +import java.util.Date; +import java.util.UUID; + +public class DataManagementPlanBlueprintListingModel implements DataModel { + + private UUID id; + private String label; + private DataManagementPlanBlueprint definition; + private int status; + private Date created = null; + private Date modified = new Date(); + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public DataManagementPlanBlueprint getDefinition() { + return definition; + } + public void setDefinition(DataManagementPlanBlueprint definition) { + this.definition = definition; + } + + public int getStatus() { + return status; + } + public void setStatus(int status) { + this.status = status; + } + + public Date getCreated() { + return created; + } + public void setCreated(Date created) { + this.created = created; + } + + public Date getModified() { + return modified; + } + public void setModified(Date modified) { + this.modified = modified; + } + + @Override + public DataManagementPlanBlueprintListingModel fromDataModel(DMPProfile entity) { + this.id = entity.getId(); + this.created = entity.getCreated(); + this.definition = new DataManagementPlanBlueprint().fromXml(XmlBuilder.fromXml(entity.getDefinition()).getDocumentElement()); + this.modified = entity.getModified(); + this.label = entity.getLabel(); + this.status = entity.getStatus(); + return this; + } + + @Override + public DMPProfile toDataModel() throws Exception { + Document document = XmlBuilder.getDocument(); + document.appendChild(this.definition.toXml(document)); + DMPProfile dmpProfile = new DMPProfile(); + dmpProfile.setCreated(this.created == null ? new Date() : this.created); + dmpProfile.setDefinition(XmlBuilder.generateXml(document)); + dmpProfile.setId(this.id); + dmpProfile.setLabel(this.label); + dmpProfile.setStatus(this.status); + dmpProfile.setModified(this.modified == null ? new Date() : this.modified); + return dmpProfile; + } + + @Override + public String getHint() { + return null; + } + +} diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing.ts b/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing.ts new file mode 100644 index 000000000..77d74a616 --- /dev/null +++ b/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing.ts @@ -0,0 +1,10 @@ +import { DmpBlueprintDefinition } from "./dmp-blueprint"; + +export interface DmpBlueprintListing { + id: string; + label: string; + definition: DmpBlueprintDefinition; + status: number; + created: Date; + modified: Date; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint.ts b/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint.ts new file mode 100644 index 000000000..5f25b8875 --- /dev/null +++ b/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint.ts @@ -0,0 +1,72 @@ +export interface DmpBlueprint { + id: string; + label: string; + definition: DmpBlueprintDefinition; + status: number; + created: Date; + modified: Date; + description: string; +} + +export interface DmpBlueprintDefinition { + sections: SectionDmpBlueprint[]; +} + +export interface SectionDmpBlueprint { + id: string; + label: string; + description: string; + ordinal: number; + systemFields: SystemFieldInSection[]; + descriptionTemplates?: DescriptionTemplatesInSection[]; + extraFields?: ExtraFieldInSection[]; +} + +export interface SystemFieldInSection { + id: string; + type: SystemFieldType; + label: string; + placeholder: string; + description: string; + required: boolean; + ordinal: number; +} + +export enum SystemFieldType { + TEXT = 0, + HTML_TEXT = 1, + RESEARCHERS= 2, + ORGANIZATIONS = 3, + LANGUAGE = 4, + CONTACT = 5, + FUNDER = 6, + GRANT = 7, + PROJECT = 8, + LICENSE = 9, + ACCESS_RIGHTS = 10 +} + +export interface DescriptionTemplatesInSection { + id: string; + descriptionTemplateId: string; + label: string; + minMultiplicity: number; + maxMultiplicity: number; +} + +export interface ExtraFieldInSection { + id: string; + label: string; + description: string; + placeholder: string; + type: ExtraFieldType; + required: boolean; + ordinal: number; +} + +export enum ExtraFieldType { + TEXT = 0, + RICH_TEXT = 1, + DATE = 2, + NUMBER = 3 +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/query/dmp/dmp-blueprint-criteria.ts b/dmp-frontend/src/app/core/query/dmp/dmp-blueprint-criteria.ts new file mode 100644 index 000000000..8f9a77042 --- /dev/null +++ b/dmp-frontend/src/app/core/query/dmp/dmp-blueprint-criteria.ts @@ -0,0 +1,5 @@ +import { BaseCriteria } from "../base-criteria"; + +export class DmpBlueprintCriteria extends BaseCriteria { + +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/dmp/dmp-profile.service.ts b/dmp-frontend/src/app/core/services/dmp/dmp-profile.service.ts index 9b9f16f39..94b666594 100644 --- a/dmp-frontend/src/app/core/services/dmp/dmp-profile.service.ts +++ b/dmp-frontend/src/app/core/services/dmp/dmp-profile.service.ts @@ -14,6 +14,9 @@ import { BaseHttpParams } from '../../../../common/http/base-http-params'; import { InterceptorType } from '../../../../common/http/interceptors/interceptor-type'; import { DmpProfileExternalAutocompleteCriteria } from '../../query/dmp/dmp-profile-external-autocomplete-criteria'; import { ConfigurationService } from '../configuration/configuration.service'; +import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria'; +import { DmpBlueprintListing } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing'; +import { DmpBlueprint } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; @Injectable() export class DmpProfileService { @@ -29,14 +32,26 @@ export class DmpProfileService { return this.http.post>(this.actionUrl + 'getPaged', dataTableRequest, { headers: this.headers }); } + getPagedBlueprint(dataTableRequest: DataTableRequest): Observable> { + return this.http.post>(this.actionUrl + 'getPagedBlueprint', dataTableRequest, { headers: this.headers }); + } + getSingle(id: String): Observable { return this.http.get(this.actionUrl + 'getSingle/' + id, { headers: this.headers }); } + getSingleBlueprint(id: String): Observable { + return this.http.get(this.actionUrl + 'getSingleBlueprint/' + id, { headers: this.headers }); + } + createDmp(dataManagementPlanModel: DmpProfile): Observable { return this.http.post(this.actionUrl, dataManagementPlanModel, { headers: this.headers }); } + createBlueprint(dmpBlueprint: DmpBlueprint): Observable { + return this.http.post(this.actionUrl + 'blueprint', dmpBlueprint, { headers: this.headers }); + } + public downloadXML(id: string): Observable> { let headerXml: HttpHeaders = this.headers.set('Content-Type', 'application/xml') return this.httpClient.get(this.actionUrl + 'getXml/' + id, { responseType: 'blob', observe: 'response', headers: headerXml }); diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.routing.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.routing.ts index 21a9ef4b8..f5c51ec6b 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.routing.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.routing.ts @@ -7,8 +7,8 @@ import { AdminAuthGuard } from '@app/core/admin-auth-guard.service'; const routes: Routes = [ { path: '', component: DmpProfileListingComponent, canActivate: [AdminAuthGuard] }, - { path: 'new', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-PROFILE-NEW' } }, - { path: ':id', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-PROFILE-EDIT' } }, + { path: 'new', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-NEW' } }, + { path: ':id', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-EDIT' } }, ]; @NgModule({ diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model.ts new file mode 100644 index 000000000..fb7c3e3d0 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model.ts @@ -0,0 +1,192 @@ +import { FormBuilder, FormGroup } from "@angular/forms"; +import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, ExtraFieldInSection, ExtraFieldType, SectionDmpBlueprint, SystemFieldInSection, SystemFieldType } from "@app/core/model/dmp/dmp-blueprint/dmp-blueprint"; + +export class DmpBlueprintEditor { + public id: string; + public label: string; + public definition: DmpBlueprintDefinitionEditor = new DmpBlueprintDefinitionEditor(); + public status: number; + public created: Date; + public modified: Date; + + fromModel(item: DmpBlueprint): DmpBlueprintEditor { + this.id = item.id; + this.label = item.label; + this.definition = new DmpBlueprintDefinitionEditor().fromModel(item.definition); + this.status = item.status; + this.created = item.created; + this.modified = item.modified; + return this; + } + + buildForm(): FormGroup { + const formGroup = new FormBuilder().group({ + id: [this.id], + label: [this.label], + status: [this.status], + created: [this.created], + modified: [this.modified] + }); + formGroup.addControl('definition', this.definition.buildForm()); + return formGroup; + } + +} + +export class DmpBlueprintDefinitionEditor { + + public sections: SectionDmpBlueprintEditor[] = new Array(); + + fromModel(item: DmpBlueprintDefinition): DmpBlueprintDefinitionEditor { + if (item.sections) { item.sections.map(x => this.sections.push(new SectionDmpBlueprintEditor().fromModel(x))); } + return this; + } + + buildForm(): FormGroup { + const formBuilder = new FormBuilder(); + const formGroup = formBuilder.group({}); + const sectionsFormArray = new Array(); + this.sections.forEach(item => { + const form: FormGroup = item.buildForm(); + sectionsFormArray.push(form); + }); + formGroup.addControl('sections', formBuilder.array(sectionsFormArray)); + return formGroup; + } +} + +export class SectionDmpBlueprintEditor { + public id: string; + public label: string; + public description: string; + public ordinal: number; + public systemFields: SystemFieldInSectionEditor[] = new Array(); + public descriptionTemplates: DescriptionTemplatesInSectionEditor[] = new Array(); + + fromModel(item: SectionDmpBlueprint): SectionDmpBlueprintEditor { + this.id = item.id; + this.label = item.label; + this.description = item.description; + this.ordinal = item.ordinal; + if (item.systemFields) { item.systemFields.map(x => this.systemFields.push(new SystemFieldInSectionEditor().fromModel(x))); } + if (item.descriptionTemplates) { item.descriptionTemplates.map(x => this.descriptionTemplates.push(new DescriptionTemplatesInSectionEditor().fromModel(x))); } + debugger; + return this; + } + + buildForm(): FormGroup { + const formGroup = new FormBuilder().group({ + id: [this.id], + label: [this.label], + description: [this.description], + ordinal: [this.ordinal] + }); + const formBuilder = new FormBuilder(); + const systemFieldsFormArray = new Array(); + this.systemFields.forEach(item => { + const form: FormGroup = item.buildForm(); + systemFieldsFormArray.push(form); + }); + formGroup.addControl('systemFields', formBuilder.array(systemFieldsFormArray)); + const descriptionTemplatesFormArray = new Array(); + this.descriptionTemplates.forEach(item => { + const form: FormGroup = item.buildForm(); + descriptionTemplatesFormArray.push(form); + }); + formGroup.addControl('descriptionTemplates', formBuilder.array(descriptionTemplatesFormArray)); + return formGroup; + } +} + +export class SystemFieldInSectionEditor { + public id: string; + public type: SystemFieldType; + public placeholder: string; + public description: string; + public required: boolean; + public ordinal: number; + + fromModel(item: SystemFieldInSection): SystemFieldInSectionEditor { + this.id = item.id; + this.type = item.type; + this.placeholder = item.placeholder; + this.description = item.description; + this.required = item.required; + this.ordinal = item.ordinal; + return this; + } + + buildForm(): FormGroup { + const formGroup = new FormBuilder().group({ + id: [this.id], + type: [this.type], + placeholder: [this.placeholder], + description: [this.description], + required: [this.required], + ordinal: [this.ordinal] + }); + return formGroup; + } +} + +export class DescriptionTemplatesInSectionEditor { + public id: string; + public descriptionTemplateId: string; + public label: string; + public minMultiplicity: number; + public maxMultiplicity: number; + + fromModel(item: DescriptionTemplatesInSection): DescriptionTemplatesInSectionEditor { + this.id = item.id; + this.descriptionTemplateId = item.descriptionTemplateId; + this.label = item.label; + this.minMultiplicity = item.minMultiplicity; + this.maxMultiplicity = item.maxMultiplicity; + return this; + } + + buildForm(): FormGroup { + const formGroup = new FormBuilder().group({ + id: [this.id], + descriptionTemplateId: [this.descriptionTemplateId], + label: [this.label], + minMultiplicity: [this.minMultiplicity], + maxMultiplicity: [this.maxMultiplicity] + }); + return formGroup; + } +} + +export class ExtraFieldsInSectionEditor { + public id: string; + public label: string; + public description: string; + public placeholder: string; + public type: ExtraFieldType; + public required: boolean; + public ordinal: number; + + fromModel(item: ExtraFieldInSection): ExtraFieldsInSectionEditor { + this.id = item.id; + this.label = item.label; + this.description = item.description; + this.placeholder = item.placeholder; + this.type = item.type; + this.required = item.required; + this.ordinal = item.ordinal; + return this; + } + + buildForm(): FormGroup { + const formGroup = new FormBuilder().group({ + id: [this.id], + label: [this.label], + description: [this.description], + placeholder: [this.placeholder], + type: [this.type], + required: [this.required], + ordinal: [this.ordinal] + }); + return formGroup; + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html index e0bc6fda9..1c09aeac8 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html @@ -18,10 +18,10 @@
    + [disabled]="true" type="button">{{'DMP-PROFILE-EDITOR.ACTIONS.FINALIZE' | translate }}
    -
    + +
    +
    + + System Field + + +
    +
    + + Label + + +
    +
    + + Placeholder + + +
    +
    + + Description + + +
    + +
    + + + + + + + +
    +
    + + + Label + + + + Description + + + + Type + + + {{getExtraFieldTypeValue(extraFieldType)}} + + + +
    + + Required + +
    +
    + delete + {{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    + +
    +
    +
    + + + Description Templates + + + + +
    +
    +
    + +
    +
    +
    + +
    + delete + {{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} +
    +
    +
    + + + + + +
    +
    +
    + +
    +
    +
    + +
    @@ -139,7 +349,7 @@
    -->
    -
    diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss index b05bd906f..9313e4bc8 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss @@ -60,4 +60,62 @@ color: #FFF; border: 0px; } +} + +.dlt-section-btn { + margin: 0; + position: absolute; + top: 50%; + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} + +.section-input { + position: relative; +} + +.section-input .arrows { + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); +} + +.action-list-item{ + display: flex; + align-items: center; + cursor: pointer; + + .action-list-icon{ + font-size: 1.2em; + // padding-right: 1em; + width: 14px; + margin-right: 0.5em; + margin-left: -.09em; + height: auto; + color: var(--primary-color); + } + + .action-list-text{ + font-size: 1em; + color: var(--primary-color); + } +} + +.extra-field-delete{ + align-items: center; + display: flex; + cursor: pointer; + + .extra-field-delete-icon{ + font-size: 1.2em; + width: 14px; + color: var(--primary-color); + } + + .extra-field-delete-text{ + font-size: 1em; + margin-left: 0.5em; + color: var(--primary-color); + } } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts index 55a0cff24..f4f3498ae 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts @@ -1,6 +1,6 @@ import { AfterViewInit, Component } from '@angular/core'; -import { FormArray, FormGroup } from '@angular/forms'; +import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { DmpProfileFieldDataType } from '@app/core/common/enum/dmp-profile-field-type'; import { DmpProfileStatus } from '@app/core/common/enum/dmp-profile-status'; @@ -25,6 +25,17 @@ import { HttpClient } from '@angular/common/http'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { MatDialog } from '@angular/material/dialog'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; +import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; +import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; +import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria'; +import { DmpService } from '@app/core/services/dmp/dmp.service'; +import { AvailableProfilesComponent } from '@app/ui/dmp/editor/available-profiles/available-profiles.component'; +import { DatasetPreviewDialogComponent } from '@app/ui/dmp/dataset-preview/dataset-preview-dialog.component'; +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { DmpBlueprint, DmpBlueprintDefinition, ExtraFieldType, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintEditor } from './dmp-blueprint-editor.model'; +import { Guid } from '@common/types/guid'; @Component({ @@ -37,19 +48,41 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie isNew = true; viewOnly = false; dmpProfileModel: DmpProfileEditorModel; + dmpBlueprintModel: DmpBlueprintEditor; formGroup: FormGroup = null; host: string; dmpProfileId: string; breadCrumbs: Observable; + dmpBlueprintsFormGroup: FormGroup = null; + + profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; + + fieldList = [ + {label: 'Title', type: SystemFieldType.TEXT}, + {label: 'Description', type: SystemFieldType.HTML_TEXT}, + {label: 'Researchers', type: SystemFieldType.RESEARCHERS}, + {label: 'Organizations', type: SystemFieldType.ORGANIZATIONS}, + {label: 'Language', type: SystemFieldType.LANGUAGE}, + {label: 'Contact', type: SystemFieldType.CONTACT}, + {label: 'Funder', type: SystemFieldType.FUNDER}, + {label: 'Grant', type: SystemFieldType.GRANT}, + {label: 'Project', type: SystemFieldType.PROJECT}, + {label: 'License', type: SystemFieldType.LICENSE}, + {label: 'Access Rights', type: SystemFieldType.ACCESS_RIGHTS} + ]; + selectedSystemFields: string[] = []; + constructor( private dmpProfileService: DmpProfileService, + private _service: DmpService, private route: ActivatedRoute, private router: Router, private language: TranslateService, private enumUtils: EnumUtils, private uiNotificationService: UiNotificationService, private formService: FormService, + private fb: FormBuilder, private configurationService: ConfigurationService, private httpClient: HttpClient, private matomoService: MatomoService, @@ -61,6 +94,16 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie ngAfterViewInit() { this.matomoService.trackPageView('Admin: DMP Profile Edit'); + + this.profilesAutoCompleteConfiguration = { + filterFn: this.filterProfiles.bind(this), + initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['label'], + titleFn: (item) => item['label'], + subtitleFn: (item) => item['description'], + popupItemActionIcon: 'visibility' + }; + this.route.params .pipe(takeUntil(this._destroyed)) .subscribe((params: Params) => { @@ -85,9 +128,11 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie }); } else { this.dmpProfileModel = new DmpProfileEditorModel(); + this.dmpBlueprintModel = new DmpBlueprintEditor(); setTimeout(() => { - this.formGroup = this.dmpProfileModel.buildForm(); - this.addField(); + // this.formGroup = this.dmpProfileModel.buildForm(); + // this.addField(); + this.formGroup = this.dmpBlueprintModel.buildForm(); }); this.breadCrumbs = observableOf([{ parentComponentName: 'DmpProfileListingComponent', @@ -96,6 +141,282 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie }]); } }); + + this.initDmpBlueptintForm(); + + } + + + filterProfiles(value: string): Observable { + const request = new DataTableRequest(null, null, { fields: ['+label'] }); + const criteria = new DatasetProfileCriteria(); + criteria.like = value; + request.criteria = criteria; + return this._service.searchDMPProfiles(request); + } + + initDmpBlueptintForm(): void { + this.dmpBlueprintsFormGroup = this.fb.group({ + label: this.fb.control(''), + sections: this.fb.array([]) + }); + } + + sectionsArray(): FormArray { + return this.dmpBlueprintsFormGroup.get('sections') as FormArray; + } + + initSection(ordinal: number): FormGroup { + return this.fb.group({ + id: this.fb.control(Guid.create().toString()), + label: this.fb.control(''), + description: this.fb.control(''), + ordinal: this.fb.control(ordinal), + systemFields: this.fb.array([]), + descriptionTemplates: this.fb.control(''), + // this.fb.array([this.initDescriptionTemplate()]), + extraFields: this.fb.array([]) + }); + } + + addSection(): void { + this.sectionsArray().push(this.initSection(this.sectionsArray().length)); + } + + removeSection(sectionIndex: number): void { + this.sectionsArray().removeAt(sectionIndex); + } + + systemFieldsArray(sectionIndex: number): FormArray { + return this.sectionsArray().at(sectionIndex).get('systemFields') as FormArray; + } + + initSystemField(systemField?: SystemFieldType): FormGroup { + return this.fb.group({ + id: this.fb.control(Guid.create().toString()), + type: this.fb.control(systemField), + label: this.fb.control(''), + placeholder: this.fb.control(''), + description: this.fb.control(''), + required: this.fb.control(true), + ordinal: this.fb.control('') + }); + } + + addSystemField(sectionIndex: number, systemField?: SystemFieldType): void { + this.systemFieldsArray(sectionIndex).push(this.initSystemField(systemField)); + } + + transfromEnumToString(type: SystemFieldType): string{ + return this.fieldList.find(f => f.type == type).label; + } + + selectedFieldType(systemField: string, type: SystemFieldType, sectionIndex: number): void { + let index = this.selectedSystemFields.indexOf(systemField); + if (index == -1) { + this.selectedSystemFields.push(systemField); + this.addSystemField(sectionIndex, type); + } + else { + this.selectedSystemFields.splice(index, 1); + this.removeSystemField(sectionIndex, type); + } + } + + systemFieldDisabled(systemField: SystemFieldType, sectionIndex: number) { + let i = 0; + for (let s in this.sectionsArray().controls) { + if (i != sectionIndex) { + for (let f of this.systemFieldsArray(i).controls) { + if (f.get('type').value == systemField) { + return true; + } + } + } + i++; + } + return false; + } + + removeSystemFieldWithIndex(sectionIndex: number, fieldIndex: number): void { + this.systemFieldsArray(sectionIndex).removeAt(fieldIndex); + } + + removeSystemField(sectionIndex: number, systemField: SystemFieldType): void { + let i = 0; + for(let sf of this.systemFieldsArray(sectionIndex).controls){ + if(sf.get('type').value == systemField){ + this.systemFieldsArray(sectionIndex).removeAt(i); + return; + } + i++; + } + } + + descriptionTemplatesArray(sectionIndex: number): FormArray { + return this.sectionsArray().at(sectionIndex).get('descriptionTemplates') as FormArray; + } + + initDescriptionTemplate(): FormGroup { + return this.fb.group({ + descriptionTemplateId: this.fb.control(''), + label: this.fb.control(''), + minMultiplicity: this.fb.control(''), + maxMultiplicity: this.fb.control('') + }); + } + + addDescriptionTemplate(descriptionTemplate, sectionIndex: number): void { + this.descriptionTemplatesArray(sectionIndex).push(this.fb.group({ + label: this.fb.control(descriptionTemplate.value) + })); + } + + removeDescriptionTemplate(sectionIndex: number, templateIndex: number): void { + this.descriptionTemplatesArray(sectionIndex).removeAt(templateIndex); + } + + extraFieldsArray(sectionIndex: number): FormArray { + return this.sectionsArray().at(sectionIndex).get('extraFields') as FormArray; + } + + initExtraField(): FormGroup { + return this.fb.group({ + id: this.fb.control(Guid.create().toString()), + label: this.fb.control(''), + placeholder: this.fb.control(''), + description: this.fb.control(''), + type: this.fb.control(''), + required: this.fb.control(false), + ordinal: this.fb.control('') + }); + } + + addExtraField(sectionIndex: number): void { + this.extraFieldsArray(sectionIndex).push(this.initExtraField()); + } + + removeExtraField(sectionIndex: number, extraFieldIndex: number): void { + this.extraFieldsArray(sectionIndex).removeAt(extraFieldIndex); + } + + getExtraFieldTypes(): Number[] { + let keys: string[] = Object.keys(ExtraFieldType); + keys = keys.slice(0, keys.length / 2); + const values: Number[] = keys.map(Number); + return values; + } + + getExtraFieldTypeValue(extraFieldType: ExtraFieldType): string { + switch (extraFieldType) { + case ExtraFieldType.TEXT: return 'Text'; + case ExtraFieldType.RICH_TEXT: return 'Rich Text'; + case ExtraFieldType.DATE: return 'Date'; + case ExtraFieldType.NUMBER: return 'Number'; + } + } + + onSubmitTest(): void { + } + + drop(event: CdkDragDrop) { + this.moveItemInFormArray( + this.systemFieldsArray(0), + event.previousIndex, + event.currentIndex + ); + } + + moveItemInFormArray(formArray: FormArray, fromIndex: number, toIndex: number): void { + const dir = toIndex > fromIndex ? 1 : -1; + + const item = formArray.at(fromIndex); + for (let i = fromIndex; i * dir < toIndex * dir; i = i + dir) { + const current = formArray.at(i + dir); + formArray.setControl(i, current); + } + formArray.setControl(toIndex, item); + } + + // clearForm(): void{ + // this.dmpBlueprintsFormGroup.reset(); + // } + + canGoUp(index: number): boolean { + return index > 0; + } + + canGoDown(index: number): boolean { + return index < (this.sectionsArray().length - 1); + } + + onRemoveTemplate(event, sectionIndex: number) { + // let found = false; + // const profiles = this.descriptionTemplatesArray(sectionIndex).value;//this.formGroup.get('profiles').value; + // this.formGroup.get('datasets')['controls'].forEach(element => { + // if (element.get('profile').value.id === event.id) { + // found = true; + // this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-REMOVE-TEMPLATE'), SnackBarNotificationLevel.Success); + // } + // }); + // if (found) { + // this.formGroup.get('profiles').setValue(profiles); + // this.profilesAutoCompleteConfiguration = { + // filterFn: this.filterProfiles.bind(this), + // initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + // displayFn: (item) => item['label'], + // titleFn: (item) => item['label'], + // subtitleFn: (item) => item['description'], + // popupItemActionIcon: 'visibility' + // }; + + // } + } + + onPreviewTemplate(event, sectionIndex: number) { + const dialogRef = this.dialog.open(DatasetPreviewDialogComponent, { + width: '590px', + minHeight: '200px', + restoreFocus: false, + data: { + template: event + }, + panelClass: 'custom-modalbox' + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + let profiles = this.descriptionTemplatesArray(sectionIndex).value;//this.formGroup.get('profiles').value; + profiles.push(event); + this.descriptionTemplatesArray(sectionIndex).setValue(profiles);//this.formGroup.get('profiles').setValue(profiles); + this.profilesAutoCompleteConfiguration = { + filterFn: this.filterProfiles.bind(this), + initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['label'], + titleFn: (item) => item['label'], + subtitleFn: (item) => item['description'], + popupItemActionIcon: 'visibility' + }; + } + }); + } + onOptionSelected(sectionIndex: number){ + try{ + const profiles = this.descriptionTemplatesArray(sectionIndex).value as {id:string, label:string}[];//this.formGroup.get('profiles').value as {id:string, label:string}[]; + const profileCounts: Map = new Map(); + profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id): 0 ) + 1)); + const duplicateProfiles = profiles.filter((value) => { + let isOk = profileCounts.get(value.id) > 1; + if (isOk) { + profileCounts.set(value.id, 0); + } + return isOk; + }); + duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1)); + profiles.sort((a,b)=> a.label.localeCompare(b.label)); + } + catch{ + console.info('Could not sort Dataset Templates') + } } formSubmit(): void { diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.html b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.html index 733ea2248..582bb35ce 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.html +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.html @@ -13,7 +13,7 @@
    diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts index 9ffd48074..b4189b030 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts @@ -71,7 +71,7 @@ export class DmpProfileListingComponent extends BaseComponent implements OnInit this.criteria.setRefreshCallback(() => this.refresh()); this.breadCrumbs = observableOf([{ parentComponentName: null, - label: this.languageService.instant('NAV-BAR.DMP-TEMPLATES'), + label: this.languageService.instant('NAV-BAR.DMP-BLUEPRINTS-CAPS'), url: '/dmp-profiles' }]); }); diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html new file mode 100644 index 000000000..7c356d557 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html @@ -0,0 +1,271 @@ +
    +
    +
    + +
    +
    +
    +
    +
    +
    {{'DMP-EDITOR.TITLE.EDIT-DMP' | translate}}
    + +
    +
    + +
    + + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    DMP Blueprint
    +
    +
      +
    1. Select Blueprint
    2. +
      +
    3. {{section.label}}
    4. +
      +
    +
    +
    + +
    +
    {{'DMP-EDITOR.STEPPER.NEXT' | translate}}
    + chevron_right +
    + + +
    +
    + +
    +
    +
    +
    +
    + + + + +
    +
    +
    + +
    +
    +
    +
    +

    or continue with

    +
    +
    + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss new file mode 100644 index 000000000..a6be61a3c --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss @@ -0,0 +1,378 @@ +@media (max-width: 768px) { + .main-content { + padding: 30px 0px; + } + + button { + font-size: small; + } +} + +.form-container { + height: calc(100vh - 124px); + margin-top: 6rem; +} + +.fixed-editor-header { + // position: fixed; + // width: calc(100% - 310px); + z-index: 3; + background-color: whitesmoke; +} + +.editor-header { + height: 64px; + background: var(--unnamed-color-var(--primary-color)) 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; + box-shadow: 0px 3px 6px #00000029; + padding: 0.6rem; + margin: 30px 0px 0px 0px; + border-radius: 4px; + opacity: 1; + + .info { + flex: 2; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +} + +.title { + text-align: left; + font-weight: 400; + font-size: 14px; + color: #ffffff; + opacity: 0.75; +} + +.subtitle { + text-align: left; + color: #ffffff; + font-weight: 700; + font-size: 16px; + opacity: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.save-btn, .dmp-export-btn { + background: #ffffff 0% 0% no-repeat padding-box !important; + border-radius: 30px; + opacity: 1; + width: 110px; + height: 40px; + display: flex; + justify-content: center; + align-items: center; + font-weight: 700; + color: var(--primary-color); +} + +.dmp-stepper { + position: fixed; + // height: 100%; + display: flex; + flex-direction: column; + height: calc(100vh - 190px); + overflow-y: auto; +} + +.stepper-title { + text-align: left; + font-weight: 300; + font-size: 20px; + letter-spacing: 0px; + color: #212121; + opacity: 0.6; + margin: 2.875rem 0rem 2.875rem 0rem; + padding-left: 1rem; +} + +.stepper-list li { + text-align: left; + font-weight: 400; + letter-spacing: 0px; + color: #212121; + padding: 0.3rem 0.1rem; + opacity: 0.6; + cursor: pointer; + max-width: 290px; +} + +.stepper-list li:hover { + background-color: #ececec; + border-radius: 6px; +} + +.stepper-list .active { + color: #212121; + font-weight: 700; + opacity: 1; +} + +.stepper-list .active-dataset { + color: #212121; + font-weight: 700; + opacity: 1; + .label { + width: 100%; + height: 27px; + line-height: 27px; + background-color: var(--secondary-color); + color: #5d5d5d; + border-radius: 4px; + font-weight: 400; + font-size: 14px; + justify-content: left; + display: flex; + align-items: center; + padding-left: 0.625rem; + padding-right: 0.625rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + } +} + +mat-icon.size-16 { + width: 16px; + height: 16px; + line-height: 16px; + font-size: 16px; + margin-top: 0.4rem; +} + +.remove-dataset { + color: #f16868; +} + +.remove-dataset:hover { + color: #f16868; +} + +.stepper-actions { + display: flex; + padding-left: 1rem; + margin-top: auto; + margin-bottom: 0.5rem; + // margin-top: 5rem; + // flex-grow: 8; +} + +.stepper-btn { + border-radius: 30px; + opacity: 1; + width: 154px; + min-height: 40px; + display: flex; + justify-content: center; + align-items: center; + font-size: 14px; +} + +.previous { + color: #212121; + background: #f5f5f5 0% 0% no-repeat padding-box; + box-shadow: 0px 3px 6px #1e202029; + border: 2px solid #212121; + font-weight: 500; + cursor: pointer; +} + +.add-dataset-btn { + background: var(--secondary-color) 0% 0% no-repeat padding-box; + box-shadow: 0px 3px 6px #1e202029; + font-weight: 500; + white-space: normal; + word-wrap: break-word; + line-height: normal; + text-align: left; + font-size: 13.8px; +} + +.add-dataset-action { + display: flex; + align-items: center; + cursor: pointer; +} + +.next { + background: var(--primary-color) 0% 0% no-repeat padding-box; + color: white; + box-shadow: 0px 3px 6px #1e202029; + font-weight: 400; + cursor: pointer; +} + +.dataset-next { + background: var(--secondary-color) 0% 0% no-repeat padding-box; + color: #212121; + box-shadow: 0px 3px 6px #1e202029; + font-weight: 700; + cursor: pointer; +} + +.previous-disabled, +.add-dataset-btn-disabled { + border: 1px solid #b5b5b5; + color: #b5b5b5 !important; + cursor: auto !important; +} + +.next-disabled { + background: #cbcbcb 0% 0% no-repeat padding-box; + box-shadow: 0px 3px 6px #1e202029; + color: white; + cursor: auto !important; +} + +.form { + // position: relative; + // left: 362px; + // width: calc(100% - 366px); + + position: relative; + left: 362px; + width: calc(100% - 366px); + overflow-y: auto; + height: calc(100vh - 218px); +} + +.action-btn { + border-radius: 30px; + background-color: var(--secondary-color); + border: 1px solid transparent; + padding-left: 2em; + padding-right: 2em; + box-shadow: 0px 3px 6px #1E202029; + + transition-property: background-color, color; + transition-duration: 200ms; + transition-delay: 50ms; + transition-timing-function: ease-in-out; + &:disabled{ + background-color: #CBCBCB; + color: #FFF; + border: 0px; + } +} + +.blueprint-section { + text-align: left; + font-weight: 400; + letter-spacing: 0px; + color: #212121; + opacity: 1; + margin: 3rem 0rem 3rem 0rem; +} + +a { + color: #000000; +} + +a:hover { + color: var(--primary-color-3); +} + +.main-content { + height: 100vh !important; + margin-top: -80px; +} + +.dmp-blueprint-form { + text-align: left; + font-weight: 400; + font-size: 16px; + letter-spacing: 0.15px; + color: #7d7d7d; + opacity: 1; + margin-bottom: 1rem; +} + +.section-info { + .intro { + text-align: left; + font-weight: 400; + letter-spacing: 0px; + color: #212121; + opacity: 1; + margin: 3rem 0rem 3rem 0rem; + } + + .heading { + text-align: left; + font-weight: 700; + font-size: 18px; + letter-spacing: 0px; + color: #212121; + opacity: 0.81; + margin-top: 1.625rem; + margin-bottom: 0.625rem; + } + + .hint { + text-align: left; + font-weight: 400; + font-size: 16px; + letter-spacing: 0px; + color: #212121; + opacity: 0.81; + margin-bottom: 2.125rem; + } + + .input-form { + text-align: left; + font-weight: 400; + font-size: 16px; + letter-spacing: 0.15px; + color: #7d7d7d; + opacity: 1; + margin-bottom: 1rem; + } + + .insert-manually { + text-decoration: underline; + color: var(--primary-color-3); + cursor: pointer; + font-size: 1rem; + font-weight: 400; + } + + .not-found { + // cursor: pointer; + font-size: 1rem; + font-weight: 400; + padding: 0rem 0.5rem 0rem 0rem; + } + + .disabled-toggle { + font-size: 1rem; + font-weight: 400; + padding: 0rem 0.5rem 0rem 0rem; + color: #e0e0e0 !important; + text-decoration: none; + } + + .input-btn { + border: none; + color: #aaaaaa; + background-color: #ffffff00; + cursor: pointer; + } + + .input-btn :hover { + color: var(--primary-color-3) !important; + } +} + +::ng-deep .input-form .mat-form-field-appearance-outline .mat-form-field-outline { + background: #fafafa !important; +} + +::ng-deep .input-form .mat-form-field-appearance-outline .mat-form-field-infix { + font-size: 1rem; + padding: 0.6em 0 1em 0 !important; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts new file mode 100644 index 000000000..53a569870 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts @@ -0,0 +1,777 @@ +import { Component, OnInit } from '@angular/core'; +import { AbstractControl, FormArray, FormControl, FormGroup, Validators } from '@angular/forms'; +import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; +import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria'; +import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service'; +import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; +import { DmpBlueprintEditor } from '@app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model'; +import { debounceTime, filter, map, switchMap, takeUntil, tap } from 'rxjs/operators'; +import { DmpEditorModel } from '../editor/dmp-editor.model'; +import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties-form.model'; +import { FunderFormModel } from '../editor/grant-tab/funder-form-model'; +import { GrantTabModel } from '../editor/grant-tab/grant-tab-model'; +import { ProjectFormModel } from '../editor/grant-tab/project-form-model'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { BaseComponent } from '@common/base/base.component'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { LanguageInfoService } from '@app/core/services/culture/language-info-service'; +import { LanguageInfo } from '@app/core/model/language-info'; +import { UserModel } from '@app/core/model/user/user'; +import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; +import { TranslateService } from '@ngx-translate/core'; +import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service'; +import { Observable } from 'rxjs'; +import { ExternalSourceItemModel } from '@app/core/model/external-sources/external-source-item'; +import { OrganisationService } from '@app/core/services/organisation/organisation.service'; +import { MatDialog } from '@angular/material/dialog'; +import { AddResearcherComponent } from '../editor/add-researcher/add-researcher.component'; +import { AddOrganizationComponent } from '../editor/add-organization/add-organization.component'; +import { RequestItem } from '@app/core/query/request-item'; +import { LicenseCriteria } from '@app/core/query/license/license-criteria'; +import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; +import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria'; +import { DmpService } from '@app/core/services/dmp/dmp.service'; +import { AvailableProfilesComponent } from '../editor/available-profiles/available-profiles.component'; +import { DatasetPreviewDialogComponent } from '../dataset-preview/dataset-preview-dialog.component'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component'; +import { DmpStatus } from '@app/core/common/enum/dmp-status'; +import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; +import { DmpModel } from '@app/core/model/dmp/dmp'; +import { Router } from '@angular/router'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { DmpToDatasetDialogComponent } from '../dmp-to-dataset/dmp-to-dataset-dialog.component'; +import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; +import { FormService } from '@common/forms/form-service'; + +interface Visible { + value: boolean; + name: string; +} + +@Component({ + selector: 'app-dmp-editor-blueprint', + templateUrl: './dmp-editor-blueprint.component.html', + styleUrls: ['./dmp-editor-blueprint.component.scss'] +}) +export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit { + + saving = false; + + isNew = true; + isUserOwner: boolean = true; + isNewVersion = false; + isFinalized = false; + isClone = false; + hasChanges = false; + isDiscarded = false; + + isCreateNew = false; + isCreateNewProject = false; + isCreateNewFunder = false; + + dmp: DmpEditorModel; + formGroup: FormGroup = null; + formGroupRawValue: any; + + associatedUsers: Array; + people: Array; + + lockStatus: Boolean = false; + + step: number = 0; + stepsBeforeDatasets: number = 4; + maxStep: number = 4; + + scrollTop: number; + hintErrors: boolean = false; + + selectedDmpBlueprintDefinition: DmpBlueprintDefinition = null; + + private associates: UserModel[] = []; + + visibles: Visible[] = [ + { value: true, name: 'DMP-EDITOR.VISIBILITY.PUBLIC' }, + { value: false, name: 'DMP-EDITOR.VISIBILITY.RESTRICTED' } + ] + + licenseAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { + filterFn: this.licenseSearch.bind(this), + initialItems: (excludedItems: any[]) => this.licenseSearch('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['name'], + titleFn: (item) => item['name'] + }; + + profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; + + constructor( + private dmpProfileService: DmpProfileService, + private authService: AuthService, + private router: Router, + private configurationService: ConfigurationService, + private languageInfoService: LanguageInfoService, + private language: TranslateService, + private externalSourcesService: ExternalSourcesService, + private organizationService: OrganisationService, + private dmpService: DmpService, + private uiNotificationService: UiNotificationService, + private formService: FormService, + private dialog: MatDialog + ) { + super(); + } + + ngOnInit(): void { + this.dmp = new DmpEditorModel(); + this.dmp.grant = new GrantTabModel(); + this.dmp.project = new ProjectFormModel(); + this.dmp.funder = new FunderFormModel(); + this.dmp.extraProperties = new ExtraPropertiesFormModel(); + this.dmp.extraProperties.visible = false; + this.dmp.extraProperties.contact = this.authService.current().id; + this.formGroup = this.dmp.buildForm(); + + this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); + + if (this.formGroup.get('profile')) { this.selectedDmpBlueprintDefinition = this.formGroup.get('profile').value; } + this.registerFormEventsForDmpBlueprint(); + + if (!this.isUserOwner) { + this.formGroup.disable(); + } + if (isNullOrUndefined(this.formGroup.get('extraProperties').get('publicDate').value)) { + this.formGroup.get('extraProperties').get('publicDate').patchValue(new Date()); + } + + const principal = this.authService.current(); + let associate: UserModel = { + id: principal.id, + name: principal.name, + appRoles: principal.authorities, + email: principal.email + }; + this.associates.push(associate); + if (isNullOrUndefined(this.formGroup.get('extraProperties').get('contact').value)) { + this.formGroup.get('extraProperties').get('contact').patchValue(associate.id); + } + if (isNullOrUndefined(this.formGroup.get('extraProperties').get('language').value)) { + this.formGroup.get('extraProperties').get('language').patchValue('en'); + } + + try{ + const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[]; + profiles.sort((a,b)=>a.label.localeCompare(b.label)); + }catch{ + console.info('Could not sort profiles'); + } + + this.profilesAutoCompleteConfiguration = { + filterFn: this.filterProfiles.bind(this), + initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['label'], + titleFn: (item) => item['label'], + subtitleFn: (item) => item['description'], + popupItemActionIcon: 'visibility' + }; + } + + save() { + this.formSubmit(true); + } + + formSubmit(addNew?: boolean, showAddDatasetDialog?: boolean): void { + this.saving = true; + this.formService.touchAllFormFields(this.formGroup); + + if(!this._isDMPDescriptionValid()){ + const errmess = this._buildDMPDescriptionErrorMessages(); + this.showValidationErrorsDialog(undefined, errmess); + this.hintErrors = true; + this.saving = false; + return; + } + this.onSubmit(addNew, showAddDatasetDialog); + } + + public formChanged() { + if (!this.isDiscarded) { + this.hasChanges = true; + } + } + + selectDefaultBlueprint() { + this.dmpProfileService.getSingleBlueprint('86635178-36a6-484f-9057-a934e4eeecd5') + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.selectedDmpBlueprintDefinition = result.definition; + this.formGroup.get('profile').setValue(result); + this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; + this.nextStep(); + }); + } + + selectBlueprint() { + this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; + this.nextStep(); + } + + nextStep() { + this.step = this.step < this.maxStep ? this.step + 1 : this.step; + this.resetScroll(); + // if (this.step >= this.stepsBeforeDatasets) { + // this.datasetId = this.datasets.at(this.step - this.stepsBeforeDatasets).get('id').value; + // } + } + + previousStep() { + this.step = this.step !== 0 ? this.step - 1 : this.step; + this.resetScroll(); + // if (this.step >= this.stepsBeforeDatasets) { + // this.datasetId = this.datasets.at(this.step - this.stepsBeforeDatasets).get('id').value; + // } + } + + changeStep(index: number, dataset?: FormControl) { + this.step = index; + this.resetScroll(); + // if (dataset) { this.datasetId = dataset.get('id').value }; + } + + private resetScroll() { + document.getElementById('editor-form').scrollTop = 0; + } + + addDataset() { + this.saving = true; + + if(!this._isDMPDescriptionValid()){ + const errmess = this._buildDMPDescriptionErrorMessages(); + this.showValidationErrorsDialog(undefined, errmess); + this.hintErrors = true; + this.saving = false; + return; + } + + + // const showDialog = this.hasProfile() && this.isNew; + + this.onSubmit(true, false); + // this.formSubmit(true, false); + + + + + // Add dataset to list + // if (!this.formGroup.get('datasets')) { + // this.formGroup.addControl('datasets', new FormBuilder().array(new Array())); + // } + // this.formGroup.get('datasets')['controls'].push(new DatasetWizardEditorModel().buildForm()); + // this.datasets = this.formGroup.get('datasets') as FormArray; + // this.step = this.stepsBeforeDatasets + this.formGroup.get('datasets')['controls'].length - 1; + // this.maxStep = this.maxStep + this.formGroup.get('datasets')['controls'].length - 1; + } + + onSubmit(addNew?: boolean, showAddDatasetDialog?: boolean): void { + this.scrollTop = document.getElementById('editor-form').scrollTop; + // return; + this.dmpService.createDmp(this.formGroup.getRawValue()) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => { + this.formGroup.get('id').setValue(complete.id); + this.formGroup.get('modified').setValue(complete.modified); + this.hasChanges = false; + if (showAddDatasetDialog) { + this.addDatasetOpenDialog(complete); + } + if (addNew) { + this.onCallbackSuccessAddNew(complete); + } + else { this.onCallbackSuccess(complete) } + }, + error => { + this.formGroup.get('status').setValue(DmpStatus.Draft); + this.onCallbackError(error); + } + ); + // this.dmpService.createDmpWithDatasets(this.formGroup.getRawValue()) + // .pipe(takeUntil(this._destroyed)) + // .subscribe( + // complete => { + // if (showAddDatasetDialog) { + // this.addDatasetOpenDialog(complete); + // } + // else if (this.step < this.stepsBeforeDatasets) { this.onCallbackSuccess(complete) } + // else { this.onCallbackSuccess(complete, this.datasetId) } + // }, + // error => { + // this.formGroup.get('status').setValue(DmpStatus.Draft); + // this.onCallbackError(error); + // } + // ) + } + + addDatasetOpenDialog(dmp: DmpModel) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '500px', + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ADD-DATASET'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.NO'), + isDeleteConfirmation: false + } + }); + + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + // this.router.navigate(['datasets/new/' + id]); + this.addDataset(); + } else { + dmp.id != null ? this.router.navigate(['/plans', 'edit', dmp.id]) : this.router.navigate(['/plans']); + } + }); + } + + onCallbackSuccess(dmp?: DmpModel, datasetId?: string): void { + + // On save keep editor position + this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + if (dmp) { + let dmpEditorModel: DmpEditorModel; + dmpEditorModel = new DmpEditorModel(); + dmpEditorModel.grant = new GrantTabModel(); + dmpEditorModel.project = new ProjectFormModel(); + dmpEditorModel.funder = new FunderFormModel(); + dmpEditorModel.extraProperties = new ExtraPropertiesFormModel(); + dmpEditorModel.fromModel(dmp); + this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); + this.associatedUsers = dmp.associatedUsers; + this.people = dmp.users; + + setTimeout(() => { this.formGroup = null; }); + setTimeout(() => { + this.formGroup = dmpEditorModel.buildForm(); + this.formGroup.valueChanges.pipe(takeUntil(this._destroyed)) + .subscribe(x => { + this.formChanged(); + });}); + setTimeout(() => { document.getElementById('editor-form').scrollTop = this.scrollTop; }); + this.saving = false; + this.isNew = false; + } else { + this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans']); }); + } + + // Uncomment to not keep editor position on save + // if (dmp.id != null) { + // datasetId ? this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans', 'edit', dmp.id], { queryParams: { dataset: datasetId } }); }) : this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans', 'edit', dmp.id]); }) + // } else { + // this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans']); }); + // } + } + + onCallbackError(error: any) { + this.uiNotificationService.snackBarNotification(error.error.message, SnackBarNotificationLevel.Error); + this.setErrorModel(error.error); + this.saving = false; + //this.validateAllFormFields(this.formGroup); + } + + public setErrorModel(validationErrorModel: ValidationErrorModel) { + Object.keys(validationErrorModel).forEach(item => { + (this.dmp.validationErrorModel)[item] = (validationErrorModel)[item]; + }); + } + + onCallbackSuccessAddNew(dmp?: DmpModel) { + // this.editDataset(dmp.id, true, this.isNew && !this.formGroup.get('datasets').value.length); + this.editDataset(dmp.id, true, false); + this.saving = false; + } + + editDataset(id: string, isNew: boolean, showModal:boolean = false) { + + + if(showModal){ + const dialogRef = this.dialog.open(DmpToDatasetDialogComponent, { + width: '500px', + autoFocus: false, + restoreFocus: false, + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + if (isNew) { + this.router.navigate(['/datasets', 'new', id]); + } else { + this.router.navigate(['/datasets', 'edit', id]); + } + } + }); + }else{ + if (isNew) { + this.router.navigate(['/datasets', 'new', id]); + } else { + this.router.navigate(['/datasets', 'edit', id]); + } + + } + + + } + + //checks if the dpm is valid not taking into account the datasets validity + private _isDMPDescriptionValid():boolean{ + + const form: FormGroup = this.formGroup; + if(form.controls){ + return Object.keys(form.controls) + .map(controlName=>{//get validity of each control + if(controlName === 'datasets'){//we dont care if datasets are valid + return true; + } + return !form.get(controlName).invalid;//!! in case the control is disabled, we consider it valid + }) + .reduce((isFormValid,isControlValid)=>{//aggregate validities + return isControlValid && isFormValid; + }, true); + } + return true; + } + + private showValidationErrorsDialog(projectOnly?: boolean, errmess?: string[]) { + + if(errmess){ + + const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, { + disableClose: true, + autoFocus: false, + restoreFocus: false, + data: { + errorMessages:errmess, + projectOnly: projectOnly + }, + }); + }else{ + const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, { + disableClose: true, + autoFocus: false, + restoreFocus: false, + data: { + formGroup: this.formGroup, + projectOnly: projectOnly + }, + }); + } + + } + + private _buildDMPDescriptionErrorMessages(): string[]{//not including datasets + const errmess: string[] = []; + Object.keys(this.formGroup.controls).forEach(controlName=>{ + if(controlName != 'datasets' && this.formGroup.get(controlName).invalid){ + errmess.push(...this._buildErrorMessagesForAbstractControl(this.formGroup.get(controlName), controlName)); + } + }) + + return errmess; + } + + // takes as an input an abstract control and gets its error messages[] + private _buildErrorMessagesForAbstractControl(aControl: AbstractControl, controlName: string):string[]{ + const errmess:string[] = []; + + if(aControl.invalid){ + + if(aControl.errors){ + //check if has placeholder + if( (aControl).nativeElement !== undefined && (aControl).nativeElement !== null){ + const placeholder = this._getPlaceHolder(aControl); + if(placeholder){ + controlName = placeholder; + } + } + const errorMessage = this._getErrorMessage(aControl, controlName); + + errmess.push(...errorMessage); + } + /*in case the aControl is FormControl then the it should have provided its error messages above. + No need to check case of FormControl below*/ + + if(aControl instanceof FormGroup){ + + const fg = aControl as FormGroup; + //check children + Object.keys(fg.controls).forEach(controlName=>{ + errmess.push(...this._buildErrorMessagesForAbstractControl(fg.get(controlName), controlName)); + }); + }else if(aControl instanceof FormArray){ + + const fa = aControl as FormArray; + + fa.controls.forEach((control,index)=>{ + errmess.push(... this._buildErrorMessagesForAbstractControl(control, `${controlName} --> ${index+1}`)); + }); + + } + + } + + return errmess; + } + + private _getErrorMessage(formControl: AbstractControl, name: string): string[] { + const errors: string[] = []; + Object.keys(formControl.errors).forEach(key => { + if (key === 'required') { errors.push(this.language.instant(name + ": " + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.REQUIRED'))); } + // if (key === 'required') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + this.getPlaceHolder(formControl) + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.REQUIRED')); } + else if (key === 'email') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.EMAIL')); } + else if (key === 'min') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.MIN-VALUE', { 'min': formControl.getError('min').min })); } + else if (key === 'max') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.MAX-VALUE', { 'max': formControl.getError('max').max })); } + else { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + formControl.errors[key].message); } + }); + return errors; + } + + private _getPlaceHolder(formControl: any): string { + if (formControl.nativeElement.localName === 'input' || formControl.nativeElement.localName === 'textarea' + || formControl.nativeElement.localName === 'richTextarea') { + return formControl.nativeElement.getAttribute('placeholder'); + } else if (formControl.nativeElement.localName === 'mat-select') { + return formControl.nativeElement.getAttribute('placeholder'); + } else if (formControl.nativeElement.localName === 'app-single-auto-complete') { + return (Array.from(formControl.nativeElement.firstChild.children).filter((x: any) => x.localName === 'input')[0] as any).getAttribute('placeholder'); + } else if (formControl.nativeElement.localName === 'app-multiple-auto-complete') { + return (Array.from(formControl.nativeElement.firstChild.firstChild.firstChild.children).filter((x: any) => x.localName === 'input')[0] as any).getAttribute('placeholder'); + } + } + + filterProfiles(value: string): Observable { + const request = new DataTableRequest(null, null, { fields: ['+label'] }); + const criteria = new DatasetProfileCriteria(); + criteria.like = value; + request.criteria = criteria; + return this.dmpService.searchDMPProfiles(request); + } + + registerFormEventsForDmpBlueprint(): void { + this.formGroup.get('profile').valueChanges + .pipe( + takeUntil(this._destroyed)) + .subscribe(Option => { + if (Option instanceof Object) { + this.selectedDmpBlueprintDefinition = Option.definition; + } + else { + this.selectedDmpBlueprintDefinition = null; + } + }) + } + + dmpBlueprintAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { + filterFn: this.dmpBlueprintSearch.bind(this), + initialItems: (extraData) => this.dmpBlueprintSearch(''), + displayFn: (item) => item['label'], + titleFn: (item) => item['label'] + }; + + dmpBlueprintSearch(query: string) { + let fields: Array = new Array(); + var request = new DataTableRequest(0, 10, { fields: fields }); + request.criteria = new DmpBlueprintCriteria(); + return this.dmpProfileService.getPagedBlueprint(request).pipe(map(x => x.data)); + } + + getLanguageInfos(): LanguageInfo[] { + return this.languageInfoService.getLanguageInfoValues(); + } + + getAssociates(): UserModel[] { + let associates: UserModel[]; + if (this.formGroup.get('associatedUsers').value && this.formGroup.get('associatedUsers').value.length > 0) { + associates = []; + } else { + associates = this.associates; + } + //associates = (this.formGroup.get('researchers').value as any[]); + associates = associates.concat(this.formGroup.get('associatedUsers').value); + return associates; + } + + organisationsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = { + filterFn: this.filterOrganisations.bind(this), + initialItems: (excludedItems: any[]) => this.filterOrganisations('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['name'], + titleFn: (item) => item['name'], + subtitleFn: (item) => item['tag'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['tag'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE')) + }; + researchersAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = { + filterFn: this.filterResearchers.bind(this), + initialItems: (excludedItems: any[]) => this.filterResearchers('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['name'], + titleFn: (item) => item['name'], + subtitleFn: (item) => item['tag'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['tag'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE')) + }; + + // Researchers + filterResearchers(value: string): Observable { + return this.externalSourcesService.searchDMPResearchers({ criteria: { name: value, like: null } }); + } + + addResearcher(event: MouseEvent) { + event.stopPropagation(); + const dialogRef = this.dialog.open(AddResearcherComponent, { + data: this.formGroup.get('researchers') + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + const fullName = result.firstName + " " + result.lastName; + const newItem = { + label: null, + name: fullName, + id: null, + status: 0, + key: "Internal", + reference: result.reference + }; + const researchersArray = this.formGroup.get('researchers').value || []; + researchersArray.push(newItem); + this.formGroup.get('researchers').setValue(researchersArray); + } + }); + } + + // Organizations + showOrganizationCreator(): boolean { + return this.configurationService.allowOrganizationCreator; + } + + filterOrganisations(value: string): Observable { + return this.organizationService.searchGeneralOrganisations({ criteria: { labelLike: value } }); + } + + cantAddOrganizations(): boolean { + if (!isNullOrUndefined(this.formGroup.get('organizations'))) { + return this.formGroup.get('organiztions').disabled; + } else { + return false; + } + } + + addOrganization(event: MouseEvent) { + event.stopPropagation(); + const dialogRef = this.dialog.open(AddOrganizationComponent, { + data: this.formGroup.get('organisations') + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + const fullName = result.name; + const newItem = { + label: null, + name: fullName, + id: null, + status: 0, + key: "Internal", + reference: result.reference + }; + const organizationsArray = this.formGroup.get('organisations').value || []; + organizationsArray.push(newItem); + this.formGroup.get('organisations').setValue(organizationsArray); + } + }); + } + + showToggleButton() { + return (!this.isFinalized && this.isUserOwner) || this.isClone; + } + + licenseSearch(query: string): Observable { + const request = new RequestItem(); + request.criteria = new LicenseCriteria(); + request.criteria.like = query; + request.criteria.type = ''; + return this.externalSourcesService.searchLicense(request); + } + + allAvailableProfiles(event: MouseEvent) { + event.stopPropagation(); + const dialogRef = this.dialog.open(AvailableProfilesComponent, { + data: { + profiles: this.formGroup.get('profiles') + } + }); + + return false; + } + + onRemoveTemplate(event) { + let found = false; + const profiles = this.formGroup.get('profiles').value; + this.formGroup.get('datasets')['controls'].forEach(element => { + if (element.get('profile').value.id === event.id) { + found = true; + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-REMOVE-TEMPLATE'), SnackBarNotificationLevel.Success); + } + }); + if (found) { + this.formGroup.get('profiles').setValue(profiles); + this.profilesAutoCompleteConfiguration = { + filterFn: this.filterProfiles.bind(this), + initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['label'], + titleFn: (item) => item['label'], + subtitleFn: (item) => item['description'], + popupItemActionIcon: 'visibility' + }; + + } + } + + onPreviewTemplate(event) { + const dialogRef = this.dialog.open(DatasetPreviewDialogComponent, { + width: '590px', + minHeight: '200px', + restoreFocus: false, + data: { + template: event + }, + panelClass: 'custom-modalbox' + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + let profiles = this.formGroup.get('profiles').value; + profiles.push(event); + this.formGroup.get('profiles').setValue(profiles); + this.profilesAutoCompleteConfiguration = { + filterFn: this.filterProfiles.bind(this), + initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['label'], + titleFn: (item) => item['label'], + subtitleFn: (item) => item['description'], + popupItemActionIcon: 'visibility' + }; + } + }); + } + onOptionSelected(){ + try{ + const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[]; + const profileCounts: Map = new Map(); + profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id): 0 ) + 1)); + const duplicateProfiles = profiles.filter((value) => { + let isOk = profileCounts.get(value.id) > 1; + if (isOk) { + profileCounts.set(value.id, 0); + } + return isOk; + }); + duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1)); + profiles.sort((a,b)=> a.label.localeCompare(b.label)); + }catch{ + console.info('Could not sort Dataset Templates') + } + } + +} diff --git a/dmp-frontend/src/app/ui/dmp/dmp.module.ts b/dmp-frontend/src/app/ui/dmp/dmp.module.ts index d6060d4b1..be42b903d 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp.module.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp.module.ts @@ -57,6 +57,7 @@ import { } from '../misc/dataset-description-form/components/form-progress-indication/form-progress-indication.module'; import {DatasetPreviewDialogComponent} from './dataset-preview/dataset-preview-dialog.component'; import {RichTextEditorModule} from "@app/library/rich-text-editor/rich-text-editor.module"; +import { DmpEditorBlueprintComponent } from './dmp-editor-blueprint/dmp-editor-blueprint.component'; @NgModule({ imports: [ @@ -110,7 +111,8 @@ import {RichTextEditorModule} from "@app/library/rich-text-editor/rich-text-edit FundingInfoComponent, DatasetInfoComponent, LicenseInfoComponent, - DatasetPreviewDialogComponent + DatasetPreviewDialogComponent, + DmpEditorBlueprintComponent ], entryComponents: [ DmpInvitationDialogComponent, diff --git a/dmp-frontend/src/app/ui/dmp/dmp.routing.ts b/dmp-frontend/src/app/ui/dmp/dmp.routing.ts index 26295c3c0..3f1ea17b8 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp.routing.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp.routing.ts @@ -8,6 +8,7 @@ import { DmpOverviewComponent } from './overview/dmp-overview.component'; import { DmpCloneComponent } from './clone/dmp-clone.component'; import { AuthGuard } from '@app/core/auth-guard.service'; import { CanDeactivateGuard } from '@app/library/deactivate/can-deactivate.guard'; +import { DmpEditorBlueprintComponent } from './dmp-editor-blueprint/dmp-editor-blueprint.component'; const routes: Routes = [ { @@ -74,9 +75,19 @@ const routes: Routes = [ // breadcrumbs: 'new' // } // }, + // { + // path: 'new', + // component: DmpEditorComponent, + // canActivate: [AuthGuard], + // data: { + // breadcrumbs: 'new', + // title: 'GENERAL.TITLES.DMP-NEW' + // }, + // canDeactivate:[CanDeactivateGuard] + // }, { path: 'new', - component: DmpEditorComponent, + component: DmpEditorBlueprintComponent, canActivate: [AuthGuard], data: { breadcrumbs: 'new', diff --git a/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.html b/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.html index 7dfd317d6..2582589cc 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.html @@ -1,19 +1,19 @@
    -
    + -
    + +
    {{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}
    {{'DMP-EDITOR.FIELDS.FUNDER-HINT' | translate}}
    info {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}
    -
    -
    +
    --> +
    @@ -38,31 +38,32 @@ {{'GENERAL.VALIDATION.REQUIRED' | translate}}
    -
    - -
    -
    -
    - {{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.ACTIONS.EXIST-FUNDER' | translate}} -
    -
    - {{'DMP-EDITOR.FUNDING-INFO.FIND' | translate}} - {{'DMP-EDITOR.ACTIONS.INSERT-MANUALLY' | translate}} + +
    +
    +
    + {{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.ACTIONS.EXIST-FUNDER' | translate}} +
    +
    + {{'DMP-EDITOR.FUNDING-INFO.FIND' | translate}} + {{'DMP-EDITOR.ACTIONS.INSERT-MANUALLY' | translate}} +
    -
    -
    + + -
    + +
    {{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}
    {{'DMP-EDITOR.FIELDS.GRANTS-HINT' | translate}}
    info {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}
    -
    -
    +
    --> +
    @@ -107,18 +108,18 @@
    -
    - + -
    + +
    {{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}
    {{'DMP-EDITOR.FIELDS.PROJECT-HINT' | translate}}
    info {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}
    -
    -
    +
    --> +
    @@ -162,9 +163,9 @@
    - - - + + diff --git a/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.ts b/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.ts index 72ba47c11..e06095ce6 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.ts @@ -28,6 +28,8 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { @Input() isClone: boolean = false; @Input() isNewVersion: boolean; + @Input() type: number; + @Input() formGroup: FormGroup; @Input() grantformGroup: FormGroup; @Input() projectFormGroup: FormGroup; @@ -71,7 +73,7 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { return ''; } - ngOnInit() { + ngOnInit() { const grantRequestItem: RequestItem = new RequestItem(); grantRequestItem.criteria = new GrantCriteria(); diff --git a/dmp-frontend/src/app/ui/misc/navigation/navigation.component.html b/dmp-frontend/src/app/ui/misc/navigation/navigation.component.html index bd512164c..937ccc065 100644 --- a/dmp-frontend/src/app/ui/misc/navigation/navigation.component.html +++ b/dmp-frontend/src/app/ui/misc/navigation/navigation.component.html @@ -11,7 +11,7 @@ {{'NAV-BAR.DMPS' | translate}} {{'NAV-BAR.DATASETS' | translate}} {{'NAV-BAR.USERS' | translate}} - {{'NAV-BAR.DMP-PROFILES' | + {{'NAV-BAR.DMP-BLUEPRINTS' | translate}} {{'NAV-BAR.DATASETS-ADMIN' | translate}} diff --git a/dmp-frontend/src/app/ui/navbar/navbar.component.html b/dmp-frontend/src/app/ui/navbar/navbar.component.html index 0c9b6c9b9..5d8f62fd5 100644 --- a/dmp-frontend/src/app/ui/navbar/navbar.component.html +++ b/dmp-frontend/src/app/ui/navbar/navbar.component.html @@ -101,7 +101,7 @@ From e01709f886c3eeeb03e417350d0b02833da20c88 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Thu, 27 Jul 2023 10:06:04 +0300 Subject: [PATCH 032/110] #8936 - fix bug when pid of object fetched was integer(PIC typed) instead of string --- .../eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java index 20c57356d..6b703ed15 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java @@ -70,7 +70,13 @@ public class RemoteFetcherUtils { Object pidObj = stringObjectMap.get(value.split("\\.")[0]); if(pidObj != null){ if(pidObj instanceof Map){ - pid = ((Map) pidObj).get(value.split("\\.")[1]); + Object o = ((Map) pidObj).get(value.split("\\.")[1]); + if(o instanceof String){ + pid = (String)o; + } + else if(o instanceof Integer){ + pid = String.valueOf(o); + } } else if(pidObj instanceof List){ Object o = ((List>) pidObj).get(0).get(value.split("\\.")[1]); From 634d49ea3573eac081f742e4154ac7ff46d7926d Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Thu, 27 Jul 2023 10:07:40 +0300 Subject: [PATCH 033/110] #8916 - when merging acoounts, save the main profile user as collaborator to elastic dmps/datasets --- .../MergeEmailConfirmationManager.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java index 8a30c6acb..5b9e1bb2c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java @@ -5,6 +5,10 @@ import eu.eudat.data.entities.EmailConfirmation; import eu.eudat.data.entities.UserDMP; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserToken; +import eu.eudat.elastic.criteria.DmpCriteria; +import eu.eudat.elastic.entities.Collaborator; +import eu.eudat.elastic.entities.Dmp; +import eu.eudat.elastic.repository.DmpRepository; import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException; import eu.eudat.exceptions.emailconfirmation.TokenExpiredException; import eu.eudat.logic.services.ApiContext; @@ -25,17 +29,21 @@ import com.fasterxml.jackson.databind.ObjectMapper; import javax.transaction.Transactional; import java.io.IOException; import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; @Component public class MergeEmailConfirmationManager { private static Logger logger = LoggerFactory.getLogger(MergeEmailConfirmationManager.class); private ApiContext apiContext; private DatabaseRepository databaseRepository; + private DmpRepository dmpRepository; @Autowired public MergeEmailConfirmationManager(ApiContext apiContext) { this.apiContext = apiContext; this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); + this.dmpRepository = apiContext.getOperationsContext().getElasticRepository().getDmpRepository(); } @Transactional @@ -91,6 +99,38 @@ public class MergeEmailConfirmationManager { userDmp.setUser(newUser); databaseRepository.getUserDmpDao().createOrUpdate(userDmp); }); + try { + DmpCriteria dmpCriteria = new DmpCriteria(); + dmpCriteria.setCollaborators(Collections.singletonList(oldUser.getId())); + List elasticDmpsIds = dmpRepository.query(dmpCriteria); + for(Dmp dmpId: elasticDmpsIds){ + Dmp dmp = dmpRepository.findDocument(dmpId.getId().toString()); + if(dmp.getDatasets() != null) { + dmp.getDatasets().forEach(dataset -> { + if(dataset.getCollaborators() != null) { + for (Collaborator collaborator : dataset.getCollaborators()) { + if (collaborator.getId().equals(oldUser.getId().toString())) { + collaborator.setId(newUser.getId().toString()); + collaborator.setName(newUser.getName()); + } + } + } + }); + } + if(dmp.getCollaborators() != null) { + for (Collaborator collaborator : dmp.getCollaborators()) { + if (collaborator.getId().equals(oldUser.getId().toString())) { + collaborator.setId(newUser.getId().toString()); + collaborator.setName(newUser.getName()); + } + } + } + dmpRepository.createOrUpdate(dmp); + } + } + catch (IOException e){ + logger.warn("Warning: Could not fetch dmps from elastic.", e); + } oldUser.setUserStatus((short)1); oldUser.setEmail(null); List credentials = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), oldUser)).toList(); From a4555f7303c295dde92cff673a7d6fefbfe5d78f Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Mon, 31 Jul 2023 16:38:20 +0300 Subject: [PATCH 034/110] Fix progress-bar for dmp editor. Fix table of contents in creation of DMP. On save of new dmp, change location instead of route. --- .../dataset-wizard/dataset-wizard.component.ts | 3 ++- .../form-progress-indication.component.ts | 6 +++--- .../tableOfContentsMaterial/table-of-contents.ts | 12 ++++++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts index 3f7210658..8f33c15d8 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts @@ -1355,7 +1355,8 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme } reloadDateset(datasetId: string) { - this.router.navigate(['/datasets', 'edit', datasetId]); + let url = this.router.createUrlTree(['/datasets', 'edit', datasetId]).toString(); + this.location.go(url); } backToDmp(id: string) { diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts index b42dc86b8..732b71e8d 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts @@ -48,7 +48,7 @@ export class FormProgressIndicationComponent extends BaseComponent implements On this.total = this.countFormControlsRequiredFieldsForTotal(this.formGroup); } else if (this.isDatasetEditor) { this.progressSoFar = this.countFormControlsValidForProgress(this.formGroup) + this.countFormControlsWithValueForProgress(this.formGroup); - this.total = this.countFormControlsRequiredFieldsForTotal(this.formGroup) + this.CountFormControlDepthLengthFotTotal(this.formGroup); + this.total = this.countFormControlsRequiredFieldsForTotal(this.formGroup, true) + this.CountFormControlDepthLengthFotTotal(this.formGroup); } else { this.progressSoFar = this.countFormControlsWithValueForProgress(this.formGroup); this.total = this.CountFormControlDepthLengthFotTotal(this.formGroup); @@ -169,14 +169,14 @@ export class FormProgressIndicationComponent extends BaseComponent implements On return valueCurrent; } - countFormControlsRequiredFieldsForTotal(formControl: AbstractControl): number { + countFormControlsRequiredFieldsForTotal(formControl: AbstractControl, checkVisibility = false): number { let valueCurrent = 0; if (formControl instanceof FormControl) { if (this.controlRequired(formControl) && this.controlEnabled(formControl)) { valueCurrent++; } } else if (formControl instanceof FormGroup) { - if(!formControl.get('id')?.value || this.visibilityRulesService.checkElementVisibility(formControl.get('id').value)) { + if(!checkVisibility || (!formControl.get('id')?.value || this.visibilityRulesService.checkElementVisibility(formControl.get('id').value))) { Object.keys(formControl.controls).forEach(item => { const control = formControl.get(item); valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(control); diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts index 44c1dd3fa..7188b965c 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts @@ -57,6 +57,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges @Input() selectedFieldsetId:string; private _tocentrySelected:ToCEntry = null; + private isSelecting: boolean = false; private _intersectionObserver: IntersectionObserver; private _actOnObservation: boolean = true; public hiddenEntries:string[] = []; @@ -442,8 +443,14 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges } onToCentrySelected(entry: ToCEntry = null, execute: boolean = true){ - this.tocentrySelected = entry; - this.entrySelected.emit({entry: entry, execute: execute}); + if(!this.isSelecting) { + this.isSelecting = true; + this.tocentrySelected = entry; + this.entrySelected.emit({entry: entry, execute: execute}); + setTimeout(() => { + this.isSelecting = false; + }, 200); + } } private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{ @@ -496,6 +503,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges return this.tocentries.some(e => this.internalTable.invalidChildsVisible(e)); } + protected readonly console = console; } export interface LinkToScroll { From 30abe4d4c9bc18c2c0cf1038a9829302485112ed Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Tue, 1 Aug 2023 11:23:06 +0300 Subject: [PATCH 035/110] #8952 - fix bug when merging two accounts did not have consistent behaviour. --- .../eu/eudat/controllers/EmailMergeConfirmation.java | 10 +++++----- .../logic/managers/MergeEmailConfirmationManager.java | 6 ++++-- .../src/app/core/services/auth/auth.service.ts | 2 +- .../merge-email-confirmation.component.ts | 10 +++++++++- dmp-frontend/src/assets/i18n/de.json | 3 ++- dmp-frontend/src/assets/i18n/en.json | 3 ++- dmp-frontend/src/assets/i18n/es.json | 3 ++- dmp-frontend/src/assets/i18n/gr.json | 3 ++- dmp-frontend/src/assets/i18n/hr.json | 3 ++- dmp-frontend/src/assets/i18n/pl.json | 3 ++- dmp-frontend/src/assets/i18n/pt.json | 3 ++- dmp-frontend/src/assets/i18n/sk.json | 3 ++- dmp-frontend/src/assets/i18n/sr.json | 3 ++- dmp-frontend/src/assets/i18n/tr.json | 3 ++- 14 files changed, 39 insertions(+), 19 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/EmailMergeConfirmation.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/EmailMergeConfirmation.java index d1e89b493..96f959078 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/EmailMergeConfirmation.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/EmailMergeConfirmation.java @@ -32,16 +32,16 @@ public class EmailMergeConfirmation { @Transactional @RequestMapping(method = RequestMethod.GET, value = {"/{emailToken}"}) public @ResponseBody - ResponseEntity emailConfirmation(@PathVariable(value = "emailToken") String token) { + ResponseEntity> emailConfirmation(@PathVariable(value = "emailToken") String token) { try { - this.emailConfirmationManager.confirmEmail(token); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); + String emailToBeMerged = this.emailConfirmationManager.confirmEmail(token); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(emailToBeMerged).status(ApiMessageCode.SUCCESS_MESSAGE)); } catch (HasConfirmedEmailException | TokenExpiredException ex) { if (ex instanceof TokenExpiredException) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); } else { - return ResponseEntity.status(HttpStatus.FOUND).body(new ResponseItem().status(ApiMessageCode.WARN_MESSAGE)); + return ResponseEntity.status(HttpStatus.FOUND).body(new ResponseItem().status(ApiMessageCode.WARN_MESSAGE)); } } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java index 5b9e1bb2c..4a6b0ac56 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java @@ -47,7 +47,7 @@ public class MergeEmailConfirmationManager { } @Transactional - public void confirmEmail(String token) throws TokenExpiredException, HasConfirmedEmailException { + public String confirmEmail(String token) throws TokenExpiredException, HasConfirmedEmailException { EmailConfirmation loginConfirmationEmail = apiContext.getOperationsContext() .getDatabaseRepository().getLoginConfirmationEmailDao().asQueryable() .where((builder, root) -> builder.equal(root.get("token"), UUID.fromString(token))).getSingle(); @@ -57,7 +57,7 @@ public class MergeEmailConfirmationManager { UserInfo userToBeMerged = databaseRepository.getUserInfoDao().asQueryable() .where((builder, root) -> builder.equal(root.get("id"), loginConfirmationEmail.getUserId())).getSingle(); - + String userToBeMergedEmail = userToBeMerged.getEmail(); try { Map map = new ObjectMapper().readValue(loginConfirmationEmail.getData(), HashMap.class); UUID otherUserId = UUID.fromString((String) map.get("userId")); @@ -72,6 +72,8 @@ public class MergeEmailConfirmationManager { } catch (Exception e) { logger.error(e.getMessage(), e); } + + return userToBeMergedEmail; } public void sendConfirmationEmail(String email, Principal principal, UUID userId, Integer provider) throws HasConfirmedEmailException { diff --git a/dmp-frontend/src/app/core/services/auth/auth.service.ts b/dmp-frontend/src/app/core/services/auth/auth.service.ts index b921df883..53355056d 100644 --- a/dmp-frontend/src/app/core/services/auth/auth.service.ts +++ b/dmp-frontend/src/app/core/services/auth/auth.service.ts @@ -38,7 +38,7 @@ export class AuthService extends BaseService { this.headers = this.headers.set('Accept', 'application/json'); } - private clear(): void { + public clear(): void { localStorage.removeItem('principal'); } diff --git a/dmp-frontend/src/app/ui/auth/login/merge-email-confirmation/merge-email-confirmation.component.ts b/dmp-frontend/src/app/ui/auth/login/merge-email-confirmation/merge-email-confirmation.component.ts index e11f9b1d9..dbff4c3d4 100644 --- a/dmp-frontend/src/app/ui/auth/login/merge-email-confirmation/merge-email-confirmation.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/merge-email-confirmation/merge-email-confirmation.component.ts @@ -1,6 +1,7 @@ import { Component, OnInit } from "@angular/core"; import { FormControl } from '@angular/forms'; import { ActivatedRoute, Router } from "@angular/router"; +import { AuthService } from "@app/core/services/auth/auth.service"; import { EmailConfirmationService } from '@app/core/services/email-confirmation/email-confirmation.service'; import { MergeEmailConfirmationService } from '@app/core/services/merge-email-confirmation/merge-email-confirmation.service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; @@ -20,6 +21,7 @@ export class MergeEmailConfirmation extends BaseComponent implements OnInit { constructor( private emailConfirmationService: MergeEmailConfirmationService, + private authService: AuthService, private route: ActivatedRoute, private router: Router, private language: TranslateService, @@ -36,7 +38,13 @@ export class MergeEmailConfirmation extends BaseComponent implements OnInit { this.emailConfirmationService.emailConfirmation(token) .pipe(takeUntil(this._destroyed)) .subscribe( - result => this.onCallbackEmailConfirmationSuccess(), + result => { + const principal = this.authService.current(); + if(!principal || !result || (principal.email == result)) + this.authService.clear(); + this.uiNotificationService.snackBarNotification(this.language.instant('USER-PROFILE.MERGING-SUCCESS'), SnackBarNotificationLevel.Success); + this.onCallbackEmailConfirmationSuccess(); + }, error => this.onCallbackError(error) ) } else { diff --git a/dmp-frontend/src/assets/i18n/de.json b/dmp-frontend/src/assets/i18n/de.json index 392e4bf0a..06d9ed19b 100644 --- a/dmp-frontend/src/assets/i18n/de.json +++ b/dmp-frontend/src/assets/i18n/de.json @@ -1687,13 +1687,14 @@ "LOG-OUT": "Abmeldung" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index a608c8ca0..b23e12d74 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -1687,13 +1687,14 @@ "LOG-OUT": "Log Out" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", diff --git a/dmp-frontend/src/assets/i18n/es.json b/dmp-frontend/src/assets/i18n/es.json index b970ca792..ac0e52f8d 100644 --- a/dmp-frontend/src/assets/i18n/es.json +++ b/dmp-frontend/src/assets/i18n/es.json @@ -1687,13 +1687,14 @@ "LOG-OUT": "Cerrar la sesión" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", diff --git a/dmp-frontend/src/assets/i18n/gr.json b/dmp-frontend/src/assets/i18n/gr.json index e1846708d..3eac2f970 100644 --- a/dmp-frontend/src/assets/i18n/gr.json +++ b/dmp-frontend/src/assets/i18n/gr.json @@ -1687,13 +1687,14 @@ "LOG-OUT": "Αποσύνδεση" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", diff --git a/dmp-frontend/src/assets/i18n/hr.json b/dmp-frontend/src/assets/i18n/hr.json index 8328c3b4a..f9833d476 100644 --- a/dmp-frontend/src/assets/i18n/hr.json +++ b/dmp-frontend/src/assets/i18n/hr.json @@ -1687,13 +1687,14 @@ "LOG-OUT": "Odjava" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Potvrdi povezani korisnički račun", "MESSAGE": "Potvrdu za ovu radnju poslali smo Vam putem elektroničke pošte. Kada potvrdite, korisnički računi biti će povezani. Posljednji račun elektroničke pošte koji povežete biti će onaj koji sadrži sve podatke o Planu upravljanja podacima i aktivnostima u {{ APP_NAME }}u." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", diff --git a/dmp-frontend/src/assets/i18n/pl.json b/dmp-frontend/src/assets/i18n/pl.json index bf8762b7d..5a29a4c1c 100644 --- a/dmp-frontend/src/assets/i18n/pl.json +++ b/dmp-frontend/src/assets/i18n/pl.json @@ -1687,13 +1687,14 @@ "LOG-OUT": "Wyloguj" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Zweryfikuj połączone konto", "MESSAGE": "Wysłano wiadomość e-mail w celu weryfikacji tej akcji. Po zaakceptowaniu będzie można zobaczyć połączone konta. Ostatnie połączone konto e-mail będzie tym, które zawiera wszystkie twoje rejestry DMP i aktywność w {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", diff --git a/dmp-frontend/src/assets/i18n/pt.json b/dmp-frontend/src/assets/i18n/pt.json index 2373b0288..86ed84324 100644 --- a/dmp-frontend/src/assets/i18n/pt.json +++ b/dmp-frontend/src/assets/i18n/pt.json @@ -1687,13 +1687,14 @@ "LOG-OUT": "Terminar Sessão" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", diff --git a/dmp-frontend/src/assets/i18n/sk.json b/dmp-frontend/src/assets/i18n/sk.json index 0c8415251..00f2823f7 100644 --- a/dmp-frontend/src/assets/i18n/sk.json +++ b/dmp-frontend/src/assets/i18n/sk.json @@ -1687,13 +1687,14 @@ "LOG-OUT": "Odhlásiť sa" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", diff --git a/dmp-frontend/src/assets/i18n/sr.json b/dmp-frontend/src/assets/i18n/sr.json index 8904496f7..0dc21c855 100644 --- a/dmp-frontend/src/assets/i18n/sr.json +++ b/dmp-frontend/src/assets/i18n/sr.json @@ -1687,13 +1687,14 @@ "LOG-OUT": "Odjavite se" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", diff --git a/dmp-frontend/src/assets/i18n/tr.json b/dmp-frontend/src/assets/i18n/tr.json index 6e360736f..955d887e9 100644 --- a/dmp-frontend/src/assets/i18n/tr.json +++ b/dmp-frontend/src/assets/i18n/tr.json @@ -1687,13 +1687,14 @@ "LOG-OUT": "Çıkış Yap" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", From 903026e2c2732d773022d9af7d20cf77961be29d Mon Sep 17 00:00:00 2001 From: Diamantis Tziotzios Date: Thu, 3 Aug 2023 10:28:18 +0300 Subject: [PATCH 036/110] metrics change --- .../main/java/eu/eudat/controllers/AboutController.java | 7 ------- .../src/main/java/eu/eudat/controllers/FaqController.java | 7 ------- .../main/java/eu/eudat/controllers/GlossaryController.java | 7 ------- .../eu/eudat/controllers/TermsOfServiceController.java | 7 ------- .../java/eu/eudat/controllers/UserGuideController.java | 7 ------- .../main/java/eu/eudat/logic/managers/MetricsManager.java | 2 ++ 6 files changed, 2 insertions(+), 35 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java index b0bf85aea..729c8cd05 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java @@ -22,22 +22,15 @@ public class AboutController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public AboutController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getAbout(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("about.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("about.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java index 0aa9ff078..5badd7959 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java @@ -21,22 +21,15 @@ public class FaqController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public FaqController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getFaq(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("faq.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("faq.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java index f46e0f4f0..5e6a783bd 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java @@ -21,22 +21,15 @@ public class GlossaryController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public GlossaryController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getGlossary(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("glossary.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("glossary.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java index d9d015193..2875f6c07 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java @@ -21,22 +21,15 @@ public class TermsOfServiceController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public TermsOfServiceController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getTermsOfService(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("termsofservice.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("termsofservice.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java index f513238cf..cd7cb9dae 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java @@ -34,22 +34,15 @@ public class UserGuideController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public UserGuideController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getUserGuide(@PathVariable(name = "lang") String lang) throws IOException { - long files = 0; - try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("userguide.path"))))) { - files = paths.count(); - } - metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("userguide.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java index ba691c1fc..2aacc8cc3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java @@ -180,6 +180,8 @@ public class MetricsManager { try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("userguide.path"))))) { long files = paths.count(); calculateValue(MetricNames.LANGUAGES, (int) files, null); + } catch (Exception e) { + logger.error("Could not calculate languages."); } calculateValue(MetricNames.INSTALLATIONS, 1, null); From b6cade6e88afeef56d030b76da448fe5b9fcae29 Mon Sep 17 00:00:00 2001 From: Diamantis Tziotzios Date: Thu, 3 Aug 2023 10:28:18 +0300 Subject: [PATCH 037/110] metrics change (cherry picked from commit 903026e2c2732d773022d9af7d20cf77961be29d) --- .../main/java/eu/eudat/controllers/AboutController.java | 7 ------- .../src/main/java/eu/eudat/controllers/FaqController.java | 7 ------- .../main/java/eu/eudat/controllers/GlossaryController.java | 7 ------- .../eu/eudat/controllers/TermsOfServiceController.java | 7 ------- .../java/eu/eudat/controllers/UserGuideController.java | 7 ------- .../main/java/eu/eudat/logic/managers/MetricsManager.java | 2 ++ 6 files changed, 2 insertions(+), 35 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java index b0bf85aea..729c8cd05 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java @@ -22,22 +22,15 @@ public class AboutController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public AboutController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getAbout(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("about.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("about.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java index 0aa9ff078..5badd7959 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java @@ -21,22 +21,15 @@ public class FaqController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public FaqController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getFaq(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("faq.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("faq.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java index f46e0f4f0..5e6a783bd 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java @@ -21,22 +21,15 @@ public class GlossaryController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public GlossaryController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getGlossary(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("glossary.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("glossary.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java index d9d015193..2875f6c07 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java @@ -21,22 +21,15 @@ public class TermsOfServiceController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public TermsOfServiceController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getTermsOfService(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("termsofservice.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("termsofservice.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java index f513238cf..cd7cb9dae 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java @@ -34,22 +34,15 @@ public class UserGuideController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public UserGuideController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getUserGuide(@PathVariable(name = "lang") String lang) throws IOException { - long files = 0; - try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("userguide.path"))))) { - files = paths.count(); - } - metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("userguide.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java index b39aebd6d..256956605 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java @@ -180,6 +180,8 @@ public class MetricsManager { try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("userguide.path"))))) { long files = paths.count(); calculateValue(MetricNames.LANGUAGES, (int) files, null); + } catch (Exception e) { + logger.error("Could not calculate languages."); } calculateValue(MetricNames.INSTALLATIONS, 1, null); From b94aa514898807eac47b56102fe94068bc8c1073 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Thu, 3 Aug 2023 11:19:33 +0300 Subject: [PATCH 038/110] change images source in emails to base64 --- .../eu/eudat/logic/services/utilities/MailServiceImpl.java | 7 +++++-- .../main/resources/templates/email/emailConfirmation.html | 2 +- .../resources/templates/email/emailMergeConfirmation.html | 2 +- .../resources/templates/email/emailUnlinkConfirmation.html | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java index 3f73d4996..cde1f885a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java @@ -108,8 +108,11 @@ public class MailServiceImpl implements MailService { lastIndex = content.indexOf("img src=\"", lastIndex); if (lastIndex != -1) { - imagePaths.add(content.substring(lastIndex + 9, content.indexOf("\"", lastIndex + 9))); - lastIndex ++; + String imagePath = content.substring(lastIndex + 9, content.indexOf("\"", lastIndex + 9)); + if (!imagePath.contains("data:image/png;base64")) { + imagePaths.add(imagePath); + } + lastIndex++; } } diff --git a/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html b/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html index a83e48013..3d46fc62d 100644 --- a/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html +++ b/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html @@ -260,7 +260,7 @@
    - OpenDMP + OpenDMP

    Thank you for joining OpenDMP!

    Please confirm that your email address is correct to continue.
    The link will expire in {expiration_time}.

    diff --git a/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html b/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html index 6d5fea269..01f0536d6 100644 --- a/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html +++ b/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html @@ -260,7 +260,7 @@
    - OpenDMP + OpenDMP

    User {userName} have sent you a merge Request.

    Please confirm that you want to merge your {host} account with that account.
    The link will expire in {expiration_time}.

    diff --git a/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html b/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html index 7f6ce7c8d..ee547f813 100644 --- a/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html +++ b/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html @@ -260,7 +260,7 @@
    - OpenDMP + OpenDMP

    You have made a request to unlink your email account in ARGOS.

    Please confirm that you want to unlink your {email} account.
    The link will expire in {expiration_time}.

    From 17dbd198ad0da75ba3b6bb32e836613e34a1c614 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Thu, 3 Aug 2023 13:10:36 +0300 Subject: [PATCH 039/110] fix dmp blueprint editor screen --- .../dmpprofiledefinition/FieldModel.java | 127 +++++++++ .../dmpprofiledefinition/Section.java | 37 ++- .../types/FieldCategory.java | 27 ++ .../model/dmp/dmp-blueprint/dmp-blueprint.ts | 23 +- .../admin/dmp-profile/dmp-profile.module.ts | 4 +- .../editor/dmp-blueprint-editor.model.ts | 89 ++++--- .../editor/dmp-profile-editor.component.html | 245 ++++++++++-------- .../editor/dmp-profile-editor.component.scss | 6 +- .../editor/dmp-profile-editor.component.ts | 81 ++++-- .../dmp-editor-blueprint.component.html | 21 +- .../dmp-editor-blueprint.component.scss | 11 + 11 files changed, 461 insertions(+), 210 deletions(-) create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/FieldModel.java create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/FieldCategory.java diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/FieldModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/FieldModel.java new file mode 100644 index 000000000..b311d005f --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/FieldModel.java @@ -0,0 +1,127 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.ExtraFieldType; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.SystemFieldType; + +import java.util.UUID; + +public class FieldModel { + + private UUID id; + private FieldCategory category; + private Integer type; + private String label; + private String placeholder; + private String description; + private Integer ordinal; + private boolean required; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public FieldCategory getCategory() { + return category; + } + public void setCategory(FieldCategory category) { + this.category = category; + } + + public Integer getType() { + return type; + } + public void setType(Integer type) { + this.type = type; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public String getPlaceholder() { + return placeholder; + } + public void setPlaceholder(String placeholder) { + this.placeholder = placeholder; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public Integer getOrdinal() { + return ordinal; + } + public void setOrdinal(Integer ordinal) { + this.ordinal = ordinal; + } + + public boolean isRequired() { + return required; + } + public void setRequired(boolean required) { + this.required = required; + } + + public SystemField toSystemField(){ + SystemField systemField = new SystemField(); + if (this.category == FieldCategory.SYSTEM) { + systemField.setId(this.id); + systemField.setType(SystemFieldType.fromInteger(this.type)); + systemField.setLabel(this.label); + systemField.setPlaceholder(this.placeholder); + systemField.setDescription(this.description); + systemField.setOrdinal(this.ordinal); + systemField.setRequired(this.required); + } + return systemField; + } + + public FieldModel fromSystemField(SystemField systemField){ + this.setId(systemField.getId()); + this.setCategory(FieldCategory.SYSTEM); + this.setType(systemField.getType().getType()); + this.setLabel(systemField.getLabel()); + this.setPlaceholder(systemField.getPlaceholder()); + this.setDescription(systemField.getDescription()); + this.setOrdinal(systemField.getOrdinal()); + this.setRequired(systemField.isRequired()); + return this; + } + + public ExtraField toExtraField(){ + ExtraField extraField = new ExtraField(); + if (this.category == FieldCategory.EXTRA) { + extraField.setId(this.id); + extraField.setType(ExtraFieldType.fromInteger(this.type)); + extraField.setLabel(this.label); + extraField.setPlaceholder(this.placeholder); + extraField.setDescription(this.description); + extraField.setOrdinal(this.ordinal); + extraField.setRequired(this.required); + } + return extraField; + } + + public FieldModel fromExtraField(ExtraField extraField){ + this.setId(extraField.getId()); + this.setCategory(FieldCategory.EXTRA); + this.setType(extraField.getType().getValue()); + this.setLabel(extraField.getLabel()); + this.setPlaceholder(extraField.getPlaceholder()); + this.setDescription(extraField.getDescription()); + this.setOrdinal(extraField.getOrdinal()); + this.setRequired(extraField.getRequired()); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/Section.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/Section.java index 2ed95c937..bcb128653 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/Section.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/Section.java @@ -2,6 +2,7 @@ package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.logic.utilities.interfaces.XmlSerializable; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -10,6 +11,7 @@ import org.w3c.dom.NodeList; import java.util.LinkedList; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; public class Section implements XmlSerializable
    { @@ -17,9 +19,8 @@ public class Section implements XmlSerializable
    { private String label; private String description; private Integer ordinal; - private List systemFields; + private List fields; private List descriptionTemplates; - private List extraFields; public UUID getId() { return id; @@ -49,11 +50,11 @@ public class Section implements XmlSerializable
    { this.ordinal = ordinal; } - public List getSystemFields() { - return systemFields; + public List getFields() { + return fields; } - public void setSystemFields(List systemFields) { - this.systemFields = systemFields; + public void setFields(List fields) { + this.fields = fields; } public List getDescriptionTemplates() { @@ -63,13 +64,6 @@ public class Section implements XmlSerializable
    { this.descriptionTemplates = descriptionTemplates; } - public List getExtraFields() { - return extraFields; - } - public void setExtraFields(List extraFields) { - this.extraFields = extraFields; - } - @Override public Element toXml(Document doc) { Element rootElement = doc.createElement("section"); @@ -77,8 +71,10 @@ public class Section implements XmlSerializable
    { rootElement.setAttribute("label", this.label); rootElement.setAttribute("description", this.description); rootElement.setAttribute("ordinal", String.valueOf(this.ordinal)); + List temp = this.fields.stream().filter(f -> f.getCategory().equals(FieldCategory.SYSTEM)).collect(Collectors.toList()); + List systemFieldsList = temp.stream().map(FieldModel::toSystemField).collect(Collectors.toList()); Element systemFields = doc.createElement("systemFields"); - for (SystemField systemField : this.systemFields) { + for (SystemField systemField : systemFieldsList) { systemFields.appendChild(systemField.toXml(doc)); } rootElement.appendChild(systemFields); @@ -87,8 +83,10 @@ public class Section implements XmlSerializable
    { descriptionTemplates.appendChild(descriptionTemplate.toXml(doc)); } rootElement.appendChild(descriptionTemplates); + temp = this.fields.stream().filter(f -> f.getCategory().equals(FieldCategory.EXTRA)).collect(Collectors.toList()); + List extraFieldList = temp.stream().map(FieldModel::toExtraField).collect(Collectors.toList()); Element extraFields = doc.createElement("extraFields"); - for (ExtraField extraField : this.extraFields) { + for (ExtraField extraField : extraFieldList) { extraFields.appendChild(extraField.toXml(doc)); } rootElement.appendChild(extraFields); @@ -102,14 +100,15 @@ public class Section implements XmlSerializable
    { this.label = item.getAttribute("label"); this.description = item.getAttribute("description"); this.ordinal = Integer.valueOf(item.getAttribute("ordinal")); - this.systemFields = new LinkedList<>(); + this.fields = new LinkedList<>(); Element systemFields = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "systemFields"); if (systemFields != null) { NodeList systemFieldElements = systemFields.getChildNodes(); for (int temp = 0; temp < systemFieldElements.getLength(); temp++) { Node systemFieldElement = systemFieldElements.item(temp); if (systemFieldElement.getNodeType() == Node.ELEMENT_NODE) { - this.systemFields.add(new SystemField().fromXml((Element) systemFieldElement)); + SystemField systemField = new SystemField().fromXml((Element) systemFieldElement); + this.fields.add(new FieldModel().fromSystemField(systemField)); } } } @@ -124,14 +123,14 @@ public class Section implements XmlSerializable
    { } } } - this.extraFields = new LinkedList<>(); Element extraFields = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "extraFields"); if (extraFields != null) { NodeList extraFieldElements = extraFields.getChildNodes(); for (int temp = 0; temp < extraFieldElements.getLength(); temp++) { Node extraFieldElement = extraFieldElements.item(temp); if (extraFieldElement.getNodeType() == Node.ELEMENT_NODE) { - this.extraFields.add(new ExtraField().fromXml((Element) extraFieldElement)); + ExtraField extraField = new ExtraField().fromXml((Element) extraFieldElement); + this.fields.add(new FieldModel().fromExtraField(extraField)); } } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/FieldCategory.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/FieldCategory.java new file mode 100644 index 000000000..cec77366d --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/FieldCategory.java @@ -0,0 +1,27 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types; + +public enum FieldCategory { + SYSTEM(0), + EXTRA(1); + + private Integer value; + + private FieldCategory(Integer value) { + this.value = value; + } + + public Integer getValue() { + return value; + } + + public static FieldCategory fromInteger(Integer value) { + switch (value) { + case 0: + return SYSTEM; + case 1: + return EXTRA; + default: + throw new RuntimeException("Unsupported FieldCategory Type"); + } + } +} diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint.ts b/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint.ts index 5f25b8875..d9f4f4f36 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint.ts @@ -17,14 +17,14 @@ export interface SectionDmpBlueprint { label: string; description: string; ordinal: number; - systemFields: SystemFieldInSection[]; + fields: FieldInSection[]; descriptionTemplates?: DescriptionTemplatesInSection[]; - extraFields?: ExtraFieldInSection[]; } -export interface SystemFieldInSection { +export interface FieldInSection { id: string; - type: SystemFieldType; + category: FieldCategory; + type: number; label: string; placeholder: string; description: string; @@ -32,6 +32,11 @@ export interface SystemFieldInSection { ordinal: number; } +export enum FieldCategory { + SYSTEM = 0, + EXTRA = 1 +} + export enum SystemFieldType { TEXT = 0, HTML_TEXT = 1, @@ -54,16 +59,6 @@ export interface DescriptionTemplatesInSection { maxMultiplicity: number; } -export interface ExtraFieldInSection { - id: string; - label: string; - description: string; - placeholder: string; - type: ExtraFieldType; - required: boolean; - ordinal: number; -} - export enum ExtraFieldType { TEXT = 0, RICH_TEXT = 1, diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.module.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.module.ts index 5059a98b0..f85a1a0d3 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.module.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.module.ts @@ -10,6 +10,7 @@ import { DialodConfirmationUploadDmpProfiles } from './listing/criteria/dialog-c import { DmpProfileCriteriaComponent } from './listing/criteria/dmp-profile-criteria.component'; import { DmpProfileListingComponent } from './listing/dmp-profile-listing.component'; import { NgxDropzoneModule } from "ngx-dropzone"; +import { DragDropModule } from '@angular/cdk/drag-drop'; @NgModule({ imports: [ @@ -18,7 +19,8 @@ import { NgxDropzoneModule } from "ngx-dropzone"; UrlListingModule, ConfirmationDialogModule, DmpProfileRoutingModule, - NgxDropzoneModule + NgxDropzoneModule, + DragDropModule ], declarations: [ DmpProfileEditorComponent, diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model.ts index fb7c3e3d0..a2ad7e5f2 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model.ts @@ -1,5 +1,5 @@ import { FormBuilder, FormGroup } from "@angular/forms"; -import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, ExtraFieldInSection, ExtraFieldType, SectionDmpBlueprint, SystemFieldInSection, SystemFieldType } from "@app/core/model/dmp/dmp-blueprint/dmp-blueprint"; +import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, FieldCategory, FieldInSection, SectionDmpBlueprint } from "@app/core/model/dmp/dmp-blueprint/dmp-blueprint"; export class DmpBlueprintEditor { public id: string; @@ -60,7 +60,7 @@ export class SectionDmpBlueprintEditor { public label: string; public description: string; public ordinal: number; - public systemFields: SystemFieldInSectionEditor[] = new Array(); + public fields: FieldInSectionEditor[] = new Array(); public descriptionTemplates: DescriptionTemplatesInSectionEditor[] = new Array(); fromModel(item: SectionDmpBlueprint): SectionDmpBlueprintEditor { @@ -68,9 +68,8 @@ export class SectionDmpBlueprintEditor { this.label = item.label; this.description = item.description; this.ordinal = item.ordinal; - if (item.systemFields) { item.systemFields.map(x => this.systemFields.push(new SystemFieldInSectionEditor().fromModel(x))); } + if (item.fields) { item.fields.map(x => this.fields.push(new FieldInSectionEditor().fromModel(x))); } if (item.descriptionTemplates) { item.descriptionTemplates.map(x => this.descriptionTemplates.push(new DescriptionTemplatesInSectionEditor().fromModel(x))); } - debugger; return this; } @@ -82,12 +81,12 @@ export class SectionDmpBlueprintEditor { ordinal: [this.ordinal] }); const formBuilder = new FormBuilder(); - const systemFieldsFormArray = new Array(); - this.systemFields.forEach(item => { + const fieldsFormArray = new Array(); + this.fields.forEach(item => { const form: FormGroup = item.buildForm(); - systemFieldsFormArray.push(form); + fieldsFormArray.push(form); }); - formGroup.addControl('systemFields', formBuilder.array(systemFieldsFormArray)); + formGroup.addControl('fields', formBuilder.array(fieldsFormArray)); const descriptionTemplatesFormArray = new Array(); this.descriptionTemplates.forEach(item => { const form: FormGroup = item.buildForm(); @@ -98,17 +97,21 @@ export class SectionDmpBlueprintEditor { } } -export class SystemFieldInSectionEditor { +export class FieldInSectionEditor { public id: string; - public type: SystemFieldType; + public category: FieldCategory; + public type: number; + public label: string; public placeholder: string; public description: string; public required: boolean; public ordinal: number; - fromModel(item: SystemFieldInSection): SystemFieldInSectionEditor { + fromModel(item: FieldInSection): FieldInSectionEditor { this.id = item.id; + this.category = item.category; this.type = item.type; + this.label = item.label; this.placeholder = item.placeholder; this.description = item.description; this.required = item.required; @@ -119,7 +122,9 @@ export class SystemFieldInSectionEditor { buildForm(): FormGroup { const formGroup = new FormBuilder().group({ id: [this.id], + category: [this.category], type: [this.type], + label: [this.label], placeholder: [this.placeholder], description: [this.description], required: [this.required], @@ -157,36 +162,36 @@ export class DescriptionTemplatesInSectionEditor { } } -export class ExtraFieldsInSectionEditor { - public id: string; - public label: string; - public description: string; - public placeholder: string; - public type: ExtraFieldType; - public required: boolean; - public ordinal: number; +// export class ExtraFieldsInSectionEditor { +// public id: string; +// public label: string; +// public description: string; +// public placeholder: string; +// public type: ExtraFieldType; +// public required: boolean; +// public ordinal: number; - fromModel(item: ExtraFieldInSection): ExtraFieldsInSectionEditor { - this.id = item.id; - this.label = item.label; - this.description = item.description; - this.placeholder = item.placeholder; - this.type = item.type; - this.required = item.required; - this.ordinal = item.ordinal; - return this; - } +// fromModel(item: ExtraFieldInSection): ExtraFieldsInSectionEditor { +// this.id = item.id; +// this.label = item.label; +// this.description = item.description; +// this.placeholder = item.placeholder; +// this.type = item.type; +// this.required = item.required; +// this.ordinal = item.ordinal; +// return this; +// } - buildForm(): FormGroup { - const formGroup = new FormBuilder().group({ - id: [this.id], - label: [this.label], - description: [this.description], - placeholder: [this.placeholder], - type: [this.type], - required: [this.required], - ordinal: [this.ordinal] - }); - return formGroup; - } -} \ No newline at end of file +// buildForm(): FormGroup { +// const formGroup = new FormBuilder().group({ +// id: [this.id], +// label: [this.label], +// description: [this.description], +// placeholder: [this.placeholder], +// type: [this.type], +// required: [this.required], +// ordinal: [this.ordinal] +// }); +// return formGroup; +// } +// } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html index 1c09aeac8..09ec4be95 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html @@ -33,22 +33,23 @@ -->
    - - + + Name + {{'GENERAL.VALIDATION.REQUIRED' | translate}}

    Sections

    - -
    +
    +
    - + Section {{sectionIndex + 1}} + drag_indicator
    @@ -73,122 +74,158 @@
    +
    - - System fields - - {{f.label}} - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - +
    +
    + + System fields + + {{f.label}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
    +
    + + +
    +
    + +
    + +
    +
    + +
    +
    +
    +
    +
    + {{fieldIndex + 1}} +
    +
    + drag_indicator +
    +
    +
    + +
    + + System Field + + +
    +
    + + Label + + +
    +
    + + Placeholder + + +
    +
    + + Description + + +
    +
    + Required +
    +
    + delete + {{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} +
    +
    + + +
    + + Type + + + {{getExtraFieldTypeValue(extraFieldType)}} + + + +
    +
    + + Label + + +
    +
    + + Placeholder + + +
    +
    + + Description + + +
    +
    + + Required + +
    +
    + delete + {{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} +
    +
    + +
    +
    +
    +
    +
    + +
    + + + + + +
    +
    +
    - -
    - -
    - -
    -
    - - System Field - - -
    -
    - - Label - - -
    -
    - - Placeholder - - -
    -
    - - Description - - -
    - -
    - -
    -
    -
    -
    - - -
    -
    - - - Label - - - - Description - - - - Type - - - {{getExtraFieldTypeValue(extraFieldType)}} - - - -
    - - Required - -
    -
    - delete - {{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    + - + - +
    - +
    diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss index 9313e4bc8..6cc8ea3a0 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss @@ -102,18 +102,18 @@ } } -.extra-field-delete{ +.field-delete{ align-items: center; display: flex; cursor: pointer; - .extra-field-delete-icon{ + .field-delete-icon{ font-size: 1.2em; width: 14px; color: var(--primary-color); } - .extra-field-delete-text{ + .field-delete-text{ font-size: 1em; margin-left: 0.5em; color: var(--primary-color); diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts index f4f3498ae..b8cf5cd85 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts @@ -32,10 +32,11 @@ import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset- import { DmpService } from '@app/core/services/dmp/dmp.service'; import { AvailableProfilesComponent } from '@app/ui/dmp/editor/available-profiles/available-profiles.component'; import { DatasetPreviewDialogComponent } from '@app/ui/dmp/dataset-preview/dataset-preview-dialog.component'; -import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; -import { DmpBlueprint, DmpBlueprintDefinition, ExtraFieldType, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { CdkDragDrop, CdkDropList, CdkDrag, moveItemInArray } from '@angular/cdk/drag-drop'; +import { DmpBlueprint, DmpBlueprintDefinition, ExtraFieldType, FieldCategory, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; import { DmpBlueprintEditor } from './dmp-blueprint-editor.model'; import { Guid } from '@common/types/guid'; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; @Component({ @@ -172,10 +173,11 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie label: this.fb.control(''), description: this.fb.control(''), ordinal: this.fb.control(ordinal), - systemFields: this.fb.array([]), + fields: this.fb.array([]), + //systemFields: this.fb.array([]), descriptionTemplates: this.fb.control(''), // this.fb.array([this.initDescriptionTemplate()]), - extraFields: this.fb.array([]) + //extraFields: this.fb.array([]) }); } @@ -187,6 +189,31 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie this.sectionsArray().removeAt(sectionIndex); } + fieldsArray(sectionIndex: number): FormArray { + return this.sectionsArray().at(sectionIndex).get('fields') as FormArray; + } + + initField(fieldCategory: FieldCategory, fieldType?: number): FormGroup { + return this.fb.group({ + id: this.fb.control(Guid.create().toString()), + category: this.fb.control(fieldCategory), + label: this.fb.control(''), + placeholder: this.fb.control(''), + description: this.fb.control(''), + type: (isNullOrUndefined(fieldType)) ? this.fb.control('') : this.fb.control(fieldType), + required: (!isNullOrUndefined(fieldType) && (fieldType == 0 || fieldType == 1)) ? this.fb.control(true) : this.fb.control(false), + ordinal: this.fb.control('') + }); + } + + addField(sectionIndex: number, fieldCategory: FieldCategory, fieldType?: number): void { + this.fieldsArray(sectionIndex).push(this.initField(fieldCategory, fieldType)); + } + + removeField(sectionIndex: number, fieldIndex: number): void { + this.fieldsArray(sectionIndex).removeAt(fieldIndex); + } + systemFieldsArray(sectionIndex: number): FormArray { return this.sectionsArray().at(sectionIndex).get('systemFields') as FormArray; } @@ -204,7 +231,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie } addSystemField(sectionIndex: number, systemField?: SystemFieldType): void { - this.systemFieldsArray(sectionIndex).push(this.initSystemField(systemField)); + this.fieldsArray(sectionIndex).push(this.initField(FieldCategory.SYSTEM, systemField)); } transfromEnumToString(type: SystemFieldType): string{ @@ -227,8 +254,8 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie let i = 0; for (let s in this.sectionsArray().controls) { if (i != sectionIndex) { - for (let f of this.systemFieldsArray(i).controls) { - if (f.get('type').value == systemField) { + for (let f of this.fieldsArray(i).controls) { + if (f.get('category').value == FieldCategory.SYSTEM && f.get('type').value == systemField) { return true; } } @@ -239,14 +266,14 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie } removeSystemFieldWithIndex(sectionIndex: number, fieldIndex: number): void { - this.systemFieldsArray(sectionIndex).removeAt(fieldIndex); + this.fieldsArray(sectionIndex).removeAt(fieldIndex); } removeSystemField(sectionIndex: number, systemField: SystemFieldType): void { let i = 0; - for(let sf of this.systemFieldsArray(sectionIndex).controls){ - if(sf.get('type').value == systemField){ - this.systemFieldsArray(sectionIndex).removeAt(i); + for(let f of this.fieldsArray(sectionIndex).controls){ + if(f.get('category').value == FieldCategory.SYSTEM && f.get('type').value == systemField){ + this.fieldsArray(sectionIndex).removeAt(i); return; } i++; @@ -293,11 +320,11 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie } addExtraField(sectionIndex: number): void { - this.extraFieldsArray(sectionIndex).push(this.initExtraField()); + this.fieldsArray(sectionIndex).push(this.initField(FieldCategory.EXTRA)); } - removeExtraField(sectionIndex: number, extraFieldIndex: number): void { - this.extraFieldsArray(sectionIndex).removeAt(extraFieldIndex); + removeExtraField(sectionIndex: number, fieldIndex: number): void { + this.fieldsArray(sectionIndex).removeAt(fieldIndex); } getExtraFieldTypes(): Number[] { @@ -319,12 +346,14 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie onSubmitTest(): void { } - drop(event: CdkDragDrop) { - this.moveItemInFormArray( - this.systemFieldsArray(0), - event.previousIndex, - event.currentIndex - ); + drop(event: CdkDragDrop, sectionIndex: number) { + moveItemInArray(this.fieldsArray(sectionIndex).controls, event.previousIndex, event.currentIndex); + moveItemInArray(this.fieldsArray(sectionIndex).value, event.previousIndex, event.currentIndex); + } + + dropSections(event: CdkDragDrop) { + moveItemInArray(this.sectionsArray().controls, event.previousIndex, event.currentIndex); + moveItemInArray(this.sectionsArray().value, event.previousIndex, event.currentIndex); } moveItemInFormArray(formArray: FormArray, fromIndex: number, toIndex: number): void { @@ -458,13 +487,13 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie this.router.navigate(['/dmp-profiles']); } - addField() { - (this.formGroup.get('definition').get('fields')).push(new DmpProfileFieldEditorModel().buildForm()); - } + // addField() { + // (this.formGroup.get('definition').get('fields')).push(new DmpProfileFieldEditorModel().buildForm()); + // } - removeField(index: number) { - (this.formGroup.get('definition').get('fields')).controls.splice(index, 1); - } + // removeField(index: number) { + // (this.formGroup.get('definition').get('fields')).controls.splice(index, 1); + // } getDMPProfileFieldDataTypeValues(): Number[] { let keys: string[] = Object.keys(DmpProfileFieldDataType); diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html index 7c356d557..34735967d 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html @@ -65,8 +65,27 @@
    -
    +
    +
    0.1 Title of DMP *
    + Title + + + +
    +
    +
    0.2 Description of DMP *
    + + +
    +
    +
    0.3 Blueprint of DMP *
    + + Select blueprint diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss index a6be61a3c..027268655 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss @@ -368,6 +368,17 @@ a:hover { } } +.heading2 { + text-align: left; + font-weight: 700; + font-size: 18px; + letter-spacing: 0px; + color: #212121; + opacity: 0.81; + margin-top: 1.625rem; + margin-bottom: 0.625rem; +} + ::ng-deep .input-form .mat-form-field-appearance-outline .mat-form-field-outline { background: #fafafa !important; } From 655483b8e2f01d9faf5845771c5d60805acbc9bb Mon Sep 17 00:00:00 2001 From: "k.triantafyllou" Date: Thu, 3 Aug 2023 13:11:19 +0300 Subject: [PATCH 040/110] Dateset Edtitor: Scroll to top in Main info. Add checkVisibility in recursion of progress bar status calculation. Increase time of selected entry in tableofcontents --- .../app/ui/dataset/dataset-wizard/dataset-wizard.component.ts | 1 + .../form-progress-indication.component.ts | 4 ++-- .../tableOfContentsMaterial/table-of-contents.ts | 2 +- dmp-frontend/src/assets/config/config.json | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts index 8f33c15d8..7e6de2aa8 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts @@ -1239,6 +1239,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme this.step = index + (selected.type === ToCEntryType.FieldSet?1:0.5); } else { this.step = 0; + this.resetScroll(); } } } diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts index 732b71e8d..dd3cfa289 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts @@ -179,12 +179,12 @@ export class FormProgressIndicationComponent extends BaseComponent implements On if(!checkVisibility || (!formControl.get('id')?.value || this.visibilityRulesService.checkElementVisibility(formControl.get('id').value))) { Object.keys(formControl.controls).forEach(item => { const control = formControl.get(item); - valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(control); + valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(control, checkVisibility); }); } } else if (formControl instanceof FormArray) { formControl.controls.forEach(item => { - valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(item); + valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(item, checkVisibility); }); } return valueCurrent; diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts index 7188b965c..cfdeffefa 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts @@ -449,7 +449,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges this.entrySelected.emit({entry: entry, execute: execute}); setTimeout(() => { this.isSelecting = false; - }, 200); + }, 600); } } diff --git a/dmp-frontend/src/assets/config/config.json b/dmp-frontend/src/assets/config/config.json index 3b2190325..87c1adf67 100644 --- a/dmp-frontend/src/assets/config/config.json +++ b/dmp-frontend/src/assets/config/config.json @@ -53,7 +53,7 @@ "loginProviders": { "enabled": [1, 2, 3, 4, 5, 6, 7, 8], "facebookConfiguration": { "clientId": "" }, - "googleConfiguration": { "clientId": "" }, + "googleConfiguration": { "clientId": "524432312250-sc9qsmtmbvlv05r44onl6l93ia3k9deo.apps.googleusercontent.com" }, "linkedInConfiguration": { "clientId": "", "oauthUrl": "https://www.linkedin.com/oauth/v2/authorization", From 78946de1b5e63b7fbcff3b1c870a5bc6c29d2903 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Thu, 3 Aug 2023 11:19:33 +0300 Subject: [PATCH 041/110] change images source in emails to base64 (cherry picked from commit b94aa514898807eac47b56102fe94068bc8c1073) --- .../eu/eudat/logic/services/utilities/MailServiceImpl.java | 7 +++++-- .../main/resources/templates/email/emailConfirmation.html | 2 +- .../resources/templates/email/emailMergeConfirmation.html | 2 +- .../resources/templates/email/emailUnlinkConfirmation.html | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java index 3f73d4996..cde1f885a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java @@ -108,8 +108,11 @@ public class MailServiceImpl implements MailService { lastIndex = content.indexOf("img src=\"", lastIndex); if (lastIndex != -1) { - imagePaths.add(content.substring(lastIndex + 9, content.indexOf("\"", lastIndex + 9))); - lastIndex ++; + String imagePath = content.substring(lastIndex + 9, content.indexOf("\"", lastIndex + 9)); + if (!imagePath.contains("data:image/png;base64")) { + imagePaths.add(imagePath); + } + lastIndex++; } } diff --git a/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html b/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html index a83e48013..3d46fc62d 100644 --- a/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html +++ b/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html @@ -260,7 +260,7 @@
    - OpenDMP + OpenDMP

    Thank you for joining OpenDMP!

    Please confirm that your email address is correct to continue.
    The link will expire in {expiration_time}.

    diff --git a/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html b/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html index 6d5fea269..01f0536d6 100644 --- a/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html +++ b/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html @@ -260,7 +260,7 @@
    - OpenDMP + OpenDMP

    User {userName} have sent you a merge Request.

    Please confirm that you want to merge your {host} account with that account.
    The link will expire in {expiration_time}.

    diff --git a/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html b/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html index 7f6ce7c8d..ee547f813 100644 --- a/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html +++ b/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html @@ -260,7 +260,7 @@
    - OpenDMP + OpenDMP

    You have made a request to unlink your email account in ARGOS.

    Please confirm that you want to unlink your {email} account.
    The link will expire in {expiration_time}.

    From 3b76397c24f17680e4e402e803863355f6565568 Mon Sep 17 00:00:00 2001 From: Diamantis Tziotzios Date: Thu, 3 Aug 2023 13:27:01 +0300 Subject: [PATCH 042/110] conf cleanup --- dmp-frontend/src/assets/config/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmp-frontend/src/assets/config/config.json b/dmp-frontend/src/assets/config/config.json index 87c1adf67..3b2190325 100644 --- a/dmp-frontend/src/assets/config/config.json +++ b/dmp-frontend/src/assets/config/config.json @@ -53,7 +53,7 @@ "loginProviders": { "enabled": [1, 2, 3, 4, 5, 6, 7, 8], "facebookConfiguration": { "clientId": "" }, - "googleConfiguration": { "clientId": "524432312250-sc9qsmtmbvlv05r44onl6l93ia3k9deo.apps.googleusercontent.com" }, + "googleConfiguration": { "clientId": "" }, "linkedInConfiguration": { "clientId": "", "oauthUrl": "https://www.linkedin.com/oauth/v2/authorization", From 3564cc16ff042451f13c35ac0c23b5c7c1bc051d Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Thu, 3 Aug 2023 17:07:35 +0300 Subject: [PATCH 043/110] update i18n - link new --- dmp-frontend/src/assets/i18n/de.json | 2 +- dmp-frontend/src/assets/i18n/en.json | 2 +- dmp-frontend/src/assets/i18n/es.json | 2 +- dmp-frontend/src/assets/i18n/gr.json | 2 +- dmp-frontend/src/assets/i18n/hr.json | 2 +- dmp-frontend/src/assets/i18n/pl.json | 2 +- dmp-frontend/src/assets/i18n/pt.json | 2 +- dmp-frontend/src/assets/i18n/sk.json | 2 +- dmp-frontend/src/assets/i18n/sr.json | 2 +- dmp-frontend/src/assets/i18n/tr.json | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dmp-frontend/src/assets/i18n/de.json b/dmp-frontend/src/assets/i18n/de.json index 392e4bf0a..87eaa675b 100644 --- a/dmp-frontend/src/assets/i18n/de.json +++ b/dmp-frontend/src/assets/i18n/de.json @@ -1745,7 +1745,7 @@ }, "ACTIONS": { "SAVE": "Save", - "LINK-NEW": "Link new", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Link new account", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 228e900f1..e8a8b7b74 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -1772,7 +1772,7 @@ }, "ACTIONS": { "SAVE": "Save", - "LINK-NEW": "Link new", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Link new account", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/es.json b/dmp-frontend/src/assets/i18n/es.json index b970ca792..4e627d694 100644 --- a/dmp-frontend/src/assets/i18n/es.json +++ b/dmp-frontend/src/assets/i18n/es.json @@ -1745,7 +1745,7 @@ }, "ACTIONS": { "SAVE": "Grabar", - "LINK-NEW": "Nuevo enlace", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Enlazar nueva cuenta", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/gr.json b/dmp-frontend/src/assets/i18n/gr.json index e1846708d..82e469b84 100644 --- a/dmp-frontend/src/assets/i18n/gr.json +++ b/dmp-frontend/src/assets/i18n/gr.json @@ -1745,7 +1745,7 @@ }, "ACTIONS": { "SAVE": "Save", - "LINK-NEW": "Link new", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Link new account", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/hr.json b/dmp-frontend/src/assets/i18n/hr.json index 8328c3b4a..8a8693fa6 100644 --- a/dmp-frontend/src/assets/i18n/hr.json +++ b/dmp-frontend/src/assets/i18n/hr.json @@ -1745,7 +1745,7 @@ }, "ACTIONS": { "SAVE": "Spremi", - "LINK-NEW": "Poveži novo", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Poveži novi korisnički račun", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/pl.json b/dmp-frontend/src/assets/i18n/pl.json index bf8762b7d..50be46810 100644 --- a/dmp-frontend/src/assets/i18n/pl.json +++ b/dmp-frontend/src/assets/i18n/pl.json @@ -1745,7 +1745,7 @@ }, "ACTIONS": { "SAVE": "Zapisz", - "LINK-NEW": "Połącz nowy", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Połącz nowe konto", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/pt.json b/dmp-frontend/src/assets/i18n/pt.json index 2373b0288..472d0a973 100644 --- a/dmp-frontend/src/assets/i18n/pt.json +++ b/dmp-frontend/src/assets/i18n/pt.json @@ -1745,7 +1745,7 @@ }, "ACTIONS": { "SAVE": "Guardar", - "LINK-NEW": "Ligar a nova(o)", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Ligar a nova conta", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/sk.json b/dmp-frontend/src/assets/i18n/sk.json index 0c8415251..c6790764b 100644 --- a/dmp-frontend/src/assets/i18n/sk.json +++ b/dmp-frontend/src/assets/i18n/sk.json @@ -1745,7 +1745,7 @@ }, "ACTIONS": { "SAVE": "Save", - "LINK-NEW": "Link new", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Link new account", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/sr.json b/dmp-frontend/src/assets/i18n/sr.json index 8904496f7..fa5278c76 100644 --- a/dmp-frontend/src/assets/i18n/sr.json +++ b/dmp-frontend/src/assets/i18n/sr.json @@ -1745,7 +1745,7 @@ }, "ACTIONS": { "SAVE": "Save", - "LINK-NEW": "Link new", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Link new account", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/tr.json b/dmp-frontend/src/assets/i18n/tr.json index 6e360736f..b7c2b3790 100644 --- a/dmp-frontend/src/assets/i18n/tr.json +++ b/dmp-frontend/src/assets/i18n/tr.json @@ -1745,7 +1745,7 @@ }, "ACTIONS": { "SAVE": "Kaydet", - "LINK-NEW": "Yeni bağlantı", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Yeni hesabı bağla", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", From 5019bc4271114fac1065451dcabdeb2400c29595 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Fri, 4 Aug 2023 11:55:46 +0300 Subject: [PATCH 044/110] Add manual addition of total users in prometheus --- .../authentication/AbstractAuthenticationService.java | 9 +++++++-- .../NonVerifiedUserEmailAuthenticationService.java | 5 +++-- .../VerifiedUserAuthenticationService.java | 5 +++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java index 2983bfa1d..34ab8a8b4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java @@ -8,12 +8,14 @@ import eu.eudat.exceptions.security.NullEmailException; import eu.eudat.logic.builders.entity.CredentialBuilder; import eu.eudat.logic.builders.entity.UserInfoBuilder; import eu.eudat.logic.builders.entity.UserTokenBuilder; +import eu.eudat.logic.managers.MetricsManager; import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.login.Credentials; import eu.eudat.models.data.loginprovider.LoginProviderUser; import eu.eudat.models.data.security.Principal; import eu.eudat.types.Authorities; +import eu.eudat.types.MetricNames; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,10 +32,12 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer protected ApiContext apiContext; protected Environment environment; + protected MetricsManager metricsManager; - public AbstractAuthenticationService(ApiContext apiContext, Environment environment) { + public AbstractAuthenticationService(ApiContext apiContext, Environment environment, MetricsManager metricsManager) { this.apiContext = apiContext; this.environment = environment; + this.metricsManager = metricsManager; } protected Date addADay(Date date) { @@ -91,6 +95,7 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer if (credential == null && credentials.getUsername().equals(environment.getProperty("autouser.root.username"))) { try { credential = this.autoCreateUser(credentials.getUsername(), credentials.getSecret()); + metricsManager.increaseValue(MetricNames.USERS, 1, MetricNames.TOTAL); } catch (Exception e) { logger.error(e.getMessage(), e); return null; @@ -162,7 +167,7 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer role.setRole(Authorities.USER.getValue()); role.setUserInfo(userInfo); apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().createOrUpdate(role); - + metricsManager.increaseValue(MetricNames.USERS, 1, MetricNames.TOTAL); } else { Map additionalInfo = userInfo.getAdditionalinfo() != null ? new JSONObject(userInfo.getAdditionalinfo()).toMap() : new HashMap<>(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java index 34fa80dc9..166188736 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java @@ -5,6 +5,7 @@ import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserRole; import eu.eudat.data.entities.UserToken; import eu.eudat.logic.builders.model.models.PrincipalBuilder; +import eu.eudat.logic.managers.MetricsManager; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.security.Principal; import eu.eudat.types.Authorities; @@ -19,8 +20,8 @@ import java.util.List; @Service("nonVerifiedUserAuthenticationService") public class NonVerifiedUserEmailAuthenticationService extends AbstractAuthenticationService { - public NonVerifiedUserEmailAuthenticationService(ApiContext apiContext, Environment environment) { - super(apiContext, environment); + public NonVerifiedUserEmailAuthenticationService(ApiContext apiContext, Environment environment, MetricsManager metricsManager) { + super(apiContext, environment, metricsManager); } public Principal Touch(UserToken token) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java index dfaca0d7a..4912346c4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java @@ -10,6 +10,7 @@ import eu.eudat.logic.builders.entity.CredentialBuilder; import eu.eudat.logic.builders.entity.UserInfoBuilder; import eu.eudat.logic.builders.entity.UserTokenBuilder; import eu.eudat.logic.builders.model.models.PrincipalBuilder; +import eu.eudat.logic.managers.MetricsManager; import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.login.Credentials; @@ -27,8 +28,8 @@ import java.util.*; @Service("verifiedUserAuthenticationService") public class VerifiedUserAuthenticationService extends AbstractAuthenticationService { - public VerifiedUserAuthenticationService(ApiContext apiContext, Environment environment) { - super(apiContext, environment); + public VerifiedUserAuthenticationService(ApiContext apiContext, Environment environment, MetricsManager metricsManager) { + super(apiContext, environment, metricsManager); } public Principal Touch(UserToken token) { From cd80e78e4071fc6f92d401ae2e4f466b9c0f444d Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Mon, 11 Sep 2023 08:40:03 +0300 Subject: [PATCH 045/110] add status to description template types, fix bugs in editor/listing --- .../DescriptionTemplateTypeDaoImpl.java | 10 +- .../entities/DescriptionTemplateType.java | 37 ++++++ .../DescriptionTemplateTypeController.java | 50 +++++-- .../DescriptionTemplateTypeManager.java | 51 ++++++-- .../DescriptionTemplateTypeModel.java | 56 ++++++++ dmp-db-scema/main/data-dump.sql | 2 +- dmp-db-scema/main/dmp-dump.sql | 3 +- ...13_Add_Description_Template_Type_table.sql | 1 + ...ame_DatasetProfile_and_add_Type_column.sql | 4 +- .../enum/description-template-type-status.ts | 5 + .../description-template-type.ts | 1 + .../description-template-type.service.ts | 12 +- .../dataset-profile-editor.component.ts | 3 +- .../description-types.module.ts | 2 + .../description-type-editor.component.html | 4 +- .../description-type-editor.component.ts | 122 ++++++++++++++---- .../listing/description-types.component.html | 6 +- .../listing/description-types.component.ts | 107 +++++++-------- dmp-frontend/src/assets/i18n/en.json | 5 + 19 files changed, 367 insertions(+), 114 deletions(-) create mode 100644 dmp-backend/web/src/main/java/eu/eudat/models/data/descriptiontemplatetype/DescriptionTemplateTypeModel.java create mode 100644 dmp-frontend/src/app/core/common/enum/description-template-type-status.ts diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDaoImpl.java index 2f0cac2f2..f93afb383 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDaoImpl.java @@ -3,7 +3,6 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccess; import eu.eudat.data.dao.databaselayer.service.DatabaseService; import eu.eudat.data.entities.DescriptionTemplateType; -import eu.eudat.data.entities.EntityDoi; import eu.eudat.queryable.QueryableList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; @@ -23,7 +22,12 @@ public class DescriptionTemplateTypeDaoImpl extends DatabaseAccess builder.equal(root.get("name"), name)).getSingle(); + try { + return this.getDatabaseService().getQueryable(DescriptionTemplateType.class).where((builder, root) -> builder.equal(root.get("name"), name)).getSingle(); + } + catch(Exception e){ + return null; + } } @Override @@ -44,7 +48,7 @@ public class DescriptionTemplateTypeDaoImpl extends DatabaseAccess asQueryable() { - return this.getDatabaseService().getQueryable(DescriptionTemplateType.class); + return this.getDatabaseService().getQueryable(DescriptionTemplateType.class).where((builder, root) -> builder.notEqual((root.get("status")), DescriptionTemplateType.Status.DELETED.getValue())); } @Async diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplateType.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplateType.java index e4d8d6257..40a755c2f 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplateType.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplateType.java @@ -11,6 +11,32 @@ import java.util.UUID; @Table(name = "\"DescriptionTemplateType\"") public class DescriptionTemplateType implements DataEntity { + public enum Status { + SAVED((short) 0), FINALIZED((short) 1), DELETED((short) 99); + + private short value; + + private Status(short value) { + this.value = value; + } + public short getValue() { + return value; + } + + public static Status fromInteger(int value) { + switch (value) { + case 0: + return SAVED; + case 1: + return FINALIZED; + case 99: + return DELETED; + default: + throw new RuntimeException("Unsupported Description Template Type Status"); + } + } + } + @Id @GeneratedValue @GenericGenerator(name = "uuid2", strategy = "uuid2") @@ -20,6 +46,9 @@ public class DescriptionTemplateType implements DataEntity> createOrUpdate(@RequestBody String type, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { - this.descriptionTemplateTypeManager.create(type); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created")); + ResponseEntity> create(@RequestBody DescriptionTemplateTypeModel type, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + try { + this.descriptionTemplateTypeManager.create(type); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created")); + } + catch(DescriptionTemplatesWithTypeException e){ + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(e.getMessage())); + } + } + + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"update"}, produces = "application/json") + public @ResponseBody + ResponseEntity> update(@RequestBody DescriptionTemplateTypeModel type, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + try { + this.descriptionTemplateTypeManager.update(type); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Updated")); + } + catch(DescriptionTemplatesWithTypeException e){ + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(e.getMessage())); + } } @RequestMapping(method = RequestMethod.GET, value = {"get"}, produces = "application/json") public @ResponseBody - ResponseEntity>> get(@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { - DataTableData dataTable = this.descriptionTemplateTypeManager.get(); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); + ResponseEntity>> get(@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { + DataTableData dataTable = this.descriptionTemplateTypeManager.get(); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); + } + + @RequestMapping(method = RequestMethod.GET, value = {"get/{id}"}, produces = "application/json") + public @ResponseBody + ResponseEntity> getSingle(@PathVariable(value = "id") UUID id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { + try { + DescriptionTemplateTypeModel typeModel = this.descriptionTemplateTypeManager.getSingle(id); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(typeModel)); + } + catch(DescriptionTemplatesWithTypeException e){ + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(e.getMessage())); + } } @Transactional @RequestMapping(method = RequestMethod.DELETE, value = {"/delete/{id}"}, produces = "application/json") public @ResponseBody - ResponseEntity> delete(@PathVariable(value = "id") UUID id, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + ResponseEntity> delete(@PathVariable(value = "id") UUID id, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { try{ this.descriptionTemplateTypeManager.delete(id); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Deleted")); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Deleted")); } catch(DescriptionTemplatesWithTypeException e){ - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.UNSUCCESS_DELETE).message(e.getMessage())); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.UNSUCCESS_DELETE).message(e.getMessage())); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DescriptionTemplateTypeManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DescriptionTemplateTypeManager.java index 046c7bebd..1dda78fdb 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DescriptionTemplateTypeManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DescriptionTemplateTypeManager.java @@ -4,6 +4,7 @@ import eu.eudat.data.entities.DescriptionTemplateType; import eu.eudat.exceptions.descriptiontemplate.DescriptionTemplatesWithTypeException; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.DatabaseRepository; +import eu.eudat.models.data.descriptiontemplatetype.DescriptionTemplateTypeModel; import eu.eudat.models.data.helpers.common.DataTableData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,6 +13,7 @@ import org.springframework.stereotype.Component; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; @Component public class DescriptionTemplateTypeManager { @@ -27,31 +29,52 @@ public class DescriptionTemplateTypeManager { this.databaseRepository = databaseRepository; } - public DataTableData get() { + public DataTableData get() { List types = this.databaseRepository.getDescriptionTemplateTypeDao().asQueryable().toList(); - DataTableData dataTableData = new DataTableData<>(); - dataTableData.setData(types); - dataTableData.setTotalCount((long) types.size()); + List typesModelList = types.stream().map(type -> new DescriptionTemplateTypeModel().fromDataModel(type)).collect(Collectors.toList()); + DataTableData dataTableData = new DataTableData<>(); + dataTableData.setData(typesModelList); + dataTableData.setTotalCount((long) typesModelList.size()); return dataTableData; } - public DescriptionTemplateType create(String name) { - DescriptionTemplateType type = this.databaseRepository.getDescriptionTemplateTypeDao().findFromName(name); - if (type == null) { - type = new DescriptionTemplateType(); - type.setId(UUID.randomUUID()); - type.setName(name); - this.databaseRepository.getDescriptionTemplateTypeDao().createOrUpdate(type); + public DescriptionTemplateTypeModel getSingle(UUID id) throws Exception { + DescriptionTemplateType type = this.databaseRepository.getDescriptionTemplateTypeDao().find(id); + if (type != null) { + return new DescriptionTemplateTypeModel().fromDataModel(type); + } + else { + throw new DescriptionTemplatesWithTypeException("No description template type found with this id"); + } + } + + public void create(DescriptionTemplateTypeModel type) throws Exception { + DescriptionTemplateType existed = this.databaseRepository.getDescriptionTemplateTypeDao().findFromName(type.getName()); + if (existed == null) { + this.databaseRepository.getDescriptionTemplateTypeDao().createOrUpdate(type.toDataModel()); + } + else { + throw new DescriptionTemplatesWithTypeException("There is already a description template type with that name."); + } + } + + public void update(DescriptionTemplateTypeModel type) throws Exception { + DescriptionTemplateType existed = this.databaseRepository.getDescriptionTemplateTypeDao().findFromName(type.getName()); + if (existed != null) { + this.databaseRepository.getDescriptionTemplateTypeDao().createOrUpdate(type.toDataModel()); + } + else { + throw new DescriptionTemplatesWithTypeException("No description template type found."); } - return type; } public void delete(UUID id) throws DescriptionTemplatesWithTypeException { DescriptionTemplateType type = this.databaseRepository.getDescriptionTemplateTypeDao().find(id); if (type != null) { - Long descriptionsWithType = this.databaseRepository.getDatasetProfileDao().countWithType(type.getId()); + Long descriptionsWithType = this.databaseRepository.getDatasetProfileDao().countWithType(type); if(descriptionsWithType == 0) { - this.databaseRepository.getDescriptionTemplateTypeDao().delete(type); + type.setStatus(DescriptionTemplateType.Status.DELETED.getValue()); + this.databaseRepository.getDescriptionTemplateTypeDao().createOrUpdate(type); } else{ throw new DescriptionTemplatesWithTypeException("This type can not deleted, because Descriptions are associated with it"); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/descriptiontemplatetype/DescriptionTemplateTypeModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/descriptiontemplatetype/DescriptionTemplateTypeModel.java new file mode 100644 index 000000000..272d405e1 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/descriptiontemplatetype/DescriptionTemplateTypeModel.java @@ -0,0 +1,56 @@ +package eu.eudat.models.data.descriptiontemplatetype; + +import eu.eudat.data.entities.DescriptionTemplateType; +import eu.eudat.models.DataModel; + +import java.util.UUID; + +public class DescriptionTemplateTypeModel implements DataModel { + + private UUID id; + private String name; + private short status; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public short getStatus() { + return status; + } + public void setStatus(short status) { + this.status = status; + } + + @Override + public DescriptionTemplateTypeModel fromDataModel(DescriptionTemplateType entity) { + this.id = entity.getId(); + this.name = entity.getName(); + this.status = entity.getStatus(); + return this; + } + + @Override + public DescriptionTemplateType toDataModel() throws Exception { + DescriptionTemplateType descriptionTemplateType = new DescriptionTemplateType(); + descriptionTemplateType.setId(this.id); + descriptionTemplateType.setName(this.name); + descriptionTemplateType.setStatus(this.status); + return descriptionTemplateType; + } + + @Override + public String getHint() { + return null; + } +} diff --git a/dmp-db-scema/main/data-dump.sql b/dmp-db-scema/main/data-dump.sql index df53ce588..f2c09c5d9 100644 --- a/dmp-db-scema/main/data-dump.sql +++ b/dmp-db-scema/main/data-dump.sql @@ -20,6 +20,6 @@ UPDATE public."DMP" UPDATE public."DescriptionTemplate" SET "Language"='en'; -INSERT INTO public."DescriptionTemplateType"("ID", "Name") VALUES (uuid_generate_v4(), 'Dataset'); +INSERT INTO public."DescriptionTemplateType"("ID", "Name", "Status") VALUES (uuid_generate_v4(), 'Dataset', 1); INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.007', '2020-10-27 13:40:00.000000+03', now(), 'Add userstatus on UserInfo table'); \ No newline at end of file diff --git a/dmp-db-scema/main/dmp-dump.sql b/dmp-db-scema/main/dmp-dump.sql index eb4a61049..4e09de7e5 100644 --- a/dmp-db-scema/main/dmp-dump.sql +++ b/dmp-db-scema/main/dmp-dump.sql @@ -307,7 +307,8 @@ ALTER TABLE public."DatasetExternalDataset" OWNER TO :POSTGRES_USER; CREATE TABLE public."DescriptionTemplateType" ( "ID" uuid DEFAULT public.uuid_generate_v4() NOT NULL, - "Name" character varying(250) NOT NULL + "Name" character varying(250) NOT NULL, + "Status" smallint DEFAULT 0 NOT NULL ); diff --git a/dmp-db-scema/updates/00.00.013_Add_Description_Template_Type_table.sql b/dmp-db-scema/updates/00.00.013_Add_Description_Template_Type_table.sql index 91890f9f0..2df4e63a1 100644 --- a/dmp-db-scema/updates/00.00.013_Add_Description_Template_Type_table.sql +++ b/dmp-db-scema/updates/00.00.013_Add_Description_Template_Type_table.sql @@ -9,6 +9,7 @@ CREATE TABLE public."DescriptionTemplateType" ( "ID" uuid NOT NULL, "Name" character varying(250) NOT NULL, + "Status" smallint DEFAULT 0 NOT NULL, CONSTRAINT "DescriptionTemplateType_pkey" PRIMARY KEY ("ID") ); diff --git a/dmp-db-scema/updates/00.00.014_Rename_DatasetProfile_and_add_Type_column.sql b/dmp-db-scema/updates/00.00.014_Rename_DatasetProfile_and_add_Type_column.sql index 8917c5d8c..1be73da3c 100644 --- a/dmp-db-scema/updates/00.00.014_Rename_DatasetProfile_and_add_Type_column.sql +++ b/dmp-db-scema/updates/00.00.014_Rename_DatasetProfile_and_add_Type_column.sql @@ -10,8 +10,8 @@ RENAME TO "DescriptionTemplate"; ALTER TABLE public."DescriptionTemplate" ADD COLUMN "Type" uuid; -INSERT INTO public."DescriptionTemplateType" ("ID", "Name") -VALUES ('709a8400-10ca-11ee-be56-0242ac120002', 'Dataset'); +INSERT INTO public."DescriptionTemplateType" ("ID", "Name", "Status") +VALUES ('709a8400-10ca-11ee-be56-0242ac120002', 'Dataset', 1); UPDATE public."DescriptionTemplate" SET ("Type") = '709a8400-10ca-11ee-be56-0242ac120002'; diff --git a/dmp-frontend/src/app/core/common/enum/description-template-type-status.ts b/dmp-frontend/src/app/core/common/enum/description-template-type-status.ts new file mode 100644 index 000000000..e41dc95b9 --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/description-template-type-status.ts @@ -0,0 +1,5 @@ +export enum DescriptionTemplateTypeStatus { + Draft = 0, + Finalized = 1, + Deleted = 99 +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts b/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts index 08f9df8a8..1b2812e09 100644 --- a/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts +++ b/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts @@ -1,4 +1,5 @@ export interface DescriptionTemplateType { id: string; name: string; + status: number; } \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts b/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts index dc6859f30..a40b02569 100644 --- a/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts +++ b/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts @@ -20,8 +20,16 @@ export class DescriptionTemplateTypeService { return this.http.get>(this.actionUrl + 'get', { headers: this.headers }); } - createType(name: string): Observable { - return this.http.post(this.actionUrl + 'create', name, { headers: this.headers }); + getSingle(id: string): Observable { + return this.http.get(this.actionUrl + 'get/' + id, { headers: this.headers }); + } + + createType(type: DescriptionTemplateType): Observable { + return this.http.post(this.actionUrl + 'create', type, { headers: this.headers }); + } + + updateType(type: DescriptionTemplateType): Observable { + return this.http.post(this.actionUrl + 'update', type, { headers: this.headers }); } deleteType(id: string): Observable { diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts index 7892340cc..904ab51ad 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts @@ -47,6 +47,7 @@ import { MatInput } from '@angular/material/input'; import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate.component'; import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; +import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status'; const skipDisable: any[] = require('../../../../../assets/resources/skipDisable.json'); @@ -608,7 +609,7 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent getDescriptionTemplateTypes(): DescriptionTemplateType[] { this.descriptionTemplateTypeService.getTypes().pipe(takeUntil(this._destroyed)) .subscribe(types => { - this.descriptionTemplateTypes = types.data; + this.descriptionTemplateTypes = types.data.filter(type => type.status === DescriptionTemplateTypeStatus.Finalized); }); return this.descriptionTemplateTypes; } diff --git a/dmp-frontend/src/app/ui/admin/description-types/description-types.module.ts b/dmp-frontend/src/app/ui/admin/description-types/description-types.module.ts index 1a91c9cee..2871d2c57 100644 --- a/dmp-frontend/src/app/ui/admin/description-types/description-types.module.ts +++ b/dmp-frontend/src/app/ui/admin/description-types/description-types.module.ts @@ -4,6 +4,7 @@ import { DescriptionTypesRoutingModule } from './description-types.routing'; import { DescriptionTypesComponent } from './listing/description-types.component'; import { CommonUiModule } from '@common/ui/common-ui.module'; import { DescriptionTypeEditorComponent } from './editor/description-type-editor.component'; +import { CommonFormsModule } from '@common/forms/common-forms.module'; @NgModule({ declarations: [ @@ -13,6 +14,7 @@ import { DescriptionTypeEditorComponent } from './editor/description-type-editor imports: [ CommonModule, CommonUiModule, + CommonFormsModule, DescriptionTypesRoutingModule ] }) diff --git a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.html b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.html index d55b295fc..6c818cfab 100644 --- a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.html @@ -24,7 +24,9 @@
    - +
    diff --git a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts index 118a226df..b430fc263 100644 --- a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts @@ -1,10 +1,15 @@ -import { AfterViewInit, Component } from '@angular/core'; +import { AfterViewInit, Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Router } from '@angular/router'; +import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status'; +import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { BaseComponent } from '@common/base/base.component'; import { FormService } from '@common/forms/form-service'; +import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; +import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; +import { ValidationContext } from '@common/forms/validation/validation-context'; import { TranslateService } from '@ngx-translate/core'; import { takeUntil } from 'rxjs/operators'; @@ -13,25 +18,52 @@ import { takeUntil } from 'rxjs/operators'; templateUrl: './description-type-editor.component.html', styleUrls: ['./description-type-editor.component.scss'] }) -export class DescriptionTypeEditorComponent extends BaseComponent implements AfterViewInit { +export class DescriptionTypeEditorComponent extends BaseComponent implements OnInit { formGroup: FormGroup = null; - descriptionTypeModel: DescriptionTypeEditorModel + descriptionTypeModel: DescriptionTypeEditorModel; + + isNew = true; + viewOnly = false; + descriptionTemplateTypeId: string; constructor( private descriptionTemplateTypeService: DescriptionTemplateTypeService, private formService: FormService, private uiNotificationService: UiNotificationService, private language: TranslateService, + private route: ActivatedRoute, private router: Router ) { super(); } - ngAfterViewInit(): void { - this.descriptionTypeModel = new DescriptionTypeEditorModel(); - setTimeout(() => { - this.formGroup = this.descriptionTypeModel.buildForm(); + ngOnInit(): void { + this.route.paramMap.pipe(takeUntil(this._destroyed)).subscribe((paramMap: ParamMap) => { + this.descriptionTemplateTypeId = paramMap.get('id'); + + if (this.descriptionTemplateTypeId != null) { + this.isNew = false; + this.descriptionTemplateTypeService.getSingle(this.descriptionTemplateTypeId) + .pipe(takeUntil(this._destroyed)).subscribe( + type => { + this.descriptionTypeModel = new DescriptionTypeEditorModel().fromModel(type); + if(this.descriptionTypeModel.status === DescriptionTemplateTypeStatus.Finalized){ + this.formGroup = this.descriptionTypeModel.buildForm(null, true); + this.viewOnly = true; + } + else{ + this.formGroup = this.descriptionTypeModel.buildForm(); + } + }, + error => this.uiNotificationService.snackBarNotification(error.message, SnackBarNotificationLevel.Error) + ); + } + else { + this.descriptionTypeModel = new DescriptionTypeEditorModel(); + this.descriptionTypeModel.status = DescriptionTemplateTypeStatus.Draft; + this.formGroup = this.descriptionTypeModel.buildForm(); + } }); } @@ -45,27 +77,53 @@ export class DescriptionTypeEditorComponent extends BaseComponent implements Aft return this.formGroup.valid; } - onSubmit(): void { - console.log(this.formGroup.value); - this.descriptionTemplateTypeService.createType(this.formGroup.value) - .pipe(takeUntil(this._destroyed)) - .subscribe( - complete => this.onCallbackSuccess(), - error => this.onCallbackError(error) - ); + finalize() { + this.formGroup.get('status').setValue(DescriptionTemplateTypeStatus.Finalized); + this.onSubmit(); } - onCallbackSuccess(): void { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION'), SnackBarNotificationLevel.Success); + onSubmit(): void { + if(this.isNew){ + this.descriptionTemplateTypeService.createType(this.formGroup.value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(true), + error => this.onCallbackError(error) + ); + } + else{ + this.descriptionTemplateTypeService.updateType(this.formGroup.value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(false), + error => this.onCallbackError(error) + ); + } + } + + onCallbackSuccess(creation: boolean): void { + if(creation){ + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION'), SnackBarNotificationLevel.Success); + } + else{ + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + } this.router.navigate(['/description-types']); } onCallbackError(errorResponse: any) { - // this.setErrorModel(errorResponse.error); - // this.formService.validateAllFormFields(this.formGroup); + this.setErrorModel(errorResponse.error); + this.formService.validateAllFormFields(this.formGroup); + this.uiNotificationService.snackBarNotification(errorResponse.error.message, SnackBarNotificationLevel.Error); } - public cancel(): void { + public setErrorModel(validationErrorModel: ValidationErrorModel) { + Object.keys(validationErrorModel).forEach(item => { + (this.descriptionTypeModel.validationErrorModel)[item] = (validationErrorModel)[item]; + }); + } + + public cancel(): void { this.router.navigate(['/description-types']); } @@ -74,12 +132,30 @@ export class DescriptionTypeEditorComponent extends BaseComponent implements Aft export class DescriptionTypeEditorModel { public id: string; public name: string; + public status: DescriptionTemplateTypeStatus; + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); - buildForm(): FormGroup { + fromModel(item: DescriptionTemplateType): DescriptionTypeEditorModel { + this.id = item.id; + this.name = item.name; + this.status = item.status; + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { + if (context == null) { context = this.createValidationContext(); } const formGroup = new FormBuilder().group({ id: [this.id], - name: [this.name, Validators.required], + name: [{ value: this.name, disabled: disabled }, context.getValidation('name').validators], + status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators] }); return formGroup; } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + baseContext.validation.push({ key: 'name', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'name')] }); + baseContext.validation.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] }); + return baseContext; + } } diff --git a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html index bebfd44bc..27311bafe 100644 --- a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html +++ b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html @@ -28,7 +28,7 @@ {{'DESCRIPTION-TYPES-LISTING.COLUMNS.STATUS' | translate}} -
    {{ 'DATASET-PROFILE-STATUS.FINALIZED' | translate}}
    +
    {{parseStatus(row.status) | translate}}
    @@ -41,10 +41,10 @@ - + - + diff --git a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts index d86fbbac9..99c79b984 100644 --- a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts +++ b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts @@ -4,6 +4,8 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; +import { Router } from '@angular/router'; +import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { BaseComponent } from '@common/base/base.component'; @@ -25,11 +27,17 @@ export class DescriptionTypesComponent extends BaseComponent implements OnInit { dataSource: DescriptionTypesDataSource | null; displayedColumns: String[] = ['label', 'status', 'delete']; + statuses = [ + { value: '0', viewValue: 'DESCRIPTION-TYPES-LISTING.STATUS.DRAFT' }, + { value: '1', viewValue: 'DESCRIPTION-TYPES-LISTING.STATUS.FINALIZED' } + ]; + constructor( private descriptionTemplateTypeService: DescriptionTemplateTypeService, private dialog: MatDialog, private language: TranslateService, - private uiNotificationService: UiNotificationService + private uiNotificationService: UiNotificationService, + private router: Router ) { super(); } @@ -42,6 +50,19 @@ export class DescriptionTypesComponent extends BaseComponent implements OnInit { this.dataSource = new DescriptionTypesDataSource(this.descriptionTemplateTypeService, this._paginator, this.sort/*, this.criteria*/); } + rowClick(rowId: String) { + this.router.navigate(['description-types/' + rowId]); + } + + parseStatus(value: number): string{ + const stringVal = value.toString() + try{ + return this.statuses.find(status => status.value === stringVal).viewValue; + }catch{ + return stringVal; + } + } + deleteTemplate(id: string){ if(id){ const dialogRef = this.dialog.open(ConfirmationDialogComponent, { @@ -56,25 +77,22 @@ export class DescriptionTypesComponent extends BaseComponent implements OnInit { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { if (result) { - // this.descriptionTemplateTypeService.deleteType(id) - // .pipe(takeUntil(this._destroyed)) - // .subscribe( - // complete => { - // this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Success); - // this.refresh(); - // }, - // error => { - // this.onCallbackError(error); - // if (error.error.statusCode == 674) { - // this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Error); - // } else { - // this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); - // } - // } - // ); - - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DESCRIPTION-TEMPLATE-TYPE-DELETE'), SnackBarNotificationLevel.Error); - this.refresh(); + this.descriptionTemplateTypeService.deleteType(id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Success); + this.refresh(); + }, + error => { + this.onCallbackError(error); + if (error.error.statusCode == 674) { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Error); + } else { + this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); + } + } + ); } }); @@ -96,55 +114,38 @@ export class DescriptionTypesComponent extends BaseComponent implements OnInit { } -export interface DescriptionTemplateTypeListingModel { - id: string; - name: string; - status: number; -} - -export class DescriptionTypesDataSource extends DataSource { +export class DescriptionTypesDataSource extends DataSource { totalCount = 0; constructor( private _service: DescriptionTemplateTypeService, private _paginator: MatPaginator, - private _sort: MatSort//, - //private _criteria: DmpProfileCriteriaComponent + private _sort: MatSort ) { super(); } - connect(): Observable { + connect(): Observable { const displayDataChanges = [ this._paginator.page //this._sort.matSortChange ]; - // return observableMerge(...displayDataChanges).pipe( - // startWith(null), - // switchMap(() => { - // // const startIndex = this._paginator.pageIndex * this._paginator.pageSize; - // // let fields: Array = new Array(); - // // if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; } - // // const request = new DataTableRequest(startIndex, this._paginator.pageSize, { fields: fields }); - // // request.criteria = this._criteria.criteria; - // // return this._service.getPaged(request); - - // return this._service.getTypes(); - // }), - // map(result => { - // return result; - // }), - // map(result => { - // // if (!result) { return []; } - // // if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } - // // return result.data; - // return result; - // })); - - return of([{id: '1234', name: 'Dataset', status: 0}]); + return observableMerge(...displayDataChanges).pipe( + startWith(null), + switchMap(() => { + return this._service.getTypes(); + }), + map(result => { + return result; + }), + map(result => { + if (!result) { return []; } + if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } + return result.data; + })); } disconnect() { diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index e8a8b7b74..112291d9d 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -960,6 +960,10 @@ "NAME": "Name", "STATUS": "Status" }, + "STATUS":{ + "DRAFT": "Draft", + "FINALIZED": "Finalized" + }, "ACTIONS": { "DELETE": "Delete" } @@ -987,6 +991,7 @@ }, "ACTIONS": { "SAVE": "Save", + "FINALIZE": "Finalize", "CANCEL": "Cancel" } }, From 6073c4cd852671e3a58c07dab97c7c1bcba6a738 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Mon, 11 Sep 2023 08:42:30 +0300 Subject: [PATCH 046/110] [WIP] refactor dmp export following the blueprint schema --- .../managers/DataManagementPlanManager.java | 361 +++++++++++++----- 1 file changed, 258 insertions(+), 103 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index 9679bc857..c112be774 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -50,8 +50,8 @@ import eu.eudat.models.data.dmp.*; import eu.eudat.models.data.doi.DepositRequest; import eu.eudat.models.data.doi.Doi; import eu.eudat.models.data.dynamicfields.DynamicFieldWithValue; -import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile; -import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Field; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.*; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory; import eu.eudat.models.data.funder.FunderDMPEditorModel; import eu.eudat.models.data.grant.GrantDMPEditorModel; import eu.eudat.models.data.helpermodels.Tuple; @@ -1251,116 +1251,271 @@ public class DataManagementPlanManager { // wordBuilder.addParagraphContent("Datasets", document, ParagraphStyle.HEADER1, BigInteger.ZERO); // // Space below Datasets. // XWPFParagraph parBreakDatasets = document.createParagraph(); - final Boolean isFinalized = dmpEntity.getStatus() == DMP.DMPStatus.FINALISED.getValue(); - final Boolean isPublic = dmpEntity.isPublic(); - dmpEntity.getDataset().stream() - .filter(item -> item.getStatus() != Dataset.Status.CANCELED.getValue()) - .filter(item -> item.getStatus() != Dataset.Status.DELETED.getValue()) - .filter(item -> !isPublic && !isFinalized || item.getStatus() == Dataset.Status.FINALISED.getValue()) - .sorted(Comparator.comparing(Dataset::getCreated)) - .forEach(datasetEntity -> { - Map properties = new HashMap<>(); - if (datasetEntity.getProperties() != null) { - //ObjectMapper objectMapper = new ObjectMapper(); - try { - properties = objectMapper.readValue(datasetEntity.getProperties(), LinkedHashMap.class); - } catch (IOException e) { - logger.error(e.getLocalizedMessage(), e); - } - /*JSONObject jObject = new JSONObject(datasetEntity.getProperties()); - properties = jObject.toMap();*/ - } - // Custom style for the Dataset title. - //wordBuilder.addParagraphContent("Title: " + datasetEntity.getLabel(), document, ParagraphStyle.HEADER1, BigInteger.ZERO); - XWPFParagraph datasetLabelParagraph = document.createParagraph(); -// datasetLabelParagraph.setStyle("Heading2"); - datasetLabelParagraph.setSpacingBetween(1.0); - XWPFRun runDatasetTitle1 = datasetLabelParagraph.createRun(); - runDatasetTitle1.setText("Title: "); - runDatasetTitle1.setColor("000000"); - //runDatasetTitle1.setBold(true); - //runDatasetTitle1.setFontSize(12); - XWPFRun runDatasetTitle = datasetLabelParagraph.createRun(); - runDatasetTitle.setText(datasetEntity.getLabel()); - runDatasetTitle.setColor("116a78"); - //runDatasetTitle.setBold(true); - //runDatasetTitle.setFontSize(12); + DMPProfile dmpProfile = dmpEntity.getProfile(); + DataManagementPlanBlueprintListingModel dmpBlueprintModel = new DataManagementPlanBlueprintListingModel(); + dmpBlueprintModel.fromDataModel(dmpProfile); + DataManagementPlanBlueprint dmpBlueprint = dmpBlueprintModel.getDefinition(); + for(Section section: dmpBlueprint.getSections()){ + wordBuilder.addParagraphContent("Section " + section.getOrdinal(), document, ParagraphStyle.HEADER1, BigInteger.ZERO, 0); + XWPFParagraph sectionInfoParagraph = document.createParagraph(); + sectionInfoParagraph.setSpacingBetween(1.0); + XWPFRun runSectionTitle = sectionInfoParagraph.createRun(); + runSectionTitle.setText("Title: "); + runSectionTitle.setColor("000000"); + XWPFRun runSectionTitleText = sectionInfoParagraph.createRun(); + runSectionTitleText.setText(section.getLabel()); + runSectionTitleText.setColor("116a78"); + XWPFParagraph sectionDescriptionParagraph = document.createParagraph(); + XWPFRun runSectionDescription = sectionDescriptionParagraph.createRun(); + runSectionDescription.setText("Description: "); + runSectionDescription.setColor("000000"); + XWPFRun runSectionDescriptionText = sectionDescriptionParagraph.createRun(); + runSectionDescriptionText.setText(section.getDescription()); + runSectionDescriptionText.setColor("116a78"); - XWPFParagraph datasetTemplateParagraph = document.createParagraph(); -// datasetTemplateParagraph.setStyle("Heading3"); - XWPFRun runDatasetTemplate1 = datasetTemplateParagraph.createRun(); - runDatasetTemplate1.setText("Template: "); - runDatasetTemplate1.setColor("000000"); - //runDatasetTemplate1.setBold(true); - //runDatasetTemplate1.setFontSize(12); - XWPFRun runDatasetTemplate = datasetTemplateParagraph.createRun(); - runDatasetTemplate.setText(datasetEntity.getProfile().getLabel()); - runDatasetTemplate.setColor("116a78"); - //runDatasetTemplate.setBold(true); - //runDatasetTemplate.setFontSize(12); + wordBuilder.addParagraphContent("Section Fields", document, ParagraphStyle.HEADER2, BigInteger.ZERO, 0); + section.getFields().sort(Comparator.comparingInt(FieldModel::getOrdinal)); + for(FieldModel field: section.getFields()){ + if(field.getCategory() == FieldCategory.SYSTEM){ + SystemField systemField = field.toSystemField(); + XWPFParagraph systemFieldParagraph = document.createParagraph(); + systemFieldParagraph.setSpacingBetween(1.0); + XWPFRun runSyStemFieldTitle = systemFieldParagraph.createRun(); + runSyStemFieldTitle.setText("Title: "); + runSyStemFieldTitle.setColor("000000"); + XWPFRun runSystemFieldTitleText = systemFieldParagraph.createRun(); + runSystemFieldTitleText.setText(systemField.getLabel()); + runSystemFieldTitleText.setColor("116a78"); + if(systemField.getDescription() != null && !systemField.getDescription().isEmpty()){ + XWPFParagraph systemFieldDescription = document.createParagraph(); + systemFieldDescription.setSpacingBetween(1.0); + XWPFRun runSyStemFieldDescription = systemFieldDescription.createRun(); + runSyStemFieldDescription.setText("Description: "); + runSyStemFieldDescription.setColor("000000"); + XWPFRun runSystemFieldDescriptionText = systemFieldDescription.createRun(); + runSystemFieldDescriptionText.setText(systemField.getDescription()); + runSystemFieldDescriptionText.setColor("116a78"); + } + XWPFParagraph systemFieldInput = document.createParagraph(); + systemFieldInput.setSpacingBetween(1.0); + XWPFRun runInput = systemFieldInput.createRun(); + runInput.setText("Input: "); + runInput.setColor("000000"); + switch (systemField.getType()) { + case TEXT: + XWPFRun runTitle = systemFieldInput.createRun(); + runTitle.setText(dmpEntity.getLabel()); + runTitle.setColor("116a78"); + break; + case HTML_TEXT: + XWPFRun runDescription = systemFieldInput.createRun(); + runDescription.setText(dmpEntity.getDescription()); + runDescription.setColor("116a78"); + break; + case RESEARCHERS: + for(Researcher researcher: dmpEntity.getResearchers()){ + XWPFRun runResearcher = systemFieldInput.createRun(); + runResearcher.setText("• " + researcher.getLabel()); + runResearcher.setColor("116a78"); + } + break; + case ORGANIZATIONS: + for(Organisation organisation: dmpEntity.getOrganisations()){ + XWPFRun runOrganisation = systemFieldInput.createRun(); + runOrganisation.setText("• " + organisation.getLabel()); + runOrganisation.setColor("116a78"); + } + break; + case LANGUAGE: + XWPFRun runLanguage = systemFieldInput.createRun(); + runLanguage.setText(objectMapper.readValue(dmpEntity.getExtraProperties(), HashMap.class).get("language").toString()); + runLanguage.setColor("116a78"); + break; + case CONTACT: + XWPFRun runContact = systemFieldInput.createRun(); + runContact.setText(dmpEntity.getCreator().getName()); + runContact.setColor("116a78"); + break; + case FUNDER: + XWPFRun runFunder = systemFieldInput.createRun(); + runFunder.setText(dmpEntity.getGrant().getFunder().getLabel()); + runFunder.setColor("116a78"); + break; + case GRANT: + XWPFRun runGrant = systemFieldInput.createRun(); + runGrant.setText(dmpEntity.getGrant().getLabel()); + runGrant.setColor("116a78"); + break; + case PROJECT: + XWPFRun runProject = systemFieldInput.createRun(); + runProject.setText(dmpEntity.getProject().getLabel()); + runProject.setColor("116a78"); + break; + case LICENSE: + XWPFRun runLicense = systemFieldInput.createRun(); + runLicense.setText(objectMapper.readValue(dmpEntity.getExtraProperties(), HashMap.class).get("license").toString()); + runLicense.setColor("116a78"); + break; + case ACCESS_RIGHTS: + XWPFRun runAccessRights = systemFieldInput.createRun(); + runAccessRights.setText(objectMapper.readValue(dmpEntity.getExtraProperties(), HashMap.class).get("visible").toString()); + runAccessRights.setColor("116a78"); + break; + } + document.createParagraph(); + } + else if(field.getCategory() == FieldCategory.EXTRA){ + ExtraField extraField = field.toExtraField(); + XWPFParagraph extraFieldParagraph = document.createParagraph(); + extraFieldParagraph.setSpacingBetween(1.0); + XWPFRun runExtraFieldLabel = extraFieldParagraph.createRun(); + runExtraFieldLabel.setText(extraField.getLabel()); + runExtraFieldLabel.setColor("116a78"); + if(extraField.getDescription() != null && !extraField.getDescription().isEmpty()){ + XWPFRun runExtraFieldDescription = extraFieldParagraph.createRun(); + runExtraFieldDescription.setText(extraField.getDescription()); + runExtraFieldDescription.setColor("116a78"); + } + XWPFRun runExtraFieldInput = extraFieldParagraph.createRun(); + runExtraFieldInput.setText(extraField.getLabel()); + runExtraFieldInput.setColor("116a78"); + } + } - document.createParagraph(); + if(!section.getDescriptionTemplates().isEmpty()){ + wordBuilder.addParagraphContent("Section descriptions", document, ParagraphStyle.HEADER2, BigInteger.ZERO, 0); + wordBuilder.addParagraphContent("Description Templates", document, ParagraphStyle.HEADER4, BigInteger.ZERO, 0); + for(eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DescriptionTemplate descriptionTemplate: section.getDescriptionTemplates()){ + XWPFParagraph templateParagraph = document.createParagraph(); + XWPFRun runTemplateLabel = templateParagraph.createRun(); + runTemplateLabel.setText("• " + descriptionTemplate.getLabel()); + runTemplateLabel.setColor("116a78"); + } -// /*XWPFParagraph externalReferencesParagraph = document.createParagraph(); -// externalReferencesParagraph.setStyle("Heading3"); -// XWPFRun externalReferencesRun = externalReferencesParagraph.createRun(); -// externalReferencesRun.setText("External References"); -// externalReferencesRun.setColor("2E75B6"); -// externalReferencesRun.setBold(true); -// externalReferencesRun.setFontSize(12); + final Boolean isFinalized = dmpEntity.getStatus() == DMP.DMPStatus.FINALISED.getValue(); + final Boolean isPublic = dmpEntity.isPublic(); + dmpEntity.getDataset().stream() + .filter(item -> item.getStatus() != Dataset.Status.CANCELED.getValue()) + .filter(item -> item.getStatus() != Dataset.Status.DELETED.getValue()) + .filter(item -> !isPublic && !isFinalized || item.getStatus() == Dataset.Status.FINALISED.getValue()) + .filter(item -> item.getDmpSectionIndex().equals(section.getOrdinal() - 1)) + .sorted(Comparator.comparing(Dataset::getCreated)) + .forEach(datasetEntity -> { + Map properties = new HashMap<>(); + if (datasetEntity.getProperties() != null) { + //ObjectMapper objectMapper = new ObjectMapper(); + try { + properties = objectMapper.readValue(datasetEntity.getProperties(), LinkedHashMap.class); + } catch (IOException e) { + logger.error(e.getLocalizedMessage(), e); + } + /*JSONObject jObject = new JSONObject(datasetEntity.getProperties()); + properties = jObject.toMap();*/ + } + + + // Dataset Description custom style. + XWPFParagraph datasetDescriptionParagraph = document.createParagraph(); + datasetDescriptionParagraph.setStyle("Heading4"); + datasetDescriptionParagraph.setSpacingBetween(1.5); + XWPFRun datasetDescriptionRun = datasetDescriptionParagraph.createRun(); + datasetDescriptionRun.setText("Dataset Description"); + //datasetDescriptionRun.setColor("2E75B6"); + //datasetDescriptionRun.setBold(true); + datasetDescriptionRun.setFontSize(15); + + + // Custom style for the Dataset title. + //wordBuilder.addParagraphContent("Title: " + datasetEntity.getLabel(), document, ParagraphStyle.HEADER1, BigInteger.ZERO); + XWPFParagraph datasetLabelParagraph = document.createParagraph(); +// datasetLabelParagraph.setStyle("Heading2"); + datasetLabelParagraph.setSpacingBetween(1.0); + XWPFRun runDatasetTitle1 = datasetLabelParagraph.createRun(); + runDatasetTitle1.setText("Title: "); + runDatasetTitle1.setColor("000000"); + //runDatasetTitle1.setBold(true); + //runDatasetTitle1.setFontSize(12); + XWPFRun runDatasetTitle = datasetLabelParagraph.createRun(); + runDatasetTitle.setText(datasetEntity.getLabel()); + runDatasetTitle.setColor("116a78"); + //runDatasetTitle.setBold(true); + //runDatasetTitle.setFontSize(12); + + XWPFParagraph datasetTemplateParagraph = document.createParagraph(); +// datasetTemplateParagraph.setStyle("Heading3"); + XWPFRun runDatasetTemplate1 = datasetTemplateParagraph.createRun(); + runDatasetTemplate1.setText("Template: "); + runDatasetTemplate1.setColor("000000"); + //runDatasetTemplate1.setBold(true); + //runDatasetTemplate1.setFontSize(12); + XWPFRun runDatasetTemplate = datasetTemplateParagraph.createRun(); + runDatasetTemplate.setText(datasetEntity.getProfile().getLabel()); + runDatasetTemplate.setColor("116a78"); + //runDatasetTemplate.setBold(true); + //runDatasetTemplate.setFontSize(12); + +// /*XWPFParagraph externalReferencesParagraph = document.createParagraph(); +// externalReferencesParagraph.setStyle("Heading3"); +// XWPFRun externalReferencesRun = externalReferencesParagraph.createRun(); +// externalReferencesRun.setText("External References"); +// externalReferencesRun.setColor("2E75B6"); +// externalReferencesRun.setBold(true); +// externalReferencesRun.setFontSize(12); // -// wordBuilder.addParagraphContent("Data Repositories", document, ParagraphStyle.HEADER4, BigInteger.ZERO); -// if (datasetEntity.getDatasetDataRepositories().size() > 0) { -// wordBuilder.addParagraphContent(datasetEntity.getDatasetDataRepositories().stream().map(DatasetDataRepository::getDataRepository).map(DataRepository::getLabel).collect(Collectors.joining(", ")) -// , document, ParagraphStyle.TEXT, BigInteger.ZERO); -// } -// wordBuilder.addParagraphContent("External Datasets", document, ParagraphStyle.HEADER4, BigInteger.ZERO); -// if (datasetEntity.getDatasetExternalDatasets().size() > 0) { -// wordBuilder.addParagraphContent(datasetEntity.getDatasetExternalDatasets().stream().map(DatasetExternalDataset::getExternalDataset).map(ExternalDataset::getLabel).collect(Collectors.joining(", ")) -// , document, ParagraphStyle.TEXT, BigInteger.ZERO); -// } -// wordBuilder.addParagraphContent("Registries", document, ParagraphStyle.HEADER4, BigInteger.ZERO); -// if (datasetEntity.getRegistries().size() > 0) { -// wordBuilder.addParagraphContent(datasetEntity.getRegistries().stream().map(Registry::getLabel).collect(Collectors.joining(", ")) -// , document, ParagraphStyle.TEXT, BigInteger.ZERO); -// } -// wordBuilder.addParagraphContent("Services", document, ParagraphStyle.HEADER4, BigInteger.ZERO); -// if (datasetEntity.getServices().size() > 0) { -// wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) -// , document, ParagraphStyle.TEXT, BigInteger.ZERO); -// } -// *//*wordBuilder.addParagraphContent("Tags", document, ParagraphStyle.HEADER3, BigInteger.ZERO); -// if (datasetEntity.().size() > 0) { -// wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) -// , document, ParagraphStyle.HEADER4, BigInteger.ZERO); -// }*/ +// wordBuilder.addParagraphContent("Data Repositories", document, ParagraphStyle.HEADER4, BigInteger.ZERO); +// if (datasetEntity.getDatasetDataRepositories().size() > 0) { +// wordBuilder.addParagraphContent(datasetEntity.getDatasetDataRepositories().stream().map(DatasetDataRepository::getDataRepository).map(DataRepository::getLabel).collect(Collectors.joining(", ")) +// , document, ParagraphStyle.TEXT, BigInteger.ZERO); +// } +// wordBuilder.addParagraphContent("External Datasets", document, ParagraphStyle.HEADER4, BigInteger.ZERO); +// if (datasetEntity.getDatasetExternalDatasets().size() > 0) { +// wordBuilder.addParagraphContent(datasetEntity.getDatasetExternalDatasets().stream().map(DatasetExternalDataset::getExternalDataset).map(ExternalDataset::getLabel).collect(Collectors.joining(", ")) +// , document, ParagraphStyle.TEXT, BigInteger.ZERO); +// } +// wordBuilder.addParagraphContent("Registries", document, ParagraphStyle.HEADER4, BigInteger.ZERO); +// if (datasetEntity.getRegistries().size() > 0) { +// wordBuilder.addParagraphContent(datasetEntity.getRegistries().stream().map(Registry::getLabel).collect(Collectors.joining(", ")) +// , document, ParagraphStyle.TEXT, BigInteger.ZERO); +// } +// wordBuilder.addParagraphContent("Services", document, ParagraphStyle.HEADER4, BigInteger.ZERO); +// if (datasetEntity.getServices().size() > 0) { +// wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) +// , document, ParagraphStyle.TEXT, BigInteger.ZERO); +// } +// *//*wordBuilder.addParagraphContent("Tags", document, ParagraphStyle.HEADER3, BigInteger.ZERO); +// if (datasetEntity.().size() > 0) { +// wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) +// , document, ParagraphStyle.HEADER4, BigInteger.ZERO); +// }*/ // // - wordBuilder.addParagraphContent(datasetEntity.getDescription(), document, ParagraphStyle.HTML, BigInteger.ZERO, 0); - // Dataset Description custom style. - XWPFParagraph datasetDescriptionParagraph = document.createParagraph(); - datasetDescriptionParagraph.setStyle("Heading4"); - datasetDescriptionParagraph.setSpacingBetween(1.5); - XWPFRun datasetDescriptionRun = datasetDescriptionParagraph.createRun(); - datasetDescriptionRun.setText("Dataset Description"); - //datasetDescriptionRun.setColor("2E75B6"); - //datasetDescriptionRun.setBold(true); - datasetDescriptionRun.setFontSize(15); + XWPFParagraph datasetDescParagraph = document.createParagraph(); + XWPFRun runDatasetDescription1 = datasetDescParagraph.createRun(); + runDatasetDescription1.setText("Description: "); + runDatasetDescription1.setColor("000000"); + XWPFRun runDatasetDescription = datasetDescParagraph.createRun(); + runDatasetDescription.setText(datasetEntity.getProfile().getLabel()); + runDatasetDescription.setColor("116a78"); + //wordBuilder.addParagraphContent(datasetEntity.getDescription(), document, ParagraphStyle.HTML, BigInteger.ZERO, 0); - PagedDatasetProfile pagedDatasetProfile = datasetManager.getPagedProfile(dataset, datasetEntity); - visibilityRuleService.setProperties(properties); - visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules()); - try { - wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - // Page break at the end of the Dataset. - XWPFParagraph parBreakDataset = document.createParagraph(); - parBreakDataset.setPageBreak(true); - }); + document.createParagraph(); + + PagedDatasetProfile pagedDatasetProfile = datasetManager.getPagedProfile(dataset, datasetEntity); + visibilityRuleService.setProperties(properties); + visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules()); + try { + wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + // Page break at the end of the Dataset. + XWPFParagraph parBreakDataset = document.createParagraph(); + parBreakDataset.setPageBreak(true); + }); + } + } // // Removes the top empty headings. // for (int i = 0; i < 6; i++) { From 4219d9003951900e22323d8e02e256a267ea8bf1 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Mon, 11 Sep 2023 08:57:09 +0300 Subject: [PATCH 047/110] add "DmpSectionIndex" column to descriptions in order to know in which section of a dmp the description belongs, add "data" column in DmpDatasetProfile table, data stores in which sections a description template is saved --- .../data/dao/entities/DatasetProfileDao.java | 3 +- .../dao/entities/DatasetProfileDaoImpl.java | 4 +- .../main/java/eu/eudat/data/entities/DMP.java | 10 +- .../data/entities/DMPDatasetProfile.java | 77 ++++ .../java/eu/eudat/data/entities/Dataset.java | 10 + .../data/entities/DescriptionTemplate.java | 8 +- .../managers/DataManagementPlanManager.java | 4 +- .../datasetwizard/DatasetWizardModel.java | 11 + .../models/data/dmp/AssociatedProfile.java | 10 + .../models/data/dmp/DataManagementPlan.java | 33 +- .../dmp/DataManagementPlanEditorModel.java | 23 +- .../DataManagementPlanNewVersionModel.java | 15 +- .../DataManagementPlanOverviewModel.java | 18 +- .../AssociatedProfilePublicModel.java | 10 + .../DataManagementPlanPublicModel.java | 14 +- dmp-db-scema/main/dmp-dump.sql | 4 +- ...olumn_to_Dataset_and_DMPDatasetProfile.sql | 15 + .../app/core/model/dataset/dataset-wizard.ts | 1 + ...dmp-dataset-profile-sections-form.model.ts | 28 ++ .../dmp-dataset-profile.ts | 7 + dmp-frontend/src/app/core/model/dmp/dmp.ts | 8 +- .../dataset-wizard-editor.model.ts | 4 + .../dataset-wizard.component.ts | 4 + .../src/app/ui/dataset/dataset.routing.ts | 2 +- .../dmp-editor-blueprint.component.html | 350 ++++++++++-------- .../dmp-editor-blueprint.component.scss | 18 + .../dmp-editor-blueprint.component.ts | 45 ++- .../src/app/ui/dmp/editor/dmp-editor.model.ts | 8 +- .../ui/dmp/wizard/dmp-wizard-editor.model.ts | 3 +- 29 files changed, 535 insertions(+), 212 deletions(-) create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/entities/DMPDatasetProfile.java create mode 100644 dmp-db-scema/updates/00.00.015_Add_new_column_to_Dataset_and_DMPDatasetProfile.sql create mode 100644 dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile-sections-form.model.ts create mode 100644 dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile.ts diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java index 5365067fc..35f508436 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java @@ -3,6 +3,7 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccessLayer; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; import eu.eudat.data.entities.DescriptionTemplate; +import eu.eudat.data.entities.DescriptionTemplateType; import eu.eudat.queryable.QueryableList; import java.util.List; @@ -18,6 +19,6 @@ public interface DatasetProfileDao extends DatabaseAccessLayer getAllIds(); - Long countWithType(UUID id); + Long countWithType(DescriptionTemplateType type); } \ No newline at end of file diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java index eae2be263..3ba9fe758 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java @@ -128,7 +128,7 @@ public class DatasetProfileDaoImpl extends DatabaseAccess i } @Override - public Long countWithType(UUID id) { - return this.getDatabaseService().getQueryable(DescriptionTemplate.class).where((builder, root) -> builder.equal(root.get("type"), id)).count(); + public Long countWithType(DescriptionTemplateType type) { + return this.getDatabaseService().getQueryable(DescriptionTemplate.class).where((builder, root) -> builder.equal(root.get("type"), type)).count(); } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java index 54beaeeb9..dcfbdb698 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java @@ -113,11 +113,7 @@ public class DMP implements DataEntity { @Column(name = "\"AssociatedDmps\"", columnDefinition = "xml", nullable = true) private String associatedDmps;*/ @OneToMany(fetch = FetchType.LAZY) - @JoinTable(name = "\"DMPDatasetProfile\"", - joinColumns = {@JoinColumn(name = "\"dmp\"", referencedColumnName = "\"ID\"")}, - inverseJoinColumns = {@JoinColumn(name = "\"datasetprofile\"", referencedColumnName = "\"ID\"")} - ) - private Set associatedDmps; + private Set associatedDmps; @ManyToOne(fetch = FetchType.LAZY) @@ -274,10 +270,10 @@ public class DMP implements DataEntity { this.grant = grant; } - public Set getAssociatedDmps() { + public Set getAssociatedDmps() { return associatedDmps; } - public void setAssociatedDmps(Set associatedDmps) { + public void setAssociatedDmps(Set associatedDmps) { this.associatedDmps = associatedDmps; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMPDatasetProfile.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMPDatasetProfile.java new file mode 100644 index 000000000..8ee7a59fc --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMPDatasetProfile.java @@ -0,0 +1,77 @@ +package eu.eudat.data.entities; + +import eu.eudat.queryable.queryableentity.DataEntity; +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.annotations.Type; + +import javax.persistence.*; +import java.util.List; +import java.util.UUID; + +@Entity +@Table(name = "\"DMPDatasetProfile\"") +public class DMPDatasetProfile implements DataEntity { + + @Id + @GeneratedValue + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID id; + + @ManyToOne + @JoinColumn(name = "\"dmp\"") + private DMP dmp; + + @ManyToOne + @JoinColumn(name = "\"datasetprofile\"") + private DescriptionTemplate datasetprofile; + + @Column(name = "\"data\"") + private String data; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public DMP getDmp() { + return dmp; + } + public void setDmp(DMP dmp) { + this.dmp = dmp; + } + + public DescriptionTemplate getDatasetprofile() { + return datasetprofile; + } + public void setDatasetprofile(DescriptionTemplate datasetprofile) { + this.datasetprofile = datasetprofile; + } + + public String getData() { + return data; + } + public void setData(String data) { + this.data = data; + } + + @Override + public void update(DMPDatasetProfile entity) { + this.dmp = entity.getDmp(); + this.datasetprofile = entity.getDatasetprofile(); + this.data = entity.getData(); + } + + @Override + public UUID getKeys() { + return this.id; + } + + @Override + public DMPDatasetProfile buildFromTuple(List tuple, List fields, String base) { + this.id = UUID.fromString((String) tuple.get(0).get(base.isEmpty() ? base + "." + "id" : "id")); + return this; + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java index 7456b21d8..357f49ec9 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java @@ -100,6 +100,9 @@ public class Dataset implements DataEntity { @JoinColumn(name = "\"DMP\"", nullable = false) private DMP dmp; + @Column(name = "\"DmpSectionIndex\"") + private Integer dmpSectionIndex; + @Column(name = "\"Uri\"") private String uri; @@ -232,6 +235,12 @@ public class Dataset implements DataEntity { this.dmp = dmp; } + public Integer getDmpSectionIndex() { + return dmpSectionIndex; + } + public void setDmpSectionIndex(Integer dmpSectionIndex) { + this.dmpSectionIndex = dmpSectionIndex; + } public String getUri() { return uri; @@ -328,6 +337,7 @@ public class Dataset implements DataEntity { this.setRegistries(entity.getRegistries()); this.setDmp(entity.getDmp()); + this.setDmpSectionIndex(entity.getDmpSectionIndex()); this.setStatus(entity.getStatus()); this.setProfile(entity.getProfile()); this.setModified(new Date()); diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java index c30018630..fdfd02b57 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java @@ -79,12 +79,8 @@ public class DescriptionTemplate implements DataEntity @Column(name = "\"Version\"", nullable = false) private Short version; - @ManyToMany(fetch = FetchType.LAZY) - @JoinTable(name = "\"DMPDatasetProfile\"", - joinColumns = {@JoinColumn(name = "\"datasetprofile\"", referencedColumnName = "\"ID\"")}, - inverseJoinColumns = {@JoinColumn(name = "\"dmp\"", referencedColumnName = "\"ID\"")} - ) - private List dmps; + @OneToMany(fetch = FetchType.LAZY) + private Set dmps; @Column(name = "\"Language\"", nullable = false) private String language; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index c112be774..6a68163cb 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -5,6 +5,7 @@ import eu.eudat.configurations.dynamicgrant.DynamicGrantConfiguration; import eu.eudat.configurations.dynamicgrant.entities.Property; import eu.eudat.data.dao.criteria.*; import eu.eudat.data.dao.entities.*; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.Organisation; import eu.eudat.data.entities.Researcher; import eu.eudat.data.entities.*; @@ -1755,7 +1756,8 @@ public class DataManagementPlanManager { Element profiles = xmlDoc.createElement("profiles"); // Get DatasetProfiles from DMP to add to XML. - for (DescriptionTemplate descriptionTemplate : dmp.getAssociatedDmps()) { + for (DMPDatasetProfile dmpDescriptionProfile : dmp.getAssociatedDmps()) { + DescriptionTemplate descriptionTemplate = dmpDescriptionProfile.getDatasetprofile(); Element profile = xmlDoc.createElement("profile"); Element profileId = xmlDoc.createElement("profileId"); profileId.setTextContent(descriptionTemplate.getId().toString()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java index bd3c0a429..439b673f6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java @@ -26,6 +26,7 @@ public class DatasetWizardModel implements DataModel registries; private List services; @@ -92,6 +93,13 @@ public class DatasetWizardModel implements DataModel new Service().fromDataModel(item.getService())).collect(Collectors.toList()) : new ArrayList<>(); this.created = entity.getCreated(); this.dmp = new DataManagementPlan().fromDataModelNoDatasets(entity.getDmp()); + this.dmpSectionIndex = entity.getDmpSectionIndex(); this.externalDatasets = entity.getDatasetExternalDatasets() != null ? entity.getDatasetExternalDatasets().stream().map(item -> { ExternalDatasetListingModel externalDatasetListingModel = new ExternalDatasetListingModel().fromDataModel(item.getExternalDataset()); if (item.getData() != null) { @@ -202,6 +211,7 @@ public class DatasetWizardModel implements DataModel new Registry().fromDataModel(item)).collect(Collectors.toList()) : new ArrayList<>(); this.dataRepositories = entity.getDatasetDataRepositories() != null ? entity.getDatasetDataRepositories().stream().map(item -> { DataRepository dataRepository = new DataRepository().fromDataModel(item.getDataRepository()); @@ -241,6 +251,7 @@ public class DatasetWizardModel implements DataModel { private UUID id; private String label; + private Map data; public UUID getId() { return id; @@ -28,6 +30,14 @@ public class AssociatedProfile implements XmlSerializable { this.label = label; } + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + @Override public Element toXml(Document doc) { Element profile = doc.createElement("profile"); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java index f86cea599..2de902349 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java @@ -1,5 +1,7 @@ package eu.eudat.models.data.dmp; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.*; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.models.DataModel; @@ -258,8 +260,14 @@ public class DataManagementPlan implements DataModel { if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) { this.profiles = new LinkedList<>(); - for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate); + for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile()); + try { + associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); + } + catch (Exception e) { + associatedProfile.setData(null); + } this.profiles.add(associatedProfile); } } @@ -320,11 +328,16 @@ public class DataManagementPlan implements DataModel { dataManagementPlanEntity.setProject(this.project.toDataModel()); } if (this.profiles != null) { - Set descriptionTemplates = new HashSet<>(); + Set dmpDatasetProfiles = new HashSet<>(); for (AssociatedProfile profile : this.profiles) { - descriptionTemplates.add(profile.toData()); + DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile(); + dmpDatasetProfile.setId(UUID.randomUUID()); + dmpDatasetProfile.setDmp(dataManagementPlanEntity); + dmpDatasetProfile.setDatasetprofile(profile.toData()); + dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData())); + dmpDatasetProfiles.add(dmpDatasetProfile); } - dataManagementPlanEntity.setAssociatedDmps(descriptionTemplates); + dataManagementPlanEntity.setAssociatedDmps(dmpDatasetProfiles); } dataManagementPlanEntity.setProperties(this.properties != null ? JSONObject.toJSONString(this.properties) : null); dataManagementPlanEntity.setGroupId(this.groupId != null ? this.groupId : UUID.randomUUID()); @@ -365,8 +378,14 @@ public class DataManagementPlan implements DataModel { if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) { this.profiles = new LinkedList<>(); - for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate); + for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile()); + try { + associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); + } + catch (Exception e) { + associatedProfile.setData(null); + } this.profiles.add(associatedProfile); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java index fc1cd7f84..1fde4e113 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java @@ -1,5 +1,7 @@ package eu.eudat.models.data.dmp; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.*; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.models.DataModel; @@ -249,8 +251,14 @@ public class DataManagementPlanEditorModel implements DataModel(); - for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate); + for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile()); + try { + associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); + } + catch (Exception e) { + associatedProfile.setData(null); + } this.profiles.add(associatedProfile); } } @@ -358,11 +366,16 @@ public class DataManagementPlanEditorModel implements DataModel descriptionTemplates = new HashSet<>(); + Set dmpDatasetProfiles = new HashSet<>(); for (AssociatedProfile profile : this.profiles) { - descriptionTemplates.add(profile.toData()); + DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile(); + dmpDatasetProfile.setId(UUID.randomUUID()); + dmpDatasetProfile.setDmp(dataManagementPlanEntity); + dmpDatasetProfile.setDatasetprofile(profile.toData()); + dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData())); + dmpDatasetProfiles.add(dmpDatasetProfile); } - dataManagementPlanEntity.setAssociatedDmps(descriptionTemplates); + dataManagementPlanEntity.setAssociatedDmps(dmpDatasetProfiles); } dataManagementPlanEntity.setProperties(this.properties != null ? JSONObject.toJSONString(this.properties) : null); dataManagementPlanEntity.setGroupId(this.groupId != null ? this.groupId : UUID.randomUUID()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java index eae784aeb..a45246e2e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java @@ -1,5 +1,6 @@ package eu.eudat.models.data.dmp; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.*; import eu.eudat.models.DataModel; import eu.eudat.models.data.dataset.Dataset; @@ -260,8 +261,18 @@ public class DataManagementPlanNewVersionModel implements DataModel x.toData()).collect(Collectors.toSet())); + if (this.profiles != null) { + Set dmpDatasetProfiles = new HashSet<>(); + for (AssociatedProfile profile : this.profiles) { + DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile(); + dmpDatasetProfile.setId(UUID.randomUUID()); + dmpDatasetProfile.setDmp(entity); + dmpDatasetProfile.setDatasetprofile(profile.toData()); + dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData())); + dmpDatasetProfiles.add(dmpDatasetProfile); + } + entity.setAssociatedDmps(dmpDatasetProfiles); + } return entity; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java index 98d491343..1c79930b0 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java @@ -1,6 +1,9 @@ package eu.eudat.models.data.listingmodels; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.DMP; +import eu.eudat.data.entities.DMPDatasetProfile; import eu.eudat.data.entities.Dataset; import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.models.DataModel; @@ -11,10 +14,7 @@ import eu.eudat.models.data.dmp.Researcher; import eu.eudat.models.data.doi.Doi; import eu.eudat.models.data.grant.GrantOverviewModel; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; public class DataManagementPlanOverviewModel implements DataModel { @@ -205,8 +205,14 @@ public class DataManagementPlanOverviewModel implements DataModel(); - for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(descriptionTemplate); + for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile()); + try { + associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); + } + catch (Exception e) { + associatedProfile.setData(null); + } this.associatedProfiles.add(associatedProfile); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java index d2783e56a..228f843e5 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java @@ -5,11 +5,13 @@ import eu.eudat.logic.utilities.interfaces.XmlSerializable; import org.w3c.dom.Document; import org.w3c.dom.Element; +import java.util.Map; import java.util.UUID; public class AssociatedProfilePublicModel implements XmlSerializable { private UUID id; private String label; + private Map data; public UUID getId() { return id; @@ -27,6 +29,14 @@ public class AssociatedProfilePublicModel implements XmlSerializable getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + @Override public Element toXml(Document doc) { Element profile = doc.createElement("profile"); diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/overviewmodels/DataManagementPlanPublicModel.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/overviewmodels/DataManagementPlanPublicModel.java index 9f8f5fb81..702f9b13f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/overviewmodels/DataManagementPlanPublicModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/overviewmodels/DataManagementPlanPublicModel.java @@ -1,10 +1,14 @@ package eu.eudat.publicapi.models.overviewmodels; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.DMP; +import eu.eudat.data.entities.DMPDatasetProfile; import eu.eudat.data.entities.Dataset; import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.models.DataModel; +import eu.eudat.models.data.dmp.AssociatedProfile; import eu.eudat.models.data.user.composite.PagedDatasetProfile; import eu.eudat.publicapi.models.associatedprofile.AssociatedProfilePublicModel; import eu.eudat.publicapi.models.doi.DoiPublicModel; @@ -193,8 +197,14 @@ public class DataManagementPlanPublicModel implements DataModel(); - for (DescriptionTemplate descriptionTemplate : entity.getAssociatedDmps()) { - AssociatedProfilePublicModel associatedProfile = new AssociatedProfilePublicModel().fromData(descriptionTemplate); + for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { + AssociatedProfilePublicModel associatedProfile = new AssociatedProfilePublicModel().fromData(dmpDescriptionProfile.getDatasetprofile()); + try { + associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); + } + catch (Exception e) { + associatedProfile.setData(null); + } this.associatedProfiles.add(associatedProfile); } } diff --git a/dmp-db-scema/main/dmp-dump.sql b/dmp-db-scema/main/dmp-dump.sql index 4e09de7e5..5852e0e75 100644 --- a/dmp-db-scema/main/dmp-dump.sql +++ b/dmp-db-scema/main/dmp-dump.sql @@ -129,7 +129,8 @@ COMMENT ON COLUMN public."DMP"."AssociatedDmps" IS 'More data about the DMP as d CREATE TABLE public."DMPDatasetProfile" ( "ID" uuid DEFAULT public.uuid_generate_v4() NOT NULL, dmp uuid NOT NULL, - datasetprofile uuid NOT NULL + datasetprofile uuid NOT NULL, + "data" text ); @@ -235,6 +236,7 @@ CREATE TABLE public."Dataset" ( "ID" uuid DEFAULT public.uuid_generate_v4() NOT NULL, "Label" character varying(250) NOT NULL, "DMP" uuid, + "DmpSectionIndex" integer, "Uri" character varying(250), "Properties" text, "Profile" uuid, diff --git a/dmp-db-scema/updates/00.00.015_Add_new_column_to_Dataset_and_DMPDatasetProfile.sql b/dmp-db-scema/updates/00.00.015_Add_new_column_to_Dataset_and_DMPDatasetProfile.sql new file mode 100644 index 000000000..b0cd7df0c --- /dev/null +++ b/dmp-db-scema/updates/00.00.015_Add_new_column_to_Dataset_and_DMPDatasetProfile.sql @@ -0,0 +1,15 @@ +DO $$DECLARE + this_version CONSTANT varchar := '00.00.014'; +BEGIN + PERFORM * FROM "DBVersion" WHERE version = this_version; + IF FOUND THEN RETURN; END IF; + +ALTER TABLE public."Dataset" +ADD COLUMN "DmpSectionIndex" integer; + +ALTER TABLE public."DMPDatasetProfile" +ADD COLUMN "data" text; + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.015', '2023-09-01 12:00:00.000000+02', now(), 'Add column DmpSectionIndex to Dataset table and data to DMPDatasetProfile.'); + +END$$; \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dataset/dataset-wizard.ts b/dmp-frontend/src/app/core/model/dataset/dataset-wizard.ts index 48a031cfa..ccbe8d43c 100644 --- a/dmp-frontend/src/app/core/model/dataset/dataset-wizard.ts +++ b/dmp-frontend/src/app/core/model/dataset/dataset-wizard.ts @@ -14,6 +14,7 @@ export interface DatasetWizardModel { description?: String; status?: number; dmp?: DmpModel; + dmpSectionIndex?: number; datasetProfileDefinition?: DatasetProfileDefinitionModel; registries?: RegistryModel[]; services?: ServiceModel[]; diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile-sections-form.model.ts b/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile-sections-form.model.ts new file mode 100644 index 000000000..8f0745359 --- /dev/null +++ b/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile-sections-form.model.ts @@ -0,0 +1,28 @@ +import { FormGroup, FormBuilder } from "@angular/forms"; +import { BackendErrorValidator } from "@common/forms/validation/custom-validator"; +import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; +import { ValidationContext } from "@common/forms/validation/validation-context"; + +export class DmpDatasetProfileSectionsFormModel { + public dmpSectionIndex: number[] = []; + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + + fromModel(item: any): DmpDatasetProfileSectionsFormModel { + this.dmpSectionIndex = item.dmpSectionIndex; + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { + if (context == null) { context = this.createValidationContext(); } + const formGroup = new FormBuilder().group({ + language: [{ value: this.dmpSectionIndex, disabled: disabled }, context.getValidation('dmpSectionIndex').validators], + }); + return formGroup; + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + baseContext.validation.push({ key: 'dmpSectionIndex', validators: [BackendErrorValidator(this.validationErrorModel, 'dmpSectionIndex')] }); + return baseContext; + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile.ts b/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile.ts new file mode 100644 index 000000000..9c40d752e --- /dev/null +++ b/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile.ts @@ -0,0 +1,7 @@ +import { DmpDatasetProfileSectionsFormModel } from "./dmp-dataset-profile-sections-form.model"; + +export interface DmpDatasetProfile { + id: string; + label: string; + data: DmpDatasetProfileSectionsFormModel; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dmp/dmp.ts b/dmp-frontend/src/app/core/model/dmp/dmp.ts index 2ebc47fcc..d26912dc4 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp.ts @@ -1,17 +1,15 @@ -import { Status } from "../../common/enum/status"; -import { DmpProfile, DmpProfileDefinition } from "../dmp-profile/dmp-profile"; +import { DmpProfileDefinition } from "../dmp-profile/dmp-profile"; import { OrganizationModel } from "../organisation/organization"; import { GrantListingModel } from "../grant/grant-listing"; import { ResearcherModel } from "../researcher/researcher"; import { UserModel } from "../user/user"; import { DmpDynamicField } from "./dmp-dynamic-field"; import { UserInfoListingModel } from "../user/user-info-listing"; -import { DatasetModel } from "../dataset/dataset"; import { ProjectModel } from "../project/project"; import { FunderModel } from "../funder/funder"; import { DmpStatus } from '@app/core/common/enum/dmp-status'; -import { ExtraPropertiesFormModel } from '@app/ui/dmp/editor/general-tab/extra-properties-form.model'; import { DatasetWizardModel } from '../dataset/dataset-wizard'; +import { DmpDatasetProfile } from "./dmp-dataset-profile/dmp-dataset-profile"; export interface DmpModel { id: string; @@ -27,7 +25,7 @@ export interface DmpModel { funder: FunderModel; datasets: DatasetWizardModel[]; datasetsToBeFinalized: string[]; - profiles: DmpProfile[]; + profiles: DmpDatasetProfile[]; organisations: OrganizationModel[]; researchers: ResearcherModel[]; associatedUsers: UserModel[]; diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts index f4ad2cf38..e2a3f45a5 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts @@ -26,6 +26,7 @@ export class DatasetWizardEditorModel { public tags: ExternalTagEditorModel[] = []; public externalDatasets: ExternalDatasetEditorModel[] = []; public dmp: DmpModel; + public dmpSectionIndex: number; public datasetProfileDefinition: DatasetDescriptionFormEditorModel; public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); public isProfileLatestVersion: Boolean; @@ -43,6 +44,7 @@ export class DatasetWizardEditorModel { if (item.dataRepositories) { this.dataRepositories = item.dataRepositories.map(x => new ExternalDataRepositoryEditorModel().fromModel(x)); } if (item.externalDatasets) { this.externalDatasets = item.externalDatasets.map(x => new ExternalDatasetEditorModel().fromModel(x)); } this.dmp = item.dmp; + this.dmpSectionIndex = item.dmpSectionIndex; if (item.datasetProfileDefinition) { this.datasetProfileDefinition = new DatasetDescriptionFormEditorModel().fromModel(item.datasetProfileDefinition); } if (item.tags) { this.tags = item.tags.map(x => new ExternalTagEditorModel().fromModel(x)); } this.isProfileLatestVersion = item.isProfileLatestVersion; @@ -60,6 +62,7 @@ export class DatasetWizardEditorModel { status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators], description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators], dmp: [{ value: this.dmp, disabled: disabled }, context.getValidation('dmp').validators], + dmpSectionIndex: [{ value: this.dmpSectionIndex, disabled: disabled }, context.getValidation('dmpSectionIndex').validators], //externalDatasets: [{ value: this.externalDatasets, disabled: disabled }, context.getValidation('externalDatasets').validators], tags: [{ value: this.tags, disabled: disabled }, context.getValidation('tags').validators], //registries: [{ value: this.registries, disabled: disabled }, context.getValidation('registries').validators], @@ -143,6 +146,7 @@ export class DatasetWizardEditorModel { baseContext.validation.push({ key: 'dataRepositories', validators: [BackendErrorValidator(this.validationErrorModel, 'dataRepositories')] }); baseContext.validation.push({ key: 'externalDatasets', validators: [BackendErrorValidator(this.validationErrorModel, 'externalDatasets')] }); baseContext.validation.push({ key: 'dmp', validators: [BackendErrorValidator(this.validationErrorModel, 'dmp')] }); + baseContext.validation.push({ key: 'dmpSectionIndex', validators: [BackendErrorValidator(this.validationErrorModel, 'dmpSectionIndex')] }); baseContext.validation.push({ key: 'datasetProfileDefinition', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] }); baseContext.validation.push({ key: 'tags', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] }); baseContext.validation.push({ key: 'modified', validators: []}); diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts index 3f7210658..70cd17950 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts @@ -95,6 +95,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme finalize: boolean = false; itemId: string; dmpId: string; + dmpSectionIndex: number; newDmpId: string; publicId: string; profileUpdateId: string; @@ -171,6 +172,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme const data: any = this.route.snapshot.data; this.itemId = params['id']; this.dmpId = params['dmpId']; + this.dmpSectionIndex = params['dmpSectionIndex']; this.newDmpId = queryParams['newDmpId']; this.publicId = params['publicId']; this.profileUpdateId = params['updateId']; @@ -266,6 +268,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme this.datasetWizardModel = new DatasetWizardEditorModel(); setTimeout(() => { this.datasetWizardModel.dmp = data; + this.datasetWizardModel.dmpSectionIndex = this.dmpSectionIndex; this.formGroup = this.datasetWizardModel.buildForm(); this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); this.editMode = this.datasetWizardModel.status === DatasetStatus.Draft; @@ -283,6 +286,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme if(result) { this.datasetWizardModel = this.datasetWizardModel.fromModel(result); this.datasetWizardModel.dmp = data; + this.datasetWizardModel.dmpSectionIndex = this.dmpSectionIndex; this.formGroup = this.datasetWizardModel.buildForm(); this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); this.formGroup.get('dmp').disable(); diff --git a/dmp-frontend/src/app/ui/dataset/dataset.routing.ts b/dmp-frontend/src/app/ui/dataset/dataset.routing.ts index c3381dc06..ab3bb27ed 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset.routing.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset.routing.ts @@ -8,7 +8,7 @@ import { DatasetOverviewComponent } from './overview/dataset-overview.component' const routes: Routes = [ { - path: 'new/:dmpId', + path: 'new/:dmpId/:dmpSectionIndex', component: DatasetWizardComponent, canActivate: [AuthGuard], data: { diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html index 34735967d..7a6652240 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html @@ -34,18 +34,27 @@
    -
    +
    DMP Blueprint
    -
      -
    1. Select Blueprint
    2. +
        +
        -
      1. {{section.label}}
      2. +
    - - +
    -
    +
    0.1 Title of DMP *
    @@ -106,177 +115,210 @@
    +
    +
    -->
    -
    diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts index b8cf5cd85..5c2c65ad1 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts @@ -1,5 +1,5 @@ -import { AfterViewInit, Component } from '@angular/core'; +import { AfterViewInit, Component, ViewChild } from '@angular/core'; import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { DmpProfileFieldDataType } from '@app/core/common/enum/dmp-profile-field-type'; @@ -34,9 +34,11 @@ import { AvailableProfilesComponent } from '@app/ui/dmp/editor/available-profile import { DatasetPreviewDialogComponent } from '@app/ui/dmp/dataset-preview/dataset-preview-dialog.component'; import { CdkDragDrop, CdkDropList, CdkDrag, moveItemInArray } from '@angular/cdk/drag-drop'; import { DmpBlueprint, DmpBlueprintDefinition, ExtraFieldType, FieldCategory, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; -import { DmpBlueprintEditor } from './dmp-blueprint-editor.model'; +import { DescriptionTemplatesInSectionEditor, DmpBlueprintEditor, FieldInSectionEditor, SectionDmpBlueprintEditor } from './dmp-blueprint-editor.model'; import { Guid } from '@common/types/guid'; import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { DmpBlueprintListing } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing'; +import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component'; @Component({ @@ -73,6 +75,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie {label: 'Access Rights', type: SystemFieldType.ACCESS_RIGHTS} ]; selectedSystemFields: string[] = []; + systemFieldListPerSection: Array> = new Array(); constructor( private dmpProfileService: DmpProfileService, @@ -112,12 +115,13 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie if (this.dmpProfileId != null) { this.isNew = false; - this.dmpProfileService.getSingle(this.dmpProfileId).pipe(map(data => data as DmpProfile)) + this.dmpProfileService.getSingleBlueprint(this.dmpProfileId).pipe(map(data => data as DmpBlueprint)) .pipe(takeUntil(this._destroyed)) .subscribe(data => { - this.dmpProfileModel = new DmpProfileEditorModel().fromModel(data); - this.formGroup = this.dmpProfileModel.buildForm(); - if (this.dmpProfileModel.status == DmpProfileStatus.Finalized) { + this.dmpBlueprintModel = new DmpBlueprintEditor().fromModel(data); + this.formGroup = this.dmpBlueprintModel.buildForm(); + this.buildSystemFields(); + if (this.dmpBlueprintModel.status == DmpProfileStatus.Finalized) { this.formGroup.disable(); this.viewOnly = true } @@ -133,6 +137,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie setTimeout(() => { // this.formGroup = this.dmpProfileModel.buildForm(); // this.addField(); + this.dmpBlueprintModel.status = DmpProfileStatus.Draft; this.formGroup = this.dmpBlueprintModel.buildForm(); }); this.breadCrumbs = observableOf([{ @@ -143,10 +148,20 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie } }); - this.initDmpBlueptintForm(); - } + buildSystemFields(){ + const sections = this.sectionsArray().controls.length; + for(let i = 0; i < sections; i++){ + let systemFieldsInSection = new Array(); + this.fieldsArray(i).controls.forEach((field) => { + if((field.get('category').value == FieldCategory.SYSTEM || field.get('category').value == 'SYSTEM')){ + systemFieldsInSection.push(this.fieldList.find(f => f.type == field.get('type').value).label); + } + }) + this.systemFieldListPerSection.push(systemFieldsInSection); + } + } filterProfiles(value: string): Observable { const request = new DataTableRequest(null, null, { fields: ['+label'] }); @@ -156,33 +171,17 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie return this._service.searchDMPProfiles(request); } - initDmpBlueptintForm(): void { - this.dmpBlueprintsFormGroup = this.fb.group({ - label: this.fb.control(''), - sections: this.fb.array([]) - }); - } - sectionsArray(): FormArray { - return this.dmpBlueprintsFormGroup.get('sections') as FormArray; - } - - initSection(ordinal: number): FormGroup { - return this.fb.group({ - id: this.fb.control(Guid.create().toString()), - label: this.fb.control(''), - description: this.fb.control(''), - ordinal: this.fb.control(ordinal), - fields: this.fb.array([]), - //systemFields: this.fb.array([]), - descriptionTemplates: this.fb.control(''), - // this.fb.array([this.initDescriptionTemplate()]), - //extraFields: this.fb.array([]) - }); + //return this.dmpBlueprintsFormGroup.get('sections') as FormArray; + return this.formGroup.get('definition').get('sections') as FormArray; } addSection(): void { - this.sectionsArray().push(this.initSection(this.sectionsArray().length)); + const section: SectionDmpBlueprintEditor = new SectionDmpBlueprintEditor(); + section.id = Guid.create().toString(); + section.ordinal = this.sectionsArray().length + 1; + section.hasTemplates = false; + this.sectionsArray().push(section.buildForm()); } removeSection(sectionIndex: number): void { @@ -192,22 +191,17 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie fieldsArray(sectionIndex: number): FormArray { return this.sectionsArray().at(sectionIndex).get('fields') as FormArray; } - - initField(fieldCategory: FieldCategory, fieldType?: number): FormGroup { - return this.fb.group({ - id: this.fb.control(Guid.create().toString()), - category: this.fb.control(fieldCategory), - label: this.fb.control(''), - placeholder: this.fb.control(''), - description: this.fb.control(''), - type: (isNullOrUndefined(fieldType)) ? this.fb.control('') : this.fb.control(fieldType), - required: (!isNullOrUndefined(fieldType) && (fieldType == 0 || fieldType == 1)) ? this.fb.control(true) : this.fb.control(false), - ordinal: this.fb.control('') - }); - } addField(sectionIndex: number, fieldCategory: FieldCategory, fieldType?: number): void { - this.fieldsArray(sectionIndex).push(this.initField(fieldCategory, fieldType)); + const field: FieldInSectionEditor = new FieldInSectionEditor(); + field.id = Guid.create().toString(); + field.ordinal = this.fieldsArray(sectionIndex).length + 1; + field.category = fieldCategory; + if(!isNullOrUndefined(fieldType)){ + field.type = fieldType + } + field.required = (!isNullOrUndefined(fieldType) && (fieldType == 0 || fieldType == 1)) ? true : false; + this.fieldsArray(sectionIndex).push(field.buildForm()); } removeField(sectionIndex: number, fieldIndex: number): void { @@ -231,7 +225,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie } addSystemField(sectionIndex: number, systemField?: SystemFieldType): void { - this.fieldsArray(sectionIndex).push(this.initField(FieldCategory.SYSTEM, systemField)); + this.addField(sectionIndex, FieldCategory.SYSTEM, systemField); } transfromEnumToString(type: SystemFieldType): string{ @@ -255,7 +249,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie for (let s in this.sectionsArray().controls) { if (i != sectionIndex) { for (let f of this.fieldsArray(i).controls) { - if (f.get('category').value == FieldCategory.SYSTEM && f.get('type').value == systemField) { + if ((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField) { return true; } } @@ -272,7 +266,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie removeSystemField(sectionIndex: number, systemField: SystemFieldType): void { let i = 0; for(let f of this.fieldsArray(sectionIndex).controls){ - if(f.get('category').value == FieldCategory.SYSTEM && f.get('type').value == systemField){ + if((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField){ this.fieldsArray(sectionIndex).removeAt(i); return; } @@ -284,15 +278,6 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie return this.sectionsArray().at(sectionIndex).get('descriptionTemplates') as FormArray; } - initDescriptionTemplate(): FormGroup { - return this.fb.group({ - descriptionTemplateId: this.fb.control(''), - label: this.fb.control(''), - minMultiplicity: this.fb.control(''), - maxMultiplicity: this.fb.control('') - }); - } - addDescriptionTemplate(descriptionTemplate, sectionIndex: number): void { this.descriptionTemplatesArray(sectionIndex).push(this.fb.group({ label: this.fb.control(descriptionTemplate.value) @@ -305,22 +290,10 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie extraFieldsArray(sectionIndex: number): FormArray { return this.sectionsArray().at(sectionIndex).get('extraFields') as FormArray; - } + } - initExtraField(): FormGroup { - return this.fb.group({ - id: this.fb.control(Guid.create().toString()), - label: this.fb.control(''), - placeholder: this.fb.control(''), - description: this.fb.control(''), - type: this.fb.control(''), - required: this.fb.control(false), - ordinal: this.fb.control('') - }); - } - addExtraField(sectionIndex: number): void { - this.fieldsArray(sectionIndex).push(this.initField(FieldCategory.EXTRA)); + this.addField(sectionIndex, FieldCategory.EXTRA); } removeExtraField(sectionIndex: number, fieldIndex: number): void { @@ -343,9 +316,6 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie } } - onSubmitTest(): void { - } - drop(event: CdkDragDrop, sectionIndex: number) { moveItemInArray(this.fieldsArray(sectionIndex).controls, event.previousIndex, event.currentIndex); moveItemInArray(this.fieldsArray(sectionIndex).value, event.previousIndex, event.currentIndex); @@ -371,86 +341,58 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie // this.dmpBlueprintsFormGroup.reset(); // } - canGoUp(index: number): boolean { - return index > 0; - } - - canGoDown(index: number): boolean { - return index < (this.sectionsArray().length - 1); - } - onRemoveTemplate(event, sectionIndex: number) { - // let found = false; - // const profiles = this.descriptionTemplatesArray(sectionIndex).value;//this.formGroup.get('profiles').value; - // this.formGroup.get('datasets')['controls'].forEach(element => { - // if (element.get('profile').value.id === event.id) { - // found = true; - // this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-REMOVE-TEMPLATE'), SnackBarNotificationLevel.Success); - // } - // }); - // if (found) { - // this.formGroup.get('profiles').setValue(profiles); - // this.profilesAutoCompleteConfiguration = { - // filterFn: this.filterProfiles.bind(this), - // initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), - // displayFn: (item) => item['label'], - // titleFn: (item) => item['label'], - // subtitleFn: (item) => item['description'], - // popupItemActionIcon: 'visibility' - // }; - - // } + const profiles = this.descriptionTemplatesArray(sectionIndex).controls; + const foundIndex = profiles.findIndex(profile => profile.get('descriptionTemplateId').value === event.id); + foundIndex !== -1 && this.descriptionTemplatesArray(sectionIndex).removeAt(foundIndex); } - onPreviewTemplate(event, sectionIndex: number) { - const dialogRef = this.dialog.open(DatasetPreviewDialogComponent, { - width: '590px', - minHeight: '200px', - restoreFocus: false, - data: { - template: event - }, - panelClass: 'custom-modalbox' - }); - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - if (result) { - let profiles = this.descriptionTemplatesArray(sectionIndex).value;//this.formGroup.get('profiles').value; - profiles.push(event); - this.descriptionTemplatesArray(sectionIndex).setValue(profiles);//this.formGroup.get('profiles').setValue(profiles); - this.profilesAutoCompleteConfiguration = { - filterFn: this.filterProfiles.bind(this), - initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), - displayFn: (item) => item['label'], - titleFn: (item) => item['label'], - subtitleFn: (item) => item['description'], - popupItemActionIcon: 'visibility' - }; - } - }); - } - onOptionSelected(sectionIndex: number){ - try{ - const profiles = this.descriptionTemplatesArray(sectionIndex).value as {id:string, label:string}[];//this.formGroup.get('profiles').value as {id:string, label:string}[]; - const profileCounts: Map = new Map(); - profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id): 0 ) + 1)); - const duplicateProfiles = profiles.filter((value) => { - let isOk = profileCounts.get(value.id) > 1; - if (isOk) { - profileCounts.set(value.id, 0); - } - return isOk; - }); - duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1)); - profiles.sort((a,b)=> a.label.localeCompare(b.label)); - } - catch{ - console.info('Could not sort Dataset Templates') - } + // onPreviewTemplate(event, sectionIndex: number) { + // const dialogRef = this.dialog.open(DatasetPreviewDialogComponent, { + // width: '590px', + // minHeight: '200px', + // restoreFocus: false, + // data: { + // template: event + // }, + // panelClass: 'custom-modalbox' + // }); + // dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + // if (result) { + // let profiles = this.sectionsArray().at(sectionIndex).get('descriptionTemplates').value;//this.formGroup.get('profiles').value; + // const profile: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor(); + // profile.id = Guid.create().toString(); + // profile.descriptionTemplateId = event.id; + // profile.label = event.label; + // profiles.push(profile.buildForm()); + // this.sectionsArray().at(sectionIndex).get('descriptionTemplates').setValue(profiles);//this.formGroup.get('profiles').setValue(profiles); + // this.profilesAutoCompleteConfiguration = { + // filterFn: this.filterProfiles.bind(this), + // initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + // displayFn: (item) => item['label'], + // titleFn: (item) => item['label'], + // subtitleFn: (item) => item['description'], + // popupItemActionIcon: 'visibility' + // }; + // } + // }); + // } + + onOptionSelected(item, sectionIndex){ + const profile: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor(); + profile.id = Guid.create().toString(); + profile.descriptionTemplateId = item.id; + profile.label = item.label; + this.descriptionTemplatesArray(sectionIndex).push(profile.buildForm()); } formSubmit(): void { this.formService.touchAllFormFields(this.formGroup); if (!this.isFormValid()) { return; } + if(!this.hasDescriptionTemplates()) { + this.showValidationErrorsDialog(undefined, ["At least one section should have description templates."]); + return; + } this.onSubmit(); } @@ -458,8 +400,27 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie return this.formGroup.valid; } + hasDescriptionTemplates(): boolean { + const dmpBlueprint: DmpBlueprint = this.formGroup.value; + return (dmpBlueprint.definition.sections.filter(s => s.hasTemplates == true).length > 0) ? true : false; + } + + private showValidationErrorsDialog(projectOnly?: boolean, errmess?: string[]) { + + const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, { + disableClose: true, + autoFocus: false, + restoreFocus: false, + data: { + errorMessages:errmess, + projectOnly: projectOnly + }, + }); + + } + onSubmit(): void { - this.dmpProfileService.createDmp(this.formGroup.value) + this.dmpProfileService.createBlueprint(this.formGroup.value) .pipe(takeUntil(this._destroyed)) .subscribe( complete => this.onCallbackSuccess(), From 6f5fcabc7957c4abecdfa1f7c48bb45b228ad242 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Tue, 12 Sep 2023 15:24:25 +0300 Subject: [PATCH 049/110] add db scripts: inserting default blueprint, attach that blueprint as profile of each dmp, make each dataset section index correspond to the default blueprint last section --- ...olumn_to_Dataset_and_DMPDatasetProfile.sql | 2 +- ...nt_and_add_dmpSectionIndex_to datasets.sql | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 dmp-db-scema/updates/00.00.016_Insert_default_blueprint_and_add_dmpSectionIndex_to datasets.sql diff --git a/dmp-db-scema/updates/00.00.015_Add_new_column_to_Dataset_and_DMPDatasetProfile.sql b/dmp-db-scema/updates/00.00.015_Add_new_column_to_Dataset_and_DMPDatasetProfile.sql index b0cd7df0c..b6729b9fe 100644 --- a/dmp-db-scema/updates/00.00.015_Add_new_column_to_Dataset_and_DMPDatasetProfile.sql +++ b/dmp-db-scema/updates/00.00.015_Add_new_column_to_Dataset_and_DMPDatasetProfile.sql @@ -1,5 +1,5 @@ DO $$DECLARE - this_version CONSTANT varchar := '00.00.014'; + this_version CONSTANT varchar := '00.00.015'; BEGIN PERFORM * FROM "DBVersion" WHERE version = this_version; IF FOUND THEN RETURN; END IF; diff --git a/dmp-db-scema/updates/00.00.016_Insert_default_blueprint_and_add_dmpSectionIndex_to datasets.sql b/dmp-db-scema/updates/00.00.016_Insert_default_blueprint_and_add_dmpSectionIndex_to datasets.sql new file mode 100644 index 000000000..bb61227b6 --- /dev/null +++ b/dmp-db-scema/updates/00.00.016_Insert_default_blueprint_and_add_dmpSectionIndex_to datasets.sql @@ -0,0 +1,20 @@ +DO $$DECLARE + this_version CONSTANT varchar := '00.00.016'; +BEGIN + PERFORM * FROM "DBVersion" WHERE version = this_version; + IF FOUND THEN RETURN; END IF; + +INSERT INTO public."DMPProfile" VALUES ('1374c46d-55b5-472a-8e10-c6ee8c0b5f7f', 'Dmp Default Blueprint', '
    ',1, now(),now()); +UPDATE public."DMP" SET ("Profile") = '1374c46d-55b5-472a-8e10-c6ee8c0b5f7f' WHERE "Profile" IS NULL; +UPDATE public."Dataset" SET ("DmpSectionIndex") = '3' WHERE "DmpSectionIndex" IS NULL; +UPDATE public."DMPDatasetProfile" SET ("data") = '{"dmpSectionIndex":[3]}' WHERE "data" IS NULL; + +ALTER TABLE public."Dataset" +ALTER COLUMN "DmpSectionIndex" SET NOT NULL; + +ALTER TABLE public."DMPDatasetProfile" +ALTER COLUMN "data" SET NOT NULL; + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.016', '2023-09-12 12:00:00.000000+02', now(), 'Insert default blueprint, update profile of existing dmps and update DmpSectionIndex for each dataset.'); + +END$$; \ No newline at end of file From 6154a5fa51beb2e1b93ce771e212815dee313773 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Tue, 12 Sep 2023 15:36:06 +0300 Subject: [PATCH 050/110] fix associated dmps bugs in DMP table, new/existing DmpDatasetProfile entries were not saved/updated --- .../dao/entities/DmpDatasetProfileDao.java | 9 ++++ .../entities/DmpDatasetProfileDaoImpl.java | 52 +++++++++++++++++++ .../main/java/eu/eudat/data/entities/DMP.java | 2 +- .../data/entities/DMPDatasetProfile.java | 1 - .../elastic/entities/DatasetTempalate.java | 24 +++++++++ .../managers/DataManagementPlanManager.java | 17 ++++-- .../logic/managers/DatasetWizardManager.java | 2 +- .../mapper/elastic/DatasetTemplateMapper.java | 18 +++++-- .../operations/DatabaseRepository.java | 2 + .../operations/DatabaseRepositoryImpl.java | 11 ++++ .../models/data/dmp/AssociatedProfile.java | 17 ++++-- .../models/data/dmp/DataManagementPlan.java | 4 +- .../dmp/DataManagementPlanEditorModel.java | 2 +- .../DataManagementPlanNewVersionModel.java | 2 +- .../data/quickwizard/DmpQuickWizardModel.java | 2 +- .../eudat/models/rda/mapper/DmpRDAMapper.java | 16 +++--- .../AssociatedProfilePublicModel.java | 15 ++++-- .../DataManagementPlanPublicModel.java | 1 + 18 files changed, 170 insertions(+), 27 deletions(-) create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDao.java create mode 100644 dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDaoImpl.java diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDao.java new file mode 100644 index 000000000..9febf7abf --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDao.java @@ -0,0 +1,9 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccessLayer; +import eu.eudat.data.entities.DMPDatasetProfile; + +import java.util.UUID; + +public interface DmpDatasetProfileDao extends DatabaseAccessLayer { +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDaoImpl.java new file mode 100644 index 000000000..6c65b804f --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDaoImpl.java @@ -0,0 +1,52 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccess; +import eu.eudat.data.dao.databaselayer.service.DatabaseService; +import eu.eudat.data.entities.Content; +import eu.eudat.data.entities.DMPDatasetProfile; +import eu.eudat.queryable.QueryableList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Service("dmpDatasetProfileDao") +public class DmpDatasetProfileDaoImpl extends DatabaseAccess implements DmpDatasetProfileDao { + @Autowired + public DmpDatasetProfileDaoImpl(DatabaseService databaseService) { + super(databaseService); + } + + @Override + public DMPDatasetProfile createOrUpdate(DMPDatasetProfile item) { + return this.getDatabaseService().createOrUpdate(item, DMPDatasetProfile.class); + } + + @Override + @Async + public CompletableFuture createOrUpdateAsync(DMPDatasetProfile item) { + return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); + } + + @Override + public DMPDatasetProfile find(UUID id) { + return this.getDatabaseService().getQueryable(DMPDatasetProfile.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle(); + } + + @Override + public DMPDatasetProfile find(UUID id, String hint) { + throw new UnsupportedOperationException(); + } + + @Override + public void delete(DMPDatasetProfile item) { + this.getDatabaseService().delete(item); + } + + @Override + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(DMPDatasetProfile.class); + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java index dcfbdb698..60277ead5 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java @@ -112,7 +112,7 @@ public class DMP implements DataEntity { /*@Type(type = "eu.eudat.configurations.typedefinition.XMLType") @Column(name = "\"AssociatedDmps\"", columnDefinition = "xml", nullable = true) private String associatedDmps;*/ - @OneToMany(fetch = FetchType.LAZY) + @OneToMany(fetch = FetchType.LAZY, mappedBy = "dmp") private Set associatedDmps; diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMPDatasetProfile.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMPDatasetProfile.java index 8ee7a59fc..816ec0410 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMPDatasetProfile.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMPDatasetProfile.java @@ -2,7 +2,6 @@ package eu.eudat.data.entities; import eu.eudat.queryable.queryableentity.DataEntity; import org.hibernate.annotations.GenericGenerator; -import org.hibernate.annotations.Type; import javax.persistence.*; import java.util.List; diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/DatasetTempalate.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/DatasetTempalate.java index c62c32986..a6a6a6782 100644 --- a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/DatasetTempalate.java +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/DatasetTempalate.java @@ -1,14 +1,18 @@ package eu.eudat.elastic.entities; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import org.elasticsearch.common.xcontent.XContentBuilder; import java.io.IOException; +import java.util.HashMap; import java.util.Map; import java.util.UUID; public class DatasetTempalate implements ElasticEntity { private UUID id; private String name; + private Map data; public UUID getId() { return id; @@ -26,11 +30,25 @@ public class DatasetTempalate implements ElasticEntity { this.name = name; } + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + @Override public XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException { builder.startObject(); builder.field("id", this.id.toString()); builder.field("name", this.name); + if(this.data != null) { + builder.field("data", new ObjectMapper().writeValueAsString(this.data)); + } + else{ + builder.field("data", ""); + } builder.endObject(); return builder; } @@ -39,6 +57,12 @@ public class DatasetTempalate implements ElasticEntity { public DatasetTempalate fromElasticEntity(Map fields) { this.id = UUID.fromString((String) fields.get("id")); this.name = (String) fields.get("name"); + try { + this.data = new ObjectMapper().readValue((String) fields.get("data"), new TypeReference>() {}); + } + catch (Exception e){ + this.data = new HashMap<>(); + } return this; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index 6a68163cb..6fddb00a3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -447,6 +447,7 @@ public class DataManagementPlanManager { * Data Management * */ + @Transactional public DMP createOrUpdate(DataManagementPlanEditorModel dataManagementPlan, Principal principal) throws Exception { boolean setNotification = false; if (dataManagementPlan.getId() != null) { @@ -463,7 +464,7 @@ public class DataManagementPlanManager { } List datasetList = dmp1.getDataset().stream().filter(dataset -> dataset.getStatus() != 99).collect(Collectors.toList()); for (Dataset dataset : datasetList) { - if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getId())).findAny().orElse(null) == null) + if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getDescriptionTemplateId())).findAny().orElse(null) == null) throw new Exception("Dataset Template for Dataset Description is missing from the DMP."); } if (dataManagementPlan.getStatus() == (int) DMP.DMPStatus.FINALISED.getValue() && dmp1.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) @@ -519,9 +520,19 @@ public class DataManagementPlanManager { assignFunderUserIfInternal(newDmp, user); assignProjectUserIfInternal(newDmp, user); + if(newDmp.getId() != null){ + for(DMPDatasetProfile dmpDatasetProfile : newDmp.getAssociatedDmps()){ + apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().createOrUpdate(dmpDatasetProfile); + } + } + apiContext.getOperationsContext().getDatabaseRepository().getGrantDao().createOrUpdate(newDmp.getGrant()); newDmp = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(newDmp); + for(DMPDatasetProfile dmpDatasetProfile : newDmp.getAssociatedDmps()){ + apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().createOrUpdate(dmpDatasetProfile); + } + if (dataManagementPlan.getUsers() != null && !dataManagementPlan.getUsers().isEmpty()) { clearUsers(newDmp); for (UserInfoListingModel userListing : dataManagementPlan.getUsers()) { @@ -597,7 +608,7 @@ public class DataManagementPlanManager { throw new Exception("Another user have already edit that DMP."); } for (DatasetWizardModel dataset : dataManagementPlan.getDatasets()) { - if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getId())).findAny().orElse(null) == null) + if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getDescriptionTemplateId())).findAny().orElse(null) == null) throw new Exception("Dataset Template for Dataset Description is missing from the DMP."); } if (dataManagementPlan.getStatus() == (int) DMP.DMPStatus.FINALISED.getValue() && dmp1.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) @@ -1997,7 +2008,7 @@ public class DataManagementPlanManager { try { dataset.setProfile(databaseRepository.getDatasetProfileDao().find(das.getProfile())); } catch (Exception ignored) { - dataset.setProfile(databaseRepository.getDatasetProfileDao().find(associatedProfiles.get(0).getId())); + dataset.setProfile(databaseRepository.getDatasetProfileDao().find(associatedProfiles.get(0).getDescriptionTemplateId())); } dataset.setProperties(objectMapper.writeValueAsString(das.getFieldImportModels())); dataset.setStatus((short) 0); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java index 20cb2dc9c..123f70881 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java @@ -40,7 +40,7 @@ public class DatasetWizardManager { return new LinkedList<>(); } DatasetProfileCriteria criteria = new DatasetProfileCriteria(); - criteria.setIds(dataManagementPlan.getProfiles().stream().map(AssociatedProfile::getId).collect(Collectors.toList())); + criteria.setIds(dataManagementPlan.getProfiles().stream().map(AssociatedProfile::getDescriptionTemplateId).collect(Collectors.toList())); List descriptionTemplates = profileDao.getWithCriteria(criteria).toList(); criteria.setIds(null); criteria.setGroupIds(descriptionTemplates.stream().map(DescriptionTemplate::getGroupId).collect(Collectors.toList())); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java index 65cd3f598..75e979175 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java @@ -1,14 +1,26 @@ package eu.eudat.logic.mapper.elastic; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import eu.eudat.data.entities.DMPDatasetProfile; import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.elastic.entities.DatasetTempalate; +import java.util.HashMap; +import java.util.Map; + public class DatasetTemplateMapper { - public static DatasetTempalate toElastic(DescriptionTemplate profile) { + public static DatasetTempalate toElastic(DMPDatasetProfile profile) { DatasetTempalate elastic = new DatasetTempalate(); - elastic.setId(profile.getId()); - elastic.setName(profile.getLabel()); + elastic.setId(profile.getDatasetprofile().getId()); + elastic.setName(profile.getDatasetprofile().getLabel()); + try { + elastic.setData(new ObjectMapper().readValue(profile.getData(), new TypeReference>() {})); + } + catch (Exception e){ + elastic.setData(new HashMap<>()); + } return elastic; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java index b10ecaa0e..1d5e10df8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java @@ -14,6 +14,8 @@ public interface DatabaseRepository { DMPDao getDmpDao(); + DmpDatasetProfileDao getDmpDatasetProfileDao(); + OrganisationDao getOrganisationDao(); GrantDao getGrantDao(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java index c72baec18..ccbb80304 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java @@ -16,6 +16,7 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { private DatasetDao datasetDao; private DatasetProfileDao datasetProfileDao; private DMPDao dmpDao; + private DmpDatasetProfileDao dmpDatasetProfileDao; private OrganisationDao organisationDao; private GrantDao GrantDao; private RegistryDao registryDao; @@ -64,6 +65,11 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { this.dmpDao = dmpDao; } + @Autowired + private void setDmpDatasetProfileDao(DmpDatasetProfileDao dmpDatasetProfileDao) { + this.dmpDatasetProfileDao = dmpDatasetProfileDao; + } + @Autowired private void setOrganisationDao(OrganisationDao organisationDao) { this.organisationDao = organisationDao; @@ -114,6 +120,11 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { return dmpDao; } + @Override + public DmpDatasetProfileDao getDmpDatasetProfileDao() { + return dmpDatasetProfileDao; + } + @Override public OrganisationDao getOrganisationDao() { return organisationDao; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/AssociatedProfile.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/AssociatedProfile.java index 46408dfa4..13343fa5b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/AssociatedProfile.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/AssociatedProfile.java @@ -11,6 +11,7 @@ import java.util.UUID; public class AssociatedProfile implements XmlSerializable { private UUID id; + private UUID descriptionTemplateId; private String label; private Map data; @@ -22,6 +23,14 @@ public class AssociatedProfile implements XmlSerializable { this.id = id; } + public UUID getDescriptionTemplateId() { + return descriptionTemplateId; + } + + public void setDescriptionTemplateId(UUID descriptionTemplateId) { + this.descriptionTemplateId = descriptionTemplateId; + } + public String getLabel() { return label; } @@ -41,27 +50,27 @@ public class AssociatedProfile implements XmlSerializable { @Override public Element toXml(Document doc) { Element profile = doc.createElement("profile"); - profile.setAttribute("profileId", this.id.toString()); + profile.setAttribute("profileId", this.descriptionTemplateId.toString()); profile.setAttribute("label", this.label); return profile; } @Override public AssociatedProfile fromXml(Element item) { - this.id = UUID.fromString(item.getAttribute("profileId")); + this.descriptionTemplateId = UUID.fromString(item.getAttribute("profileId")); this.label = item.getAttribute("label"); return this; } public DescriptionTemplate toData() { DescriptionTemplate profile = new DescriptionTemplate(); - profile.setId(this.id); + profile.setId(this.descriptionTemplateId); profile.setLabel(this.label); return profile; } public AssociatedProfile fromData(DescriptionTemplate entity) { - this.id = entity.getId(); + this.descriptionTemplateId = entity.getId(); this.label = entity.getLabel(); return this; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java index 2de902349..002cd9bf8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java @@ -262,6 +262,7 @@ public class DataManagementPlan implements DataModel { this.profiles = new LinkedList<>(); for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile()); + associatedProfile.setId(dmpDescriptionProfile.getId()); try { associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); } @@ -331,7 +332,7 @@ public class DataManagementPlan implements DataModel { Set dmpDatasetProfiles = new HashSet<>(); for (AssociatedProfile profile : this.profiles) { DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile(); - dmpDatasetProfile.setId(UUID.randomUUID()); + dmpDatasetProfile.setId(profile.getId()); dmpDatasetProfile.setDmp(dataManagementPlanEntity); dmpDatasetProfile.setDatasetprofile(profile.toData()); dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData())); @@ -380,6 +381,7 @@ public class DataManagementPlan implements DataModel { this.profiles = new LinkedList<>(); for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile()); + associatedProfile.setId(dmpDescriptionProfile.getId()); try { associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java index 1fde4e113..4f3f0b644 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java @@ -369,7 +369,7 @@ public class DataManagementPlanEditorModel implements DataModel dmpDatasetProfiles = new HashSet<>(); for (AssociatedProfile profile : this.profiles) { DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile(); - dmpDatasetProfile.setId(UUID.randomUUID()); + dmpDatasetProfile.setId(profile.getId()); dmpDatasetProfile.setDmp(dataManagementPlanEntity); dmpDatasetProfile.setDatasetprofile(profile.toData()); dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData())); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java index a45246e2e..ed62cda3e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java @@ -265,7 +265,7 @@ public class DataManagementPlanNewVersionModel implements DataModel dmpDatasetProfiles = new HashSet<>(); for (AssociatedProfile profile : this.profiles) { DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile(); - dmpDatasetProfile.setId(UUID.randomUUID()); + dmpDatasetProfile.setId(profile.getId()); dmpDatasetProfile.setDmp(entity); dmpDatasetProfile.setDatasetprofile(profile.toData()); dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData())); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java index 427172351..5f2be414a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java @@ -112,7 +112,7 @@ public class DmpQuickWizardModel { DescriptionTemplate descriptionTemplate = new DescriptionTemplate(); descriptionTemplate.setDefinition(this.datasetProfile.getLabel()); descriptionTemplate.setLabel(this.datasetProfile.getLabel()); - descriptionTemplate.setId(this.datasetProfile.getId()); + descriptionTemplate.setId(this.datasetProfile.getDescriptionTemplateId()); return descriptionTemplate; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java index 5272cc6cd..c55d0d66c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java @@ -125,16 +125,15 @@ public class DmpRDAMapper { entity.setDois(new HashSet<>()); } } - if (((List) rda.getAdditionalProperties().get("templates")) != null && !((List) rda.getAdditionalProperties().get("templates")).isEmpty()) { - entity.setAssociatedDmps(((List) rda.getAdditionalProperties().get("templates")).stream().map(this::getProfile).filter(Objects::nonNull).collect(Collectors.toSet())); + if (((List) rda.getAdditionalProperties().get("templates")) != null && !((List) rda.getAdditionalProperties().get("templates")).isEmpty() && entity.getId() != null) { + entity.setAssociatedDmps(((List) rda.getAdditionalProperties().get("templates")).stream().map(x -> this.getProfile(x, entity.getId())).filter(Objects::nonNull).collect(Collectors.toSet())); } if (entity.getAssociatedDmps() == null) { entity.setAssociatedDmps(new HashSet<>()); } - if (profiles != null) { + if (profiles != null && entity.getId() != null) { for (String profile : profiles) { - DescriptionTemplate exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(profile)); - entity.getAssociatedDmps().add(exProfile); + entity.getAssociatedDmps().add(this.getProfile(profile, entity.getId())); } } if (rda.getContributor() != null && !rda.getContributor().isEmpty() && rda.getContributor().get(0).getContributorId() != null) { @@ -159,7 +158,10 @@ public class DmpRDAMapper { return entity; } - private DescriptionTemplate getProfile(String id) { - return apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().asQueryable().where(((builder, root) -> builder.equal(root.get("id"), UUID.fromString(id)))).getSingleOrDefault(); + private DMPDatasetProfile getProfile(String descriptionTemplateId, UUID dmpId) { + return apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().asQueryable().where(((builder, root) -> builder.and( + builder.equal(root.get("datasetprofile"), UUID.fromString(descriptionTemplateId)), + builder.equal(root.get("dmp"), dmpId)) + )).getSingleOrDefault(); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java index 228f843e5..b04f57678 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java @@ -10,6 +10,7 @@ import java.util.UUID; public class AssociatedProfilePublicModel implements XmlSerializable { private UUID id; + private UUID descriptionTemplateId; private String label; private Map data; @@ -21,6 +22,14 @@ public class AssociatedProfilePublicModel implements XmlSerializable(); for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { AssociatedProfilePublicModel associatedProfile = new AssociatedProfilePublicModel().fromData(dmpDescriptionProfile.getDatasetprofile()); + associatedProfile.setId(dmpDescriptionProfile.getId()); try { associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); } From 29f5b6a6ccc3a15e46e760b0f2b4e0e3f29b455b Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Tue, 12 Sep 2023 15:38:23 +0300 Subject: [PATCH 051/110] fix editing dmp page, add section templates to new dataset page --- .../src/app/core/formatting.module.ts | 10 +- .../dmp-dataset-profile.ts | 1 + .../app/core/pipes/dataset-in-section.pipe.ts | 18 + .../editor/dmp-profile-editor.component.html | 2 +- .../dataset-wizard.component.html | 2 +- .../dataset-wizard.component.ts | 10 +- .../dmp-editor-blueprint.component.html | 37 +- .../dmp-editor-blueprint.component.scss | 22 + .../dmp-editor-blueprint.component.ts | 401 ++++++++++++++---- dmp-frontend/src/app/ui/dmp/dmp.routing.ts | 12 +- .../dmp-editor/dmp-editor-wizard-model.ts | 2 +- 11 files changed, 405 insertions(+), 112 deletions(-) create mode 100644 dmp-frontend/src/app/core/pipes/dataset-in-section.pipe.ts diff --git a/dmp-frontend/src/app/core/formatting.module.ts b/dmp-frontend/src/app/core/formatting.module.ts index cac6237cb..fc082e27b 100644 --- a/dmp-frontend/src/app/core/formatting.module.ts +++ b/dmp-frontend/src/app/core/formatting.module.ts @@ -9,6 +9,7 @@ import { JsonParserPipe } from './pipes/json-parser.pipe'; import { DateTimeCultureFormatPipe } from './pipes/date-time-culture-format.pipe'; import {FieldValuePipe} from "@app/core/pipes/field-value.pipe"; import {ColumnClassPipe} from "@app/core/pipes/column-class.pipe"; +import { DatasetInSectioPipe } from './pipes/dataset-in-section.pipe'; // // @@ -25,7 +26,8 @@ import {ColumnClassPipe} from "@app/core/pipes/column-class.pipe"; DateTimeCultureFormatPipe, JsonParserPipe, FieldValuePipe, - ColumnClassPipe + ColumnClassPipe, + DatasetInSectioPipe ], exports: [ NgForLimitPipe, @@ -35,7 +37,8 @@ import {ColumnClassPipe} from "@app/core/pipes/column-class.pipe"; DateTimeCultureFormatPipe, JsonParserPipe, FieldValuePipe, - ColumnClassPipe + ColumnClassPipe, + DatasetInSectioPipe ], providers: [ EnumUtils, @@ -47,7 +50,8 @@ import {ColumnClassPipe} from "@app/core/pipes/column-class.pipe"; DateTimeCultureFormatPipe, JsonParserPipe, FieldValuePipe, - ColumnClassPipe + ColumnClassPipe, + DatasetInSectioPipe ] }) export class FormattingModule { } diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile.ts b/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile.ts index 9c40d752e..043f4d525 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile.ts @@ -2,6 +2,7 @@ import { DmpDatasetProfileSectionsFormModel } from "./dmp-dataset-profile-sectio export interface DmpDatasetProfile { id: string; + descriptionTemplateId: string; label: string; data: DmpDatasetProfileSectionsFormModel; } \ No newline at end of file diff --git a/dmp-frontend/src/app/core/pipes/dataset-in-section.pipe.ts b/dmp-frontend/src/app/core/pipes/dataset-in-section.pipe.ts new file mode 100644 index 000000000..7d0e12f6d --- /dev/null +++ b/dmp-frontend/src/app/core/pipes/dataset-in-section.pipe.ts @@ -0,0 +1,18 @@ +import { Pipe, PipeTransform } from "@angular/core"; +import { FormGroup } from "@angular/forms"; + +@Pipe({ + name: 'datasetInSection' +}) +export class DatasetInSectioPipe implements PipeTransform{ + + transform(datasets: FormGroup[], args: string): FormGroup[] { + let values = []; + for(var dataset of datasets){ + if(dataset.get('dmpSectionIndex').value == args){ + values.push(dataset); + } + } + return values; + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html index 65f6940c2..5c9c18514 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html @@ -172,7 +172,7 @@
    Placeholder - +
    diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html index d6c8feb05..6b84a8950 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html @@ -141,7 +141,7 @@
    - +
    diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts index 70cd17950..c968f3c46 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts @@ -62,6 +62,7 @@ import {CheckDeactivateBaseComponent} from '@app/library/deactivate/deactivate.c import {PrefillDatasetComponent} from "@app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component"; import {ToCEntry, ToCEntryType} from "@app/ui/misc/dataset-description-form/dataset-description.component"; import {dispatchFakeEvent} from "@angular/cdk/testing/testbed/fake-events"; +import { DmpDatasetProfile } from '@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile'; @Component({ selector: 'app-dataset-wizard-component', @@ -96,6 +97,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme itemId: string; dmpId: string; dmpSectionIndex: number; + availableDescriptionTemplates: DatasetProfileModel[] = []; newDmpId: string; publicId: string; profileUpdateId: string; @@ -172,7 +174,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme const data: any = this.route.snapshot.data; this.itemId = params['id']; this.dmpId = params['dmpId']; - this.dmpSectionIndex = params['dmpSectionIndex']; + this.dmpSectionIndex = parseInt(params['dmpSectionIndex']); this.newDmpId = queryParams['newDmpId']; this.publicId = params['publicId']; this.profileUpdateId = params['updateId']; @@ -270,6 +272,10 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme this.datasetWizardModel.dmp = data; this.datasetWizardModel.dmpSectionIndex = this.dmpSectionIndex; this.formGroup = this.datasetWizardModel.buildForm(); + let profiles = this.datasetWizardModel.dmp.profiles.filter(profile => profile.data.dmpSectionIndex.includes(this.dmpSectionIndex)); + for(var profile of profiles){ + this.availableDescriptionTemplates.push({id: profile.descriptionTemplateId, label: profile.label, description: ""}) + } this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); this.editMode = this.datasetWizardModel.status === DatasetStatus.Draft; this.formGroup.get('dmp').disable(); @@ -278,7 +284,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme minHeight: '200px', restoreFocus: false, data: { - availableProfiles: this.formGroup.get('dmp').value.profiles, + availableProfiles: this.availableDescriptionTemplates, }, panelClass: 'custom-modalbox' }); diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html index 7a6652240..12f1dd67d 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html @@ -1,6 +1,6 @@
    -
    +
    @@ -8,25 +8,25 @@
    {{'DMP-EDITOR.TITLE.EDIT-DMP' | translate}}
    - +
    {{ formGroup.get('label').value }} ({{'DMP-EDITOR.CHANGES' | translate}})
    - + - - +
    +
    @@ -42,9 +42,18 @@
  • {{section.label}}
  • +
      +
    1. +
      +
      {{'DMP-EDITOR.STEPPER.DATASET' | translate}}: {{ dataset.get('label').value }}
      + close + check +
      +
    2. +
    -
    +
    0.1 Title of DMP *
    @@ -116,7 +125,7 @@
    -
    +
    - +
    - +
    - +
    @@ -294,7 +303,7 @@
    Description templates
    {{'DMP-EDITOR.FIELDS.SELECT-TEMPLATE' | translate}} - + {{formGroup.get('profiles').getError('backendError').message}} diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss index 8e0b97e36..3d4fd45d8 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss @@ -38,6 +38,10 @@ } } +.datasetsInSection { + counter-reset: item +} + .title { text-align: left; font-weight: 400; @@ -280,6 +284,24 @@ mat-icon.size-16 { margin: 3rem 0rem 3rem 0rem; } +.changes { + font-weight: 400; + color: #ffffff; +} + +.discard-btn { + background: transparent; + border: 1px solid #ffffff; + color: white; + border-radius: 30px; + opacity: 1; + width: 110px; + height: 40px; + display: flex; + justify-content: center; + align-items: center; +} + a { color: #000000; } diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts index d81048a0f..b77b73ca1 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts @@ -13,7 +13,6 @@ import { FunderFormModel } from '../editor/grant-tab/funder-form-model'; import { GrantTabModel } from '../editor/grant-tab/grant-tab-model'; import { ProjectFormModel } from '../editor/grant-tab/project-form-model'; import { AuthService } from '@app/core/services/auth/auth.service'; -import { BaseComponent } from '@common/base/base.component'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; import { LanguageInfoService } from '@app/core/services/culture/language-info-service'; @@ -22,7 +21,7 @@ import { UserModel } from '@app/core/model/user/user'; import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; import { TranslateService } from '@ngx-translate/core'; import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service'; -import { Observable } from 'rxjs'; +import { Observable, interval } from 'rxjs'; import { ExternalSourceItemModel } from '@app/core/model/external-sources/external-source-item'; import { OrganisationService } from '@app/core/services/organisation/organisation.service'; import { MatDialog } from '@angular/material/dialog'; @@ -40,13 +39,22 @@ import { FormValidationErrorsDialogComponent } from '@common/forms/form-validati import { DmpStatus } from '@app/core/common/enum/dmp-status'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; import { DmpModel } from '@app/core/model/dmp/dmp'; -import { Router } from '@angular/router'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { DmpToDatasetDialogComponent } from '../dmp-to-dataset/dmp-to-dataset-dialog.component'; import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; import { FormService } from '@common/forms/form-service'; import { DmpDatasetProfile } from '@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile'; import { DmpDatasetProfileSectionsFormModel } from '@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile-sections-form.model'; +import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { LockService } from '@app/core/services/lock/lock.service'; +import { Principal } from '@app/core/model/auth/principal'; +import { Role } from '@app/core/common/enum/role'; +import { LockModel } from '@app/core/model/lock/lock.model'; +import { Guid } from '@common/types/guid'; +import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; +import { GrantEditorModel } from '@app/ui/grant/editor/grant-editor.model'; +import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate.component'; interface Visible { value: boolean; @@ -58,7 +66,11 @@ interface Visible { templateUrl: './dmp-editor-blueprint.component.html', styleUrls: ['./dmp-editor-blueprint.component.scss'] }) -export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit { +export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent implements OnInit { + + canDeactivate(): boolean { + return !this.isDirty(); + } saving = false; @@ -78,10 +90,12 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit dmpSectionIndex: number = 0; formGroup: FormGroup = null; formGroupRawValue: any; + datasets = new FormArray([]); associatedUsers: Array; people: Array; + lock: LockModel; lockStatus: Boolean = false; step: number = 0; @@ -114,6 +128,7 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit constructor( private dmpProfileService: DmpProfileService, private authService: AuthService, + private route: ActivatedRoute, private router: Router, private configurationService: ConfigurationService, private languageInfoService: LanguageInfoService, @@ -123,54 +138,150 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit private dmpService: DmpService, private uiNotificationService: UiNotificationService, private formService: FormService, - private dialog: MatDialog + private dialog: MatDialog, + private lockService: LockService, + private matomoService: MatomoService ) { super(); } ngOnInit(): void { - this.dmp = new DmpEditorModel(); - this.dmp.grant = new GrantTabModel(); - this.dmp.project = new ProjectFormModel(); - this.dmp.funder = new FunderFormModel(); - this.dmp.extraProperties = new ExtraPropertiesFormModel(); - this.dmp.extraProperties.visible = false; - this.dmp.extraProperties.contact = this.authService.current().id; - this.formGroup = this.dmp.buildForm(); + this.matomoService.trackPageView('DMP Editor'); + this.route.params + .pipe(takeUntil(this._destroyed)) + .subscribe((params: Params) => { + const itemId = params['id']; - this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); + if (itemId != null) { + this.isNew = false; + this.dmpService.getSingle(itemId).pipe(map(data => data as DmpModel)) + .pipe(takeUntil(this._destroyed)) + .subscribe(async data => { + this.lockService.checkLockStatus(data.id).pipe(takeUntil(this._destroyed)).subscribe(lockStatus => { + this.lockStatus = lockStatus; - if (this.formGroup.get('profile')) { this.selectedDmpBlueprintDefinition = this.formGroup.get('profile').value; } - this.registerFormEventsForDmpBlueprint(); + this.dmp = new DmpEditorModel(); + this.dmp.grant = new GrantTabModel(); + this.dmp.project = new ProjectFormModel(); + this.dmp.funder = new FunderFormModel(); + this.dmp.extraProperties = new ExtraPropertiesFormModel(); + this.dmp.fromModel(data); + this.formGroup = this.dmp.buildForm(); - if (!this.isUserOwner) { - this.formGroup.disable(); - } - if (isNullOrUndefined(this.formGroup.get('extraProperties').get('publicDate').value)) { - this.formGroup.get('extraProperties').get('publicDate').patchValue(new Date()); - } + this.datasets = this.formGroup.get('datasets') as FormArray; - const principal = this.authService.current(); - let associate: UserModel = { - id: principal.id, - name: principal.name, - appRoles: principal.authorities, - email: principal.email - }; - this.associates.push(associate); - if (isNullOrUndefined(this.formGroup.get('extraProperties').get('contact').value)) { - this.formGroup.get('extraProperties').get('contact').patchValue(associate.id); - } - if (isNullOrUndefined(this.formGroup.get('extraProperties').get('language').value)) { - this.formGroup.get('extraProperties').get('language').patchValue('en'); - } + this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); + if (!isNullOrUndefined(this.formGroup.get('profile').value)) { + this.dmpProfileService.getSingleBlueprint(this.formGroup.get('profile').value.id) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.selectedDmpBlueprintDefinition = result.definition; + this.formGroup.get('profile').setValue(result); + this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; + this.step = 1; + this.addProfiles(this.dmp.profiles); + }); + } + this.maxStep = this.formGroup.get('datasets') ? this.maxStep + this.formGroup.get('datasets').value.length - 1 : this.maxStep; - try{ - const profiles = this.formGroup.get('profiles').value as DmpDatasetProfile[]; - profiles.sort((a,b)=>a.label.localeCompare(b.label)); - }catch{ - console.info('Could not sort profiles'); - } + this.setIsUserOwner(); + if (!this.isUserOwner) { + + if(this.isUserMember()){ + this.router.navigate(['plans', 'overview', itemId]); + return; + } + this.isFinalized = true; + this.formGroup.disable(); + } + + if (this.dmp.status === DmpStatus.Finalized || lockStatus) { + this.isFinalized = true; + this.formGroup.disable(); + } + + if (this.authService.current() != null) { + if (!lockStatus) { + this.lock = new LockModel(data.id, this.getUserFromDMP()); + + this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe(async result => { + this.lock.id = Guid.parse(result); + interval(this.configurationService.lockInterval).pipe(takeUntil(this._destroyed)).subscribe(() => this.pumpLock()); + }); + } + } + + this.associatedUsers = data.associatedUsers; + this.people = data.users; + this.formGroup.valueChanges.pipe(takeUntil(this._destroyed)) + .subscribe(x => { + this.formChanged(); + }); + if(this.lockStatus){ + this.dialog.open(PopupNotificationDialogComponent,{data:{ + title:this.language.instant('DMP-EDITOR.LOCKED.TITLE'), + message:this.language.instant('DMP-EDITOR.LOCKED.MESSAGE') + }, maxWidth:'30em'}); + } + }); + }); + } + else { + this.dmp = new DmpEditorModel(); + this.dmp.grant = new GrantTabModel(); + this.dmp.project = new ProjectFormModel(); + this.dmp.funder = new FunderFormModel(); + this.dmp.extraProperties = new ExtraPropertiesFormModel(); + this.dmp.extraProperties.visible = false; + this.dmp.extraProperties.contact = this.authService.current().id; + this.formGroup = this.dmp.buildForm(); + + this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); + + if (!isNullOrUndefined(this.formGroup.get('profile').value)) { + this.dmpProfileService.getSingleBlueprint(this.formGroup.get('profile').value.id) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.selectedDmpBlueprintDefinition = result.definition; + this.formGroup.get('profile').setValue(result); + this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; + this.step = 1; + this.addProfiles(); + }); + } + this.registerFormEventsForDmpBlueprint(); + + if (!this.isUserOwner) { + this.formGroup.disable(); + } + if (isNullOrUndefined(this.formGroup.get('extraProperties').get('publicDate').value)) { + this.formGroup.get('extraProperties').get('publicDate').patchValue(new Date()); + } + + const principal = this.authService.current(); + let associate: UserModel = { + id: principal.id, + name: principal.name, + appRoles: principal.authorities, + email: principal.email + }; + this.associates.push(associate); + if (isNullOrUndefined(this.formGroup.get('extraProperties').get('contact').value)) { + this.formGroup.get('extraProperties').get('contact').patchValue(associate.id); + } + if (isNullOrUndefined(this.formGroup.get('extraProperties').get('language').value)) { + this.formGroup.get('extraProperties').get('language').patchValue('en'); + } + + try{ + const profiles = this.formGroup.get('profiles').value as DmpDatasetProfile[]; + profiles.sort((a,b)=>a.label.localeCompare(b.label)); + }catch{ + console.info('Could not sort profiles'); + } + } + }); + this.profilesAutoCompleteConfiguration = { filterFn: this.filterProfiles.bind(this), @@ -182,8 +293,104 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit }; } + setIsUserOwner() { + if (this.dmp) { + const principal: Principal = this.authService.current(); + this.isUserOwner = !!this.dmp.users.find(x => (x.role === Role.Owner) && (x.id === principal.id) ); + } + } + + isUserMember(): boolean{ + try{ + const principal: Principal = this.authService.current(); + return !!this.dmp.users.find(x => (x.role === Role.Member) && (x.id === principal.id) ); + }catch{ + return false; + } + } + + getUserFromDMP(): any { + if (this.dmp) { + const principal: Principal = this.authService.current(); + return this.dmp.users.find(x => x.id === principal.id); + } + } + + private pumpLock() { + this.lock.touchedAt = new Date(); + this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe(async result => this.lock.id = Guid.parse(result)); + } + + public isDirty(): boolean { + return this.formGroup && this.formGroup.dirty && this.hasChanges; + } + + public discard() { + let messageText = ""; + let confirmButtonText = ""; + let cancelButtonText = ""; + if (this.isNew) { + messageText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-NEW-MESSAGE'); + confirmButtonText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-NEW-CONFIRM'); + cancelButtonText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-NEW-DENY'); + } else { + messageText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-EDITED-MESSAGE'); + confirmButtonText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-EDITED-CONFIRM'); + cancelButtonText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-EDITED-DENY'); + } + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + restoreFocus: false, + data: { + message: messageText, + confirmButton: confirmButtonText, + cancelButton: cancelButtonText, + isDeleteConfirmation: true + }, + maxWidth: '40em' + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + // this.backToDmp(this.formGroup.get('dmp').value.id) + setTimeout(x => { + this.discardChanges(); + }); + } + }); + } + + public discardChanges() { + this.isDiscarded = true; + this.hasChanges = false; + if (!this.isNew) { + let grantControl; + if (this.formGroup.get('grant').get('existGrant')) { + grantControl = new GrantTabModel(); + grantControl.fromModel(this.formGroup.get('grant').get('existGrant').value); + } else { + grantControl = new GrantEditorModel(); + grantControl.fromModel(this.formGroup.get('grant').value); + } + grantControl.buildForm() + + this.formGroup.patchValue(JSON.parse(JSON.stringify(this.formGroupRawValue))); + + if (this.formGroup.get('grant').get('existGrant')) { + this.formGroup.get('grant').get('existGrant').setValue(grantControl.existGrant); + } else { + this.formGroup.get('grant').setValue(grantControl); + } + } else { + this.formGroup.reset(); + this.formGroup.get("status").setValue(DmpStatus.Draft); + this.formGroup.get('extraProperties').get('visible').setValue(false); + this.formGroup.get('extraProperties').get('contact').setValue(this.authService.current().id); + this.formGroup.get('associatedUsers').setValue([]); + } + this.isDiscarded = false; + } + save() { - this.formSubmit(true); + this.formSubmit(false); } formSubmit(addNew?: boolean, showAddDatasetDialog?: boolean): void { @@ -349,6 +556,9 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit // On save keep editor position this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); if (dmp) { + if(this.isNew){ + this.router.navigate(['/plans', 'edit', dmp.id]); + } let dmpEditorModel: DmpEditorModel; dmpEditorModel = new DmpEditorModel(); dmpEditorModel.grant = new GrantTabModel(); @@ -572,30 +782,7 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit .subscribe(Option => { if (Option instanceof Object) { this.selectedDmpBlueprintDefinition = Option.definition; - for(let i = 0; i < this.selectedDmpBlueprintDefinition.sections.length; i++){ - this.sectionTemplates.push(new Array()); - } - const templates: Array = new Array(); - this.selectedDmpBlueprintDefinition.sections.forEach(section => { - section.descriptionTemplates.forEach(template => { - this.sectionTemplates[section.ordinal - 1].push({id: template.descriptionTemplateId, label: template.label, description: ""}) - let data: DmpDatasetProfileSectionsFormModel= new DmpDatasetProfileSectionsFormModel(); - data.dmpSectionIndex.push(section.ordinal - 1); - let profile: DmpDatasetProfile = { - id: template.descriptionTemplateId, - label: template.label, - data: data - }; - let found: DmpDatasetProfile = templates.find(dmpDatasetProfile => dmpDatasetProfile.id == profile.id); - if (found === undefined) { - templates.push(profile); - } - else { - found.data.dmpSectionIndex.push(section.ordinal - 1); - } - }); - }); - this.formGroup.get('profiles').setValue(templates); + this.addProfiles(); } else { this.selectedDmpBlueprintDefinition = null; @@ -603,6 +790,47 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit }) } + private addProfiles(profiles?: DmpDatasetProfile[]) { + for(let i = 0; i < this.selectedDmpBlueprintDefinition.sections.length; i++){ + this.sectionTemplates.push(new Array()); + } + const templates: Array = new Array(); + this.selectedDmpBlueprintDefinition.sections.forEach(section => { + if (profiles !== undefined) { + profiles.filter(profile => profile.data.dmpSectionIndex.includes(section.ordinal - 1)).forEach(profile => this.sectionTemplates[section.ordinal - 1].push({id: profile.descriptionTemplateId, label: profile.label, description: ""})); + } + else { + section.descriptionTemplates.forEach(template => { + this.sectionTemplates[section.ordinal - 1].push({id: template.descriptionTemplateId, label: template.label, description: ""}) + let found: DmpDatasetProfile = templates.find(dmpDatasetProfile => dmpDatasetProfile.id == template.descriptionTemplateId); + if (found === undefined) { + let data: DmpDatasetProfileSectionsFormModel= new DmpDatasetProfileSectionsFormModel(); + data.dmpSectionIndex.push(section.ordinal - 1); + let id = null; + if (profiles !== undefined) { + let existedProfile = profiles.find(profile => profile.descriptionTemplateId == template.descriptionTemplateId); + if (existedProfile !== undefined) { + id = existedProfile.id; + } + } + let profile: DmpDatasetProfile = { + id: id, + descriptionTemplateId: template.descriptionTemplateId, + label: template.label, + data: data + }; + templates.push(profile); + } + else { + found.data.dmpSectionIndex.push(section.ordinal - 1); + } + }); + } + }); + (profiles !== undefined) ? this.formGroup.get('profiles').setValue(profiles) : this.formGroup.get('profiles').setValue(templates); + + } + dmpBlueprintAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { filterFn: this.dmpBlueprintSearch.bind(this), initialItems: (extraData) => this.dmpBlueprintSearch(''), @@ -788,20 +1016,35 @@ export class DmpEditorBlueprintComponent extends BaseComponent implements OnInit } }); } - onOptionSelected(){ + onOptionSelected(event, sectionIndex: number){ try{ - const profiles = this.formGroup.get('profiles').value as {id:string, label:string}[]; - const profileCounts: Map = new Map(); - profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id): 0 ) + 1)); - const duplicateProfiles = profiles.filter((value) => { - let isOk = profileCounts.get(value.id) > 1; - if (isOk) { - profileCounts.set(value.id, 0); + const profiles = this.formGroup.get('profiles').value as DmpDatasetProfile[]; + let found = profiles.find((value) => value.id === event.id); + if(found !== undefined) { + if(found.data.dmpSectionIndex.indexOf(sectionIndex) === -1){ + found.data.dmpSectionIndex.push(sectionIndex); } - return isOk; - }); - duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1)); - profiles.sort((a,b)=> a.label.localeCompare(b.label)); + else{ + this.sectionTemplates[sectionIndex].pop(); + } + } + else{ + let dmpDatasetProfileSection: DmpDatasetProfileSectionsFormModel = new DmpDatasetProfileSectionsFormModel(); + dmpDatasetProfileSection.dmpSectionIndex = [sectionIndex]; + profiles.push({id: null, descriptionTemplateId: event.id, label: event.label, data: dmpDatasetProfileSection}); + } + this.formGroup.get('profiles').setValue(profiles); + // const profileCounts: Map = new Map(); + // profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id): 0 ) + 1)); + // const duplicateProfiles = profiles.filter((value) => { + // let isOk = profileCounts.get(value.id) > 1; + // if (isOk) { + // profileCounts.set(value.id, 0); + // } + // return isOk; + // }); + // duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1)); + // profiles.sort((a,b)=> a.label.localeCompare(b.label)); }catch{ console.info('Could not sort Dataset Templates') } diff --git a/dmp-frontend/src/app/ui/dmp/dmp.routing.ts b/dmp-frontend/src/app/ui/dmp/dmp.routing.ts index 3f1ea17b8..3f8e41b86 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp.routing.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp.routing.ts @@ -35,7 +35,7 @@ const routes: Routes = [ }, { path: 'edit/:id', - component: DmpEditorComponent, + component: DmpEditorBlueprintComponent, data: { breadcrumb: true, title: 'GENERAL.TITLES.DMP-EDIT' @@ -75,16 +75,6 @@ const routes: Routes = [ // breadcrumbs: 'new' // } // }, - // { - // path: 'new', - // component: DmpEditorComponent, - // canActivate: [AuthGuard], - // data: { - // breadcrumbs: 'new', - // title: 'GENERAL.TITLES.DMP-NEW' - // }, - // canDeactivate:[CanDeactivateGuard] - // }, { path: 'new', component: DmpEditorBlueprintComponent, diff --git a/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts b/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts index 496ba5cb3..088f44d84 100644 --- a/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts +++ b/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts @@ -24,7 +24,7 @@ export class DmpEditorWizardModel { this.label = item.label; this.status = item.status; this.description = item.description; - this.datasetProfile = item.profiles[0]; + this.datasetProfile = {id: item.profiles[0].descriptionTemplateId, label: item.profiles[0].label, description: ""}; this.language = item.language; return this; } From c1858d582c3a3a0c7d0d0dc543650ed2d9436620 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Tue, 12 Sep 2023 15:39:08 +0300 Subject: [PATCH 052/110] no message --- .../main/java/eu/eudat/data/entities/DescriptionTemplate.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java index fdfd02b57..958934c72 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java @@ -92,6 +92,8 @@ public class DescriptionTemplate implements DataEntity @OneToMany(mappedBy = "descriptionTemplate", fetch = FetchType.LAZY) private Set users; + @OneToMany(fetch = FetchType.LAZY, mappedBy = "datasetprofile") + private Set associatedDmps; public String getDescription() { return description; From b1a832074dff684b7241e73561656bbb1a7d3d86 Mon Sep 17 00:00:00 2001 From: Aldo Mihasi Date: Wed, 13 Sep 2023 15:55:38 +0300 Subject: [PATCH 053/110] small fixes, (wip) remove description template chip from dmp editor --- .../eudat/logic/managers/DatasetManager.java | 2 +- .../logic/managers/PrefillingManager.java | 4 +- ...nt_and_add_dmpSectionIndex_to datasets.sql | 8 +-- .../ui/dashboard/drafts/drafts.component.html | 6 +- .../dmp-editor-blueprint.component.html | 6 +- .../dmp-editor-blueprint.component.ts | 61 +++++++++++-------- .../funding-info/funding-info.component.ts | 2 +- 7 files changed, 49 insertions(+), 40 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index 9b4c64840..5da228f05 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -308,7 +308,7 @@ public class DatasetManager { // Iterate through the versions and remove those that are not included in the DMP of the dataset in question. for (DescriptionTemplate version : profileVersions) { for (AssociatedProfile p : dataset.getDmp().getProfiles()) { - if (version.getId().toString().equals(p.getId().toString())) { + if (version.getId().toString().equals(p.getDescriptionTemplateId().toString())) { profileVersionsIncluded.add(version); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java index 0643ecbe4..a2c7e789b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java @@ -68,8 +68,8 @@ public class PrefillingManager { public DatasetWizardModel getPrefilledDatasetUsingData(Map data, String configId, UUID profileId) throws Exception { PrefillingConfig prefillingConfig = configLoader.getExternalUrls().getPrefillings().get(configId); PrefillingGet prefillingGet = prefillingConfig.getPrefillingGet(); - DatasetProfile datasetProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(profileId); - return PrefillingMapper.mapPrefilledEntityToDatasetWizard(data, prefillingGet, prefillingConfig.getType(), datasetProfile, datasetManager, licenseManager); + DescriptionTemplate descriptionTemplate = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(profileId); + return PrefillingMapper.mapPrefilledEntityToDatasetWizard(data, prefillingGet, prefillingConfig.getType(), descriptionTemplate, datasetManager, licenseManager); } private Map getSingle(String url, String id) { diff --git a/dmp-db-scema/updates/00.00.016_Insert_default_blueprint_and_add_dmpSectionIndex_to datasets.sql b/dmp-db-scema/updates/00.00.016_Insert_default_blueprint_and_add_dmpSectionIndex_to datasets.sql index bb61227b6..f5d549762 100644 --- a/dmp-db-scema/updates/00.00.016_Insert_default_blueprint_and_add_dmpSectionIndex_to datasets.sql +++ b/dmp-db-scema/updates/00.00.016_Insert_default_blueprint_and_add_dmpSectionIndex_to datasets.sql @@ -4,10 +4,10 @@ BEGIN PERFORM * FROM "DBVersion" WHERE version = this_version; IF FOUND THEN RETURN; END IF; -INSERT INTO public."DMPProfile" VALUES ('1374c46d-55b5-472a-8e10-c6ee8c0b5f7f', 'Dmp Default Blueprint', '
    ',1, now(),now()); -UPDATE public."DMP" SET ("Profile") = '1374c46d-55b5-472a-8e10-c6ee8c0b5f7f' WHERE "Profile" IS NULL; -UPDATE public."Dataset" SET ("DmpSectionIndex") = '3' WHERE "DmpSectionIndex" IS NULL; -UPDATE public."DMPDatasetProfile" SET ("data") = '{"dmpSectionIndex":[3]}' WHERE "data" IS NULL; +INSERT INTO public."DMPProfile" VALUES ('86635178-36a6-484f-9057-a934e4eeecd5', 'Dmp Default Blueprint', '
    ',1, now(),now()); +UPDATE public."DMP" SET "Profile" = '86635178-36a6-484f-9057-a934e4eeecd5' WHERE "Profile" IS NULL; +UPDATE public."Dataset" SET "DmpSectionIndex" = '3' WHERE "DmpSectionIndex" IS NULL; +UPDATE public."DMPDatasetProfile" SET "data" = '{"dmpSectionIndex":[3]}' WHERE "data" IS NULL; ALTER TABLE public."Dataset" ALTER COLUMN "DmpSectionIndex" SET NOT NULL; diff --git a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html index d0b819ce2..b35b6b4c8 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html @@ -102,7 +102,7 @@
    -
    {{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}
    +
    {{'DATASET-LISTING.DESCRIPTION' | translate}}
    {{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | dateTimeCultureFormatter: "d MMMM y"}}
    {{'DATASET-LISTING.STATES.PUBLISHED' | translate}}: {{activity.publishedAt | dateTimeCultureFormatter: "d MMMM y"}}
    @@ -125,7 +125,7 @@
    -