Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

# Conflicts:
#	dmp-frontend/src/app/ui/plan/overview/plan-overview.component.html
This commit is contained in:
Sofia Papacharalampous 2024-07-08 15:20:38 +03:00
commit 986d83df49
136 changed files with 1111 additions and 806 deletions

View File

@ -165,8 +165,8 @@ public class DescriptionController {
@OperationWithTenantHeader(summary = "Query all descriptions", description = SwaggerHelpers.Description.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Description.endpoint_query_request_body, content = @Content( @OperationWithTenantHeader(summary = "Query all descriptions", description = SwaggerHelpers.Description.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Description.endpoint_query_request_body, content = @Content(
examples = { examples = {
@ExampleObject( @ExampleObject(
name = "Pagination and projection", name = SwaggerHelpers.Commons.pagination_example,
description = "Simple paginated request using a property projection list and pagination info", description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.Description.endpoint_query_request_body_example value = SwaggerHelpers.Description.endpoint_query_request_body_example
) )
} }
@ -177,8 +177,8 @@ public class DescriptionController {
) )
), ),
examples = @ExampleObject( examples = @ExampleObject(
name = "First page", name = SwaggerHelpers.Commons.pagination_response_example,
description = "Example with the first page of paginated results", description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.Description.endpoint_query_response_example value = SwaggerHelpers.Description.endpoint_query_response_example
)))) ))))
public QueryResult<Description> query(@RequestBody DescriptionLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<Description> query(@RequestBody DescriptionLookup lookup) throws MyApplicationException, MyForbiddenException {

View File

@ -101,8 +101,8 @@ public class DescriptionTemplateController {
@OperationWithTenantHeader(summary = "Query all description templates", description = SwaggerHelpers.DescriptionTemplate.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.DescriptionTemplate.endpoint_query_request_body, content = @Content( @OperationWithTenantHeader(summary = "Query all description templates", description = SwaggerHelpers.DescriptionTemplate.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.DescriptionTemplate.endpoint_query_request_body, content = @Content(
examples = { examples = {
@ExampleObject( @ExampleObject(
name = "Pagination and projection", name = SwaggerHelpers.Commons.pagination_example,
description = "Simple paginated request using a property projection list and pagination info", description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.DescriptionTemplate.endpoint_query_request_body_example value = SwaggerHelpers.DescriptionTemplate.endpoint_query_request_body_example
) )
} }
@ -113,8 +113,8 @@ public class DescriptionTemplateController {
) )
), ),
examples = @ExampleObject( examples = @ExampleObject(
name = "First page", name = SwaggerHelpers.Commons.pagination_response_example,
description = "Example with the first page of paginated results", description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.DescriptionTemplate.endpoint_query_response_example value = SwaggerHelpers.DescriptionTemplate.endpoint_query_response_example
)))) ))))
public QueryResult<DescriptionTemplate> query(@RequestBody DescriptionTemplateLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<DescriptionTemplate> query(@RequestBody DescriptionTemplateLookup lookup) throws MyApplicationException, MyForbiddenException {

View File

@ -82,8 +82,8 @@ public class DescriptionTemplateTypeController {
@OperationWithTenantHeader(summary = "Query all description template types", description = SwaggerHelpers.DescriptionTemplateType.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.DescriptionTemplateType.endpoint_query_request_body, content = @Content( @OperationWithTenantHeader(summary = "Query all description template types", description = SwaggerHelpers.DescriptionTemplateType.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.DescriptionTemplateType.endpoint_query_request_body, content = @Content(
examples = { examples = {
@ExampleObject( @ExampleObject(
name = "Pagination and projection", name = SwaggerHelpers.Commons.pagination_example,
description = "Simple paginated request using a property projection list and pagination info", description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.DescriptionTemplateType.endpoint_query_request_body_example value = SwaggerHelpers.DescriptionTemplateType.endpoint_query_request_body_example
) )
} }
@ -94,8 +94,8 @@ public class DescriptionTemplateTypeController {
) )
), ),
examples = @ExampleObject( examples = @ExampleObject(
name = "First page", name = SwaggerHelpers.Commons.pagination_response_example,
description = "Example with the first page of paginated results", description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.DescriptionTemplateType.endpoint_query_response_example value = SwaggerHelpers.DescriptionTemplateType.endpoint_query_response_example
)))) ))))
public QueryResult<DescriptionTemplateType> Query(@RequestBody DescriptionTemplateTypeLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<DescriptionTemplateType> Query(@RequestBody DescriptionTemplateTypeLookup lookup) throws MyApplicationException, MyForbiddenException {

View File

@ -82,8 +82,8 @@ public class EntityDoiController {
@OperationWithTenantHeader(summary = "Query all entity dois", description = SwaggerHelpers.EntityDoi.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.EntityDoi.endpoint_query_request_body, content = @Content( @OperationWithTenantHeader(summary = "Query all entity dois", description = SwaggerHelpers.EntityDoi.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.EntityDoi.endpoint_query_request_body, content = @Content(
examples = { examples = {
@ExampleObject( @ExampleObject(
name = "Pagination and projection", name = SwaggerHelpers.Commons.pagination_example,
description = "Simple paginated request using a property projection list and pagination info", description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.EntityDoi.endpoint_query_request_body_example value = SwaggerHelpers.EntityDoi.endpoint_query_request_body_example
) )
} }
@ -94,8 +94,8 @@ public class EntityDoiController {
) )
), ),
examples = @ExampleObject( examples = @ExampleObject(
name = "First page", name = SwaggerHelpers.Commons.pagination_response_example,
description = "Example with the first page of paginated results", description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.EntityDoi.endpoint_query_response_example value = SwaggerHelpers.EntityDoi.endpoint_query_response_example
)))) ))))
public QueryResult<EntityDoi> query(@RequestBody EntityDoiLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<EntityDoi> query(@RequestBody EntityDoiLookup lookup) throws MyApplicationException, MyForbiddenException {

View File

@ -105,8 +105,8 @@ public class LockController {
@OperationWithTenantHeader(summary = "Query all locked entities", description = SwaggerHelpers.Lock.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Lock.endpoint_query_request_body, content = @Content( @OperationWithTenantHeader(summary = "Query all locked entities", description = SwaggerHelpers.Lock.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Lock.endpoint_query_request_body, content = @Content(
examples = { examples = {
@ExampleObject( @ExampleObject(
name = "Pagination and projection", name = SwaggerHelpers.Commons.pagination_example,
description = "Simple paginated request using a property projection list and pagination info", description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.Lock.endpoint_query_request_body_example value = SwaggerHelpers.Lock.endpoint_query_request_body_example
) )
} }
@ -117,8 +117,8 @@ public class LockController {
) )
), ),
examples = @ExampleObject( examples = @ExampleObject(
name = "First page", name = SwaggerHelpers.Commons.pagination_response_example,
description = "Example with the first page of paginated results", description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.Lock.endpoint_query_response_example value = SwaggerHelpers.Lock.endpoint_query_response_example
)))) ))))
public QueryResult<Lock> query(@RequestBody LockLookup lookup) throws MyApplicationException, MyForbiddenException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException { public QueryResult<Lock> query(@RequestBody LockLookup lookup) throws MyApplicationException, MyForbiddenException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {

View File

@ -94,8 +94,8 @@ public class PlanBlueprintController {
@OperationWithTenantHeader(summary = "Query all plan blueprints", description = SwaggerHelpers.PlanBlueprint.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.PlanBlueprint.endpoint_query_request_body, content = @Content( @OperationWithTenantHeader(summary = "Query all plan blueprints", description = SwaggerHelpers.PlanBlueprint.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.PlanBlueprint.endpoint_query_request_body, content = @Content(
examples = { examples = {
@ExampleObject( @ExampleObject(
name = "Pagination and projection", name = SwaggerHelpers.Commons.pagination_example,
description = "Simple paginated request using a property projection list and pagination info", description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.PlanBlueprint.endpoint_query_request_body_example value = SwaggerHelpers.PlanBlueprint.endpoint_query_request_body_example
) )
} }
@ -106,8 +106,8 @@ public class PlanBlueprintController {
) )
), ),
examples = @ExampleObject( examples = @ExampleObject(
name = "First page", name = SwaggerHelpers.Commons.pagination_response_example,
description = "Example with the first page of paginated results", description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.PlanBlueprint.endpoint_query_response_example value = SwaggerHelpers.PlanBlueprint.endpoint_query_response_example
)))) ))))
public QueryResult<PlanBlueprint> query(@RequestBody PlanBlueprintLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<PlanBlueprint> query(@RequestBody PlanBlueprintLookup lookup) throws MyApplicationException, MyForbiddenException {

View File

@ -147,8 +147,8 @@ public class PlanController {
@PostMapping("query") @PostMapping("query")
@OperationWithTenantHeader(summary = "Query all plans", description = SwaggerHelpers.Plan.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Plan.endpoint_query_request_body, content = @Content(examples = @ExampleObject( @OperationWithTenantHeader(summary = "Query all plans", description = SwaggerHelpers.Plan.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Plan.endpoint_query_request_body, content = @Content(examples = @ExampleObject(
name = "Pagination and projection", name = SwaggerHelpers.Commons.pagination_example,
description = "Simple paginated request using a property projection list and pagination info", description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.Plan.endpoint_query_request_body_example value = SwaggerHelpers.Plan.endpoint_query_request_body_example
))), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content( ))), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
array = @ArraySchema( array = @ArraySchema(
@ -157,8 +157,8 @@ public class PlanController {
) )
), ),
examples = @ExampleObject( examples = @ExampleObject(
name = "First page", name = SwaggerHelpers.Commons.pagination_response_example,
description = "Example with the first page of paginated results", description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.Plan.endpoint_query_response_example value = SwaggerHelpers.Plan.endpoint_query_response_example
)))) ))))
public QueryResult<Plan> Query(@RequestBody PlanLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<Plan> Query(@RequestBody PlanLookup lookup) throws MyApplicationException, MyForbiddenException {

View File

@ -14,7 +14,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import org.opencdmp.audit.AuditableAction; import org.opencdmp.audit.AuditableAction;
import org.opencdmp.controllers.swagger.SwaggerHelpers; import org.opencdmp.controllers.swagger.SwaggerHelpers;
import org.opencdmp.controllers.swagger.annotation.OperationWithTenantHeader; import org.opencdmp.controllers.swagger.annotation.OperationWithTenantHeader;
import org.opencdmp.model.Lock; import org.opencdmp.controllers.swagger.annotation.SwaggerCommonErrorResponses;
import org.opencdmp.model.Tenant; import org.opencdmp.model.Tenant;
import org.opencdmp.models.Account; import org.opencdmp.models.Account;
import org.opencdmp.models.AccountBuilder; import org.opencdmp.models.AccountBuilder;
@ -32,84 +32,89 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/api/principal/") @RequestMapping("/api/principal/")
@Tag(name = "Principal", description = "Get user account information") @Tag(name = "Principal", description = "Get user account information")
@SwaggerCommonErrorResponses
public class PrincipalController { public class PrincipalController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(PrincipalController.class));
private final AuditService auditService;
private final CurrentPrincipalResolver currentPrincipalResolver; private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(PrincipalController.class));
private final AccountBuilder accountBuilder;
private final TenantService tenantService;
@Autowired private final AuditService auditService;
public PrincipalController(
CurrentPrincipalResolver currentPrincipalResolver,
AccountBuilder accountBuilder,
AuditService auditService, TenantService tenantService) {
this.currentPrincipalResolver = currentPrincipalResolver;
this.accountBuilder = accountBuilder;
this.auditService = auditService;
this.tenantService = tenantService;
}
@RequestMapping(path = "me", method = RequestMethod.GET ) private final CurrentPrincipalResolver currentPrincipalResolver;
@OperationWithTenantHeader(summary = "Fetch auth information of the logged in user", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = Account.class
))
))
public Account me(
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws InvalidApplicationException {
logger.debug("me");
if (fieldSet == null || fieldSet.isEmpty()) { private final AccountBuilder accountBuilder;
fieldSet = new BaseFieldSet(
Account._isAuthenticated,
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._subject),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._userId),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._name),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._scope),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._client),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._issuedAt),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._notBefore),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._authenticatedAt),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._expiresAt),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._more),
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._avatarUrl),
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._language),
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._culture),
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._timezone),
Account._permissions,
BaseFieldSet.asIndexer(Account._selectedTenant, Tenant._id),
BaseFieldSet.asIndexer(Account._selectedTenant, Tenant._name),
BaseFieldSet.asIndexer(Account._selectedTenant, Tenant._code));
}
MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal(); private final TenantService tenantService;
Account me = this.accountBuilder.build(fieldSet, principal); @Autowired
public PrincipalController(
CurrentPrincipalResolver currentPrincipalResolver,
AccountBuilder accountBuilder,
AuditService auditService, TenantService tenantService) {
this.currentPrincipalResolver = currentPrincipalResolver;
this.accountBuilder = accountBuilder;
this.auditService = auditService;
this.tenantService = tenantService;
}
this.auditService.track(AuditableAction.Principal_Lookup); @RequestMapping(path = "me", method = RequestMethod.GET)
//auditService.trackIdentity(AuditableAction.IdentityTracking_Action); @OperationWithTenantHeader(summary = "Fetch auth information of the logged in user", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
schema = @Schema(
implementation = Account.class
))
))
public Account me(
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) throws InvalidApplicationException {
logger.debug("me");
return me; if (fieldSet == null || fieldSet.isEmpty()) {
} fieldSet = new BaseFieldSet(
Account._isAuthenticated,
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._subject),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._userId),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._name),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._scope),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._client),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._issuedAt),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._notBefore),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._authenticatedAt),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._expiresAt),
BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._more),
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._avatarUrl),
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._language),
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._culture),
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._timezone),
Account._permissions,
BaseFieldSet.asIndexer(Account._selectedTenant, Tenant._id),
BaseFieldSet.asIndexer(Account._selectedTenant, Tenant._name),
BaseFieldSet.asIndexer(Account._selectedTenant, Tenant._code));
}
@GetMapping("my-tenants") MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal();
@OperationWithTenantHeader(summary = "Fetch a list with the tenants the user belongs to", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
public List<Tenant> myTenants(
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) {
logger.debug("my-tenants");
List<Tenant> models = this.tenantService.myTenants(fieldSet); Account me = this.accountBuilder.build(fieldSet, principal);
this.auditService.track(AuditableAction.Principal_MyTenants); this.auditService.track(AuditableAction.Principal_Lookup);
//auditService.trackIdentity(AuditableAction.IdentityTracking_Action); //auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
return models; return me;
} }
@GetMapping("my-tenants")
@OperationWithTenantHeader(summary = "Fetch a list with the tenants the user belongs to", description = "",
responses = @ApiResponse(description = "OK", responseCode = "200"))
public List<Tenant> myTenants(
@Parameter(name = "fieldSet", description = SwaggerHelpers.Commons.fieldset_description, required = true) FieldSet fieldSet
) {
logger.debug("my-tenants");
List<Tenant> models = this.tenantService.myTenants(fieldSet);
this.auditService.track(AuditableAction.Principal_MyTenants);
//auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
return models;
}
} }

View File

@ -12,7 +12,6 @@ import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry; import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.ValidationFilterAnnotation; import gr.cite.tools.validation.ValidationFilterAnnotation;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
@ -33,7 +32,6 @@ import org.opencdmp.data.ReferenceEntity;
import org.opencdmp.model.builder.reference.ReferenceBuilder; import org.opencdmp.model.builder.reference.ReferenceBuilder;
import org.opencdmp.model.censorship.reference.ReferenceCensor; import org.opencdmp.model.censorship.reference.ReferenceCensor;
import org.opencdmp.model.persist.ReferencePersist; import org.opencdmp.model.persist.ReferencePersist;
import org.opencdmp.model.planblueprint.PlanBlueprint;
import org.opencdmp.model.reference.Reference; import org.opencdmp.model.reference.Reference;
import org.opencdmp.model.result.QueryResult; import org.opencdmp.model.result.QueryResult;
import org.opencdmp.query.ReferenceQuery; import org.opencdmp.query.ReferenceQuery;
@ -74,7 +72,6 @@ public class ReferenceController {
private final MessageSource messageSource; private final MessageSource messageSource;
@Autowired @Autowired
public ReferenceController( public ReferenceController(
BuilderFactory builderFactory, BuilderFactory builderFactory,
@ -95,8 +92,8 @@ public class ReferenceController {
@OperationWithTenantHeader(summary = "Query all references", description = SwaggerHelpers.Reference.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Reference.endpoint_query_request_body, content = @Content( @OperationWithTenantHeader(summary = "Query all references", description = SwaggerHelpers.Reference.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Reference.endpoint_query_request_body, content = @Content(
examples = { examples = {
@ExampleObject( @ExampleObject(
name = "Pagination and projection", name = SwaggerHelpers.Commons.pagination_example,
description = "Simple paginated request using a property projection list and pagination info", description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.Reference.endpoint_query_request_body_example value = SwaggerHelpers.Reference.endpoint_query_request_body_example
) )
} }
@ -107,8 +104,8 @@ public class ReferenceController {
) )
), ),
examples = @ExampleObject( examples = @ExampleObject(
name = "First page", name = SwaggerHelpers.Commons.pagination_response_example,
description = "Example with the first page of paginated results", description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.Reference.endpoint_query_response_example value = SwaggerHelpers.Reference.endpoint_query_response_example
)))) ))))
public QueryResult<Reference> query(@RequestBody ReferenceLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<Reference> query(@RequestBody ReferenceLookup lookup) throws MyApplicationException, MyForbiddenException {
@ -126,10 +123,27 @@ public class ReferenceController {
return new QueryResult<>(models, count); return new QueryResult<>(models, count);
} }
@PostMapping("search") @PostMapping("search")
@Hidden @OperationWithTenantHeader(summary = "Query all references including results from external APIs", description = SwaggerHelpers.Reference.endpoint_search, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Reference.endpoint_search_request_body, content = @Content(
//TODO thgiannos add swagger docs examples = {
@ExampleObject(
name = SwaggerHelpers.Commons.pagination_example,
description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.Reference.endpoint_search_request_body_example
)
}
)), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
array = @ArraySchema(
schema = @Schema(
implementation = Reference.class
)
),
examples = @ExampleObject(
name = SwaggerHelpers.Commons.pagination_response_example,
description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.Reference.endpoint_search_response_example
))))
@Swagger404
public List<Reference> searchReferenceWithDefinition(@RequestBody ReferenceSearchLookup lookup) throws MyNotFoundException, InvalidApplicationException { public List<Reference> searchReferenceWithDefinition(@RequestBody ReferenceSearchLookup lookup) throws MyNotFoundException, InvalidApplicationException {
logger.debug("search with db definition {}", Reference.class.getSimpleName()); logger.debug("search with db definition {}", Reference.class.getSimpleName());

View File

@ -94,8 +94,8 @@ public class ReferenceTypeController{
@OperationWithTenantHeader(summary = "Query all reference types", description = SwaggerHelpers.ReferenceType.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.ReferenceType.endpoint_query_request_body, content = @Content( @OperationWithTenantHeader(summary = "Query all reference types", description = SwaggerHelpers.ReferenceType.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.ReferenceType.endpoint_query_request_body, content = @Content(
examples = { examples = {
@ExampleObject( @ExampleObject(
name = "Pagination and projection", name = SwaggerHelpers.Commons.pagination_example,
description = "Simple paginated request using a property projection list and pagination info", description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.ReferenceType.endpoint_query_request_body_example value = SwaggerHelpers.ReferenceType.endpoint_query_request_body_example
) )
} }
@ -106,8 +106,8 @@ public class ReferenceTypeController{
) )
), ),
examples = @ExampleObject( examples = @ExampleObject(
name = "First page", name = SwaggerHelpers.Commons.pagination_response_example,
description = "Example with the first page of paginated results", description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.ReferenceType.endpoint_query_response_example value = SwaggerHelpers.ReferenceType.endpoint_query_response_example
)))) ))))
public QueryResult<ReferenceType> query(@RequestBody ReferenceTypeLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<ReferenceType> query(@RequestBody ReferenceTypeLookup lookup) throws MyApplicationException, MyForbiddenException {

View File

@ -81,8 +81,8 @@ public class TagController {
@OperationWithTenantHeader(summary = "Query all tags", description = SwaggerHelpers.Tag.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Tag.endpoint_query_request_body, content = @Content( @OperationWithTenantHeader(summary = "Query all tags", description = SwaggerHelpers.Tag.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.Tag.endpoint_query_request_body, content = @Content(
examples = { examples = {
@ExampleObject( @ExampleObject(
name = "Pagination and projection", name = SwaggerHelpers.Commons.pagination_example,
description = "Simple paginated request using a property projection list and pagination info", description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.Tag.endpoint_query_request_body_example value = SwaggerHelpers.Tag.endpoint_query_request_body_example
) )
} }
@ -93,8 +93,8 @@ public class TagController {
) )
), ),
examples = @ExampleObject( examples = @ExampleObject(
name = "First page", name = SwaggerHelpers.Commons.pagination_response_example,
description = "Example with the first page of paginated results", description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.Tag.endpoint_query_response_example value = SwaggerHelpers.Tag.endpoint_query_response_example
)))) ))))
public QueryResult<Tag> Query(@RequestBody TagLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<Tag> Query(@RequestBody TagLookup lookup) throws MyApplicationException, MyForbiddenException {

View File

@ -12,7 +12,6 @@ import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry; import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.ValidationFilterAnnotation; import gr.cite.tools.validation.ValidationFilterAnnotation;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
@ -37,9 +36,11 @@ import org.opencdmp.model.builder.PlanAssociatedUserBuilder;
import org.opencdmp.model.builder.UserBuilder; import org.opencdmp.model.builder.UserBuilder;
import org.opencdmp.model.censorship.PlanAssociatedUserCensor; import org.opencdmp.model.censorship.PlanAssociatedUserCensor;
import org.opencdmp.model.censorship.UserCensor; import org.opencdmp.model.censorship.UserCensor;
import org.opencdmp.model.persist.*; import org.opencdmp.model.persist.UserMergeRequestPersist;
import org.opencdmp.model.persist.UserPersist;
import org.opencdmp.model.persist.UserRolePatchPersist;
import org.opencdmp.model.persist.UserTenantUsersInviteRequest;
import org.opencdmp.model.persist.actionconfirmation.RemoveCredentialRequestPersist; import org.opencdmp.model.persist.actionconfirmation.RemoveCredentialRequestPersist;
import org.opencdmp.model.plan.Plan;
import org.opencdmp.model.result.QueryResult; import org.opencdmp.model.result.QueryResult;
import org.opencdmp.model.user.User; import org.opencdmp.model.user.User;
import org.opencdmp.query.UserQuery; import org.opencdmp.query.UserQuery;
@ -110,8 +111,8 @@ public class UserController {
@OperationWithTenantHeader(summary = "Query all users", description = SwaggerHelpers.User.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.User.endpoint_query_request_body, content = @Content( @OperationWithTenantHeader(summary = "Query all users", description = SwaggerHelpers.User.endpoint_query, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.User.endpoint_query_request_body, content = @Content(
examples = { examples = {
@ExampleObject( @ExampleObject(
name = "Pagination and projection", name = SwaggerHelpers.Commons.pagination_example,
description = "Simple paginated request using a property projection list and pagination info", description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.User.endpoint_query_request_body_example value = SwaggerHelpers.User.endpoint_query_request_body_example
) )
} }
@ -122,8 +123,8 @@ public class UserController {
) )
), ),
examples = @ExampleObject( examples = @ExampleObject(
name = "First page", name = SwaggerHelpers.Commons.pagination_response_example,
description = "Example with the first page of paginated results", description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.User.endpoint_query_response_example value = SwaggerHelpers.User.endpoint_query_response_example
)))) ))))
public QueryResult<User> query(@RequestBody UserLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<User> query(@RequestBody UserLookup lookup) throws MyApplicationException, MyForbiddenException {
@ -143,7 +144,25 @@ public class UserController {
} }
@PostMapping("plan-associated/query") @PostMapping("plan-associated/query")
@Hidden @OperationWithTenantHeader(summary = "Query all plan associated users", description = SwaggerHelpers.User.endpoint_query_plan_associated, requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(description = SwaggerHelpers.User.endpoint_query_request_body, content = @Content(
examples = {
@ExampleObject(
name = SwaggerHelpers.Commons.pagination_example,
description = SwaggerHelpers.Commons.pagination_example_description,
value = SwaggerHelpers.User.endpoint_query_plan_associated_request_body_example
)
}
)), responses = @ApiResponse(description = "OK", responseCode = "200", content = @Content(
array = @ArraySchema(
schema = @Schema(
implementation = PlanAssociatedUser.class
)
),
examples = @ExampleObject(
name = SwaggerHelpers.Commons.pagination_response_example,
description = SwaggerHelpers.Commons.pagination_response_example_description,
value = SwaggerHelpers.User.endpoint_query_plan_associated_response_example
))))
public QueryResult<PlanAssociatedUser> queryPlanAssociated(@RequestBody UserLookup lookup) throws MyApplicationException, MyForbiddenException { public QueryResult<PlanAssociatedUser> queryPlanAssociated(@RequestBody UserLookup lookup) throws MyApplicationException, MyForbiddenException {
logger.debug("querying {}", User.class.getSimpleName()); logger.debug("querying {}", User.class.getSimpleName());
@ -219,8 +238,11 @@ public class UserController {
} }
@GetMapping("/export/csv/{hasTenantAdminMode}") @GetMapping("/export/csv/{hasTenantAdminMode}")
@Hidden @OperationWithTenantHeader(summary = "Export users in a .csv file", description = "",
public ResponseEntity<byte[]> exportCsv(@PathVariable("hasTenantAdminMode") Boolean hasTenantAdminMode) throws MyApplicationException, MyForbiddenException, MyNotFoundException, IOException, InvalidApplicationException { responses = @ApiResponse(description = "OK", responseCode = "200"))
public ResponseEntity<byte[]> exportCsv(
@Parameter(name = "hasTenantAdminMode", description = "Controls whether to fetch users as a tenant admin or not", example = "false", required = true) @PathVariable("hasTenantAdminMode") Boolean hasTenantAdminMode
) throws MyApplicationException, MyForbiddenException, MyNotFoundException, IOException, InvalidApplicationException {
logger.debug(new MapLogEntry("export" + User.class.getSimpleName()).And("hasTenantAdminMode", hasTenantAdminMode)); logger.debug(new MapLogEntry("export" + User.class.getSimpleName()).And("hasTenantAdminMode", hasTenantAdminMode));
// this.censorFactory.censor(UserCensor.class).censor(fieldSet, null); // this.censorFactory.censor(UserCensor.class).censor(fieldSet, null);

View File

@ -8,6 +8,26 @@ public final class SwaggerHelpers {
""" """
This is an object containing a list of the properties you wish to include in the response, similar to the 'project' attribute on queries. This is an object containing a list of the properties you wish to include in the response, similar to the 'project' attribute on queries.
"""; """;
public static final String pagination_example =
"""
Pagination and projection
""";
public static final String pagination_example_description =
"""
Simple paginated request using a property projection list and pagination info
""";
public static final String pagination_response_example =
"""
Pagination and projection
""";
public static final String pagination_response_example_description =
"""
Simple paginated request using a property projection list and pagination info
""";
} }
public static final class Errors { public static final class Errors {
@ -3346,6 +3366,190 @@ public final class SwaggerHelpers {
} }
"""; """;
public static final String endpoint_search =
"""
This endpoint is used to fetch all the available references.<br/>
It also allows to restrict the results using a query object passed in the request body.<br/>
""";
public static final String endpoint_search_request_body =
"""
Let's explore the options this object gives us.
### <u>General query parameters:</u>
<ul>
<li><b>page:</b>
This is an object controlling the pagination of the results. It contains two properties.
</li>
<ul>
<li><b>offset:</b>
How many records to omit.
</li>
<li><b>size:</b>
How many records to include in each page.
</li>
</ul>
</ul>
For example, if we want the third page, and our pages to contain 15 elements, we would pass the following object:
```JSON
{
"offset": 30,
"size": 15
}
```
<ul>
<li><b>order:</b>
This is an object controlling the ordering of the results.
It contains a list of strings called <i>items</i> with the names of the properties to use.
<br/>If the name of the property is prefixed with a <b>'-'</b>, the ordering direction is <b>DESC</b>. Otherwise, it is <b>ASC</b>.
</li>
</ul>
For example, if we wanted to order based on the field 'createdAt' in descending order, we would pass the following object:
```JSON
{
"items": [
"-createdAt"
],
}
```
<ul>
<li><b>metadata:</b>
This is an object containing metadata for the request. There is only one available option.
<ul>
<li><b>countAll:</b>
If this is set to true, the count property included in the response will account for all the records regardless the pagination,
with all the rest of filtering options applied of course.
Otherwise, if it is set to false or not present, only the returned results will be counted.
<br/>The first option is useful for the UI clients to calculate how many result pages are available.
</li>
</ul>
</li>
<li><b>project:</b>
This is an object controlling the data projection of the results.
It contains a list of strings called <i>fields</i> with the names of the properties to project.
<br/>You can also include properties that are deeper in the object tree by prefixing them with dots.
</li>
</ul>
### <u>Reference specific query parameters:</u>
<ul>
<li><b>like:</b>
If there is a like parameter present in the query, only the reference entities that include the contents of the parameter either in their labels, descriptions or the references will be in the response.
</li>
<li><b>typeId:</b>
This is the type id of the references we want in the response. <br/>If empty, every record is included.
</li>
<li><b>key:</b>
This is the id of the external source (API) we want results from.
<br/>If not present, no external reference is included.
</li>
<li><b>dependencyReferences:</b>
This is a list and determines which records we want to include in the response, based on the references they depend on.
<br/>If not present, every record is included.
</li>
</ul>
""";
public static final String endpoint_search_request_body_example =
"""
{
"project":{
"fields":[
"id",
"hash",
"label",
"type",
"type.id",
"description",
"definition.fields.code",
"definition.fields.dataType",
"definition.fields.value",
"reference",
"abbreviation",
"source",
"sourceType"
]
},
"page":{
"size":100,
"offset":0
},
"typeId":"5b9c284f-f041-4995-96cc-fad7ad13289c",
"dependencyReferences":[
\s
],
"order":{
"items":[
"label"
]
}
}
""";
public static final String endpoint_search_response_example =
"""
[
{
"label": "A Randomized, Double-Blind, Placebo-Controlled, Multi-Center Study to Evaluate the Efficacy of ManNAc in Subjects with GNE Myopathy (nih_________::5U01AR070498-04)",
"type": {
"id": "5b9c284f-f041-4995-96cc-fad7ad13289c"
},
"description": "A Randomized, Double-Blind, Placebo-Controlled, Multi-Center Study to Evaluate the Efficacy of ManNAc in Subjects with GNE Myopathy",
"definition": {
"fields": [
{
"code": "referenceType",
"dataType": 0,
"value": "Grants"
},
{
"code": "key",
"dataType": 0,
"value": "openaire"
}
]
},
"reference": "nih_________::5U01AR070498-04",
"source": "openaire",
"sourceType": 1,
"hash": ""
},
{
"label": "A genome scale census of virulence factors in the major mould pathogen of human lungs, Aspergillus fumigatus (ukri________::1640253)",
"type": {
"id": "5b9c284f-f041-4995-96cc-fad7ad13289c"
},
"description": "A genome scale census of virulence factors in the major mould pathogen of human lungs, Aspergillus fumigatus",
"definition": {
"fields": [
{
"code": "referenceType",
"dataType": 0,
"value": "Grants"
},
{
"code": "key",
"dataType": 0,
"value": "openaire"
}
]
},
"reference": "ukri________::1640253",
"source": "openaire",
"sourceType": 1,
"hash": ""
}
]
""";
} }
public static final class ReferenceType { public static final class ReferenceType {
@ -3779,6 +3983,12 @@ public final class SwaggerHelpers {
It also allows to restrict the results using a query object passed in the request body.<br/> It also allows to restrict the results using a query object passed in the request body.<br/>
"""; """;
public static final String endpoint_query_plan_associated =
"""
This endpoint is used to fetch all the available users.<br/>
It also allows to restrict the results using a query object passed in the request body.<br/>
""";
public static final String endpoint_query_request_body = public static final String endpoint_query_request_body =
""" """
Let's explore the options this object gives us. Let's explore the options this object gives us.
@ -3908,6 +4118,32 @@ public final class SwaggerHelpers {
} }
"""; """;
public static final String endpoint_query_plan_associated_request_body_example =
"""
{
"project":{
"fields":[
"id",
"name",
"email"
]
},
"page":{
"size":100,
"offset":0
},
"isActive":[
1
],
"order":{
"items":[
"name"
]
},
"like":"user%"
}
""";
public static final String endpoint_query_response_example = public static final String endpoint_query_response_example =
""" """
{ {
@ -4241,6 +4477,25 @@ public final class SwaggerHelpers {
} }
"""; """;
public static final String endpoint_query_plan_associated_response_example =
"""
{
"items":[
{
"id":"d26916c6-8763-450e-9048-b06e1114d0b4",
"name":"user3 user3",
"email":"user3@dmp.gr"
},
{
"id":"02832fb6-0b12-469f-a886-7685406959d4",
"name":"user4",
"email":"user4@dmp.gr"
}
],
"count":2
}
""";
} }
public static final class Principal { public static final class Principal {

View File

@ -45,7 +45,7 @@ const appRoutes: Routes = [
}, },
{ {
path: 'plans', path: 'plans',
loadChildren: () => import('./ui/plan/plan.module').then(m => m.DmpModule), loadChildren: () => import('./ui/plan/plan.module').then(m => m.PlanModule),
data: { data: {
authContext: { authContext: {
permissions: [AppPermission.ViewMyPlanPage] permissions: [AppPermission.ViewMyPlanPage]
@ -59,7 +59,7 @@ const appRoutes: Routes = [
}, },
{ {
path: 'explore-plans', path: 'explore-plans',
loadChildren: () => import('./ui/plan/plan.module').then(m => m.PublicDmpModule), loadChildren: () => import('./ui/plan/plan.module').then(m => m.PublicPlanModule),
data: { data: {
breadcrumb: true, breadcrumb: true,
...BreadcrumbService.generateRouteDataConfiguration({ ...BreadcrumbService.generateRouteDataConfiguration({

View File

@ -252,7 +252,7 @@ export class AppComponent implements OnInit, AfterViewInit {
return this.authentication.currentAccountIsAuthenticated(); return this.authentication.currentAccountIsAuthenticated();
} }
goToDMPs() { //not used goToPlans() { //not used
this.router.navigate(['/plans'], { queryParams: { /*refresh : Math.random() ,returnUrl: this.state.url*/ } }); this.router.navigate(['/plans'], { queryParams: { /*refresh : Math.random() ,returnUrl: this.state.url*/ } });
} }

View File

@ -1,4 +1,4 @@
export enum AnnotationEntityType { export enum AnnotationEntityType {
Description = "description", Description = "description",
Dmp = "dmp" Plan = "plan"
} }

View File

@ -1,4 +1,4 @@
export enum FileTransformerEntityType { export enum FileTransformerEntityType {
Dmp = 0, Plan = 0,
Description = 1 Description = 1
} }

View File

@ -13,11 +13,11 @@ export enum ResponseErrorCode {
DescriptionTemplateNewVersionConflict = 113, DescriptionTemplateNewVersionConflict = 113,
DescriptionTemplateIsNotFinalized = 114, DescriptionTemplateIsNotFinalized = 114,
MultipleDescriptionTemplateVersionsNotSupported = 115, MultipleDescriptionTemplateVersionsNotSupported = 115,
DmpNewVersionConflict = 116, PlanNewVersionConflict = 116,
DmpIsNotFinalized = 117, PlanIsNotFinalized = 117,
MultipleDmpVersionsNotSupported = 118, MultiplePlanVersionsNotSupported = 118,
DmpIsFinalized = 119, PlanIsFinalized = 119,
DmpCanNotChange = 120, PlanCanNotChange = 120,
PlanDescriptionTemplateCanNotChange = 121, PlanDescriptionTemplateCanNotChange = 121,
InvalidDescriptionTemplate = 122, InvalidDescriptionTemplate = 122,
DescriptionIsFinalized = 123, DescriptionIsFinalized = 123,
@ -28,11 +28,11 @@ export enum ResponseErrorCode {
TenantConfigurationTypeCanNotChange = 128, TenantConfigurationTypeCanNotChange = 128,
MultipleTenantConfigurationTypeNotAllowed = 129, MultipleTenantConfigurationTypeNotAllowed = 129,
TenantCodeExists = 130, TenantCodeExists = 130,
DmpNewVersionAlreadyCreatedDraft = 131, PlanNewVersionAlreadyCreatedDraft = 131,
DescriptionTemplateInactiveUser = 132, DescriptionTemplateInactiveUser = 132,
DescriptionTemplateMissingUserContactInfo = 133, DescriptionTemplateMissingUserContactInfo = 133,
DmpInactiveUser = 134, PlanInactiveUser = 134,
DmpMissingUserContactInfo = 135, PlanMissingUserContactInfo = 135,
ImportDescriptionWithoutPlanDescriptionTemplate = 136, ImportDescriptionWithoutPlanDescriptionTemplate = 136,
DuplicatePlanUser = 137, DuplicatePlanUser = 137,
DescriptionTemplateNewVersionAlreadyCreatedDraft = 138, DescriptionTemplateNewVersionAlreadyCreatedDraft = 138,
@ -79,15 +79,15 @@ export class ResponseErrorCodeHelper {
return language.instant("GENERAL.BACKEND-ERRORS.DESCRIPTION-TEMPLATE-IS-NOT-FINALIZED"); return language.instant("GENERAL.BACKEND-ERRORS.DESCRIPTION-TEMPLATE-IS-NOT-FINALIZED");
case ResponseErrorCode.MultipleDescriptionTemplateVersionsNotSupported: case ResponseErrorCode.MultipleDescriptionTemplateVersionsNotSupported:
return language.instant("GENERAL.BACKEND-ERRORS.MULTIPLE-DESCRIPTION-TEMPLATE-VERSIONS-NOT-SUPPORTED"); return language.instant("GENERAL.BACKEND-ERRORS.MULTIPLE-DESCRIPTION-TEMPLATE-VERSIONS-NOT-SUPPORTED");
case ResponseErrorCode.DmpNewVersionConflict: case ResponseErrorCode.PlanNewVersionConflict:
return language.instant("GENERAL.BACKEND-ERRORS.PLAN-NEW-VERSION-CONFLICT"); return language.instant("GENERAL.BACKEND-ERRORS.PLAN-NEW-VERSION-CONFLICT");
case ResponseErrorCode.DmpIsNotFinalized: case ResponseErrorCode.PlanIsNotFinalized:
return language.instant("GENERAL.BACKEND-ERRORS.PLAN-IS-NOT-FINALIZED"); return language.instant("GENERAL.BACKEND-ERRORS.PLAN-IS-NOT-FINALIZED");
case ResponseErrorCode.MultipleDmpVersionsNotSupported: case ResponseErrorCode.MultiplePlanVersionsNotSupported:
return language.instant("GENERAL.BACKEND-ERRORS.MULTIPLE-PLAN-VERSIONS-NOT-SUPPORTED"); return language.instant("GENERAL.BACKEND-ERRORS.MULTIPLE-PLAN-VERSIONS-NOT-SUPPORTED");
case ResponseErrorCode.DmpIsFinalized: case ResponseErrorCode.PlanIsFinalized:
return language.instant("GENERAL.BACKEND-ERRORS.PLAN-IS-FINALIZED"); return language.instant("GENERAL.BACKEND-ERRORS.PLAN-IS-FINALIZED");
case ResponseErrorCode.DmpCanNotChange: case ResponseErrorCode.PlanCanNotChange:
return language.instant("GENERAL.BACKEND-ERRORS.PLAN-CAN-NOT-CHANGE"); return language.instant("GENERAL.BACKEND-ERRORS.PLAN-CAN-NOT-CHANGE");
case ResponseErrorCode.PlanDescriptionTemplateCanNotChange: case ResponseErrorCode.PlanDescriptionTemplateCanNotChange:
return language.instant("GENERAL.BACKEND-ERRORS.PLAN-DESCRIPTION-TEMPLATE-CAN-NOT-CHANGE"); return language.instant("GENERAL.BACKEND-ERRORS.PLAN-DESCRIPTION-TEMPLATE-CAN-NOT-CHANGE");
@ -109,15 +109,15 @@ export class ResponseErrorCodeHelper {
return language.instant("GENERAL.BACKEND-ERRORS.MULTIPLE-TENANT-CONFIGURATION-TYPE-NOT-ALLOWED"); return language.instant("GENERAL.BACKEND-ERRORS.MULTIPLE-TENANT-CONFIGURATION-TYPE-NOT-ALLOWED");
case ResponseErrorCode.TenantCodeExists: case ResponseErrorCode.TenantCodeExists:
return language.instant("GENERAL.BACKEND-ERRORS.TENANT-CODE-EXISTS"); return language.instant("GENERAL.BACKEND-ERRORS.TENANT-CODE-EXISTS");
case ResponseErrorCode.DmpNewVersionAlreadyCreatedDraft: case ResponseErrorCode.PlanNewVersionAlreadyCreatedDraft:
return language.instant("GENERAL.BACKEND-ERRORS.PLAN-NEW-VERSION-ALREADY-CREATED-DRAFT"); return language.instant("GENERAL.BACKEND-ERRORS.PLAN-NEW-VERSION-ALREADY-CREATED-DRAFT");
case ResponseErrorCode.DescriptionTemplateInactiveUser: case ResponseErrorCode.DescriptionTemplateInactiveUser:
return language.instant("GENERAL.BACKEND-ERRORS.DESCRIPTION-TEMPLATE-INACTIVE-USER"); return language.instant("GENERAL.BACKEND-ERRORS.DESCRIPTION-TEMPLATE-INACTIVE-USER");
case ResponseErrorCode.DescriptionTemplateMissingUserContactInfo: case ResponseErrorCode.DescriptionTemplateMissingUserContactInfo:
return language.instant("GENERAL.BACKEND-ERRORS.DESCRIPTION-TEMPLATE-MISSING-USER-CONTACT-INFO"); return language.instant("GENERAL.BACKEND-ERRORS.DESCRIPTION-TEMPLATE-MISSING-USER-CONTACT-INFO");
case ResponseErrorCode.DmpInactiveUser: case ResponseErrorCode.PlanInactiveUser:
return language.instant("GENERAL.BACKEND-ERRORS.PLAN-INACTIVE-USER"); return language.instant("GENERAL.BACKEND-ERRORS.PLAN-INACTIVE-USER");
case ResponseErrorCode.DmpMissingUserContactInfo: case ResponseErrorCode.PlanMissingUserContactInfo:
return language.instant("GENERAL.BACKEND-ERRORS.PLAN-MISSING-USER-CONTACT-INFO"); return language.instant("GENERAL.BACKEND-ERRORS.PLAN-MISSING-USER-CONTACT-INFO");
case ResponseErrorCode.ImportDescriptionWithoutPlanDescriptionTemplate: case ResponseErrorCode.ImportDescriptionWithoutPlanDescriptionTemplate:
return language.instant("GENERAL.BACKEND-ERRORS.IMPORT-DESCRIPTION-WITHOUT-PLAN-DESCRIPTION-TEMPLATE"); return language.instant("GENERAL.BACKEND-ERRORS.IMPORT-DESCRIPTION-WITHOUT-PLAN-DESCRIPTION-TEMPLATE");

View File

@ -72,7 +72,7 @@ export interface UserCredentialData {
email: String; email: String;
} }
export interface DmpAssociatedUser { export interface PlanAssociatedUser {
id: Guid; id: Guid;
name: string; name: string;
email: string; email: string;

View File

@ -30,7 +30,7 @@ export class FileTransformerService extends BaseService {
private _loading: boolean = false; private _loading: boolean = false;
private xmlExportRepo: RepositoryFileFormat = { private xmlExportRepo: RepositoryFileFormat = {
entityTypes: [FileTransformerEntityType.Description, FileTransformerEntityType.Dmp], entityTypes: [FileTransformerEntityType.Description, FileTransformerEntityType.Plan],
format: "xml", format: "xml",
hasLogo: true, hasLogo: true,
icon: "fa-file-code-o", icon: "fa-file-code-o",

View File

@ -34,7 +34,7 @@ export class AnalyticsService {
public static PlanFilterDialog: string = 'DMP Criteria'; public static PlanFilterDialog: string = 'DMP Criteria';
public static PlanListingItem: string = 'DMP Listing Item'; public static PlanListingItem: string = 'DMP Listing Item';
public static StartNewPlanDialog: string = 'Start New DMP Dialog'; public static StartNewPlanDialog: string = 'Start New DMP Dialog';
public static DmpUploadDialog: string = 'DMP Upload Dialog'; public static PlanUploadDialog: string = 'DMP Upload Dialog';
public static PlanOverview: string = 'DMP Overview'; public static PlanOverview: string = 'DMP Overview';
public static FAQ: string = 'FAQ'; public static FAQ: string = 'FAQ';
public static Glossary: string = 'Glossary'; public static Glossary: string = 'Glossary';

View File

@ -1,7 +1,7 @@
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http'; import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { IsActive } from '@app/core/common/enum/is-active.enum'; import { IsActive } from '@app/core/common/enum/is-active.enum';
import { DmpAssociatedUser, RemoveCredentialRequestPersist, User, UserMergeRequestPersist, UserPersist, UserRolePatchPersist, UserTenantUsersInviteRequest } from '@app/core/model/user/user'; import { PlanAssociatedUser, RemoveCredentialRequestPersist, User, UserMergeRequestPersist, UserPersist, UserRolePatchPersist, UserTenantUsersInviteRequest } from '@app/core/model/user/user';
import { UserLookup } from '@app/core/query/user.lookup'; import { UserLookup } from '@app/core/query/user.lookup';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
@ -31,9 +31,9 @@ export class UserService {
return this.http.post<QueryResult<User>>(url, q).pipe(catchError((error: any) => throwError(error))); return this.http.post<QueryResult<User>>(url, q).pipe(catchError((error: any) => throwError(error)));
} }
queryDmpAssociated(q: UserLookup): Observable<QueryResult<DmpAssociatedUser>> { queryPlanAssociated(q: UserLookup): Observable<QueryResult<PlanAssociatedUser>> {
const url = `${this.apiBase}/plan-associated/query`; const url = `${this.apiBase}/plan-associated/query`;
return this.http.post<QueryResult<DmpAssociatedUser>>(url, q).pipe(catchError((error: any) => throwError(error))); return this.http.post<QueryResult<PlanAssociatedUser>>(url, q).pipe(catchError((error: any) => throwError(error)));
} }
getSingle(id: Guid, reqFields: string[] = []): Observable<User> { getSingle(id: Guid, reqFields: string[] = []): Observable<User> {
@ -178,14 +178,14 @@ export class UserService {
valueAssign: (item: User) => item.id, valueAssign: (item: User) => item.id,
}; };
singleAutoCompleteDmpAssociatedUserConfiguration: SingleAutoCompleteConfiguration = { singleAutoCompletePlanAssociatedUserConfiguration: SingleAutoCompleteConfiguration = {
initialItems: (data?: any) => this.queryDmpAssociated(this.buildAutocompleteLookup()).pipe(map(x => x.items)), initialItems: (data?: any) => this.queryPlanAssociated(this.buildAutocompleteLookup()).pipe(map(x => x.items)),
filterFn: (searchQuery: string, data?: any) => this.queryDmpAssociated(this.buildAutocompleteLookup(searchQuery)).pipe(map(x => x.items)), filterFn: (searchQuery: string, data?: any) => this.queryPlanAssociated(this.buildAutocompleteLookup(searchQuery)).pipe(map(x => x.items)),
getSelectedItem: (selectedItem: any) => this.queryDmpAssociated(this.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])), getSelectedItem: (selectedItem: any) => this.queryPlanAssociated(this.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
displayFn: (item: DmpAssociatedUser) => item.name, displayFn: (item: PlanAssociatedUser) => item.name,
subtitleFn: (item: DmpAssociatedUser) => item.email, subtitleFn: (item: PlanAssociatedUser) => item.email,
titleFn: (item: DmpAssociatedUser) => item.name, titleFn: (item: PlanAssociatedUser) => item.name,
valueAssign: (item: DmpAssociatedUser) => item.id, valueAssign: (item: PlanAssociatedUser) => item.id,
}; };
public buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): UserLookup { public buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): UserLookup {

View File

@ -225,11 +225,11 @@
</button> </button>
<mat-action-list class="ml-4"> <mat-action-list class="ml-4">
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_PLANS)"> <button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_PLANS)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Internal Dmp icon"> <img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Internal Plan icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_PLANS)}} {{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_PLANS)}}
</button> </button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS)"> <button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS)">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Internal Dmp icon"> <img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="Internal Plan icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS)}} {{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS)}}
</button> </button>
<button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.TAGS)"> <button mat-list-item (click)="addNewInput(descriptionTemplateFieldTypeEnum.TAGS)">

View File

@ -93,11 +93,11 @@
<mat-divider></mat-divider> <mat-divider></mat-divider>
<mat-optgroup label="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.INTERNAL-ENTITIES' | translate}}"> <mat-optgroup label="{{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.FIELDS.INTERNAL-ENTITIES' | translate}}">
<mat-option [value]="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_PLANS"> <mat-option [value]="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_PLANS">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="InternalDmpEntities icon"> <img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="InternalPlanEntities icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_PLANS)}} {{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_PLANS)}}
</mat-option> </mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS"> <mat-option [value]="descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS">
<img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="InternalDmpEntities icon"> <img src="/assets/images/editor/icons/api_entity.svg" class="input_icon" alt="InternalPlanEntities icon">
{{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS)}} {{enumUtils.toDescriptionTemplateFieldTypeString(descriptionTemplateFieldTypeEnum.INTERNAL_ENTRIES_DESCRIPTIONS)}}
</mat-option> </mat-option>
<mat-option [value]="descriptionTemplateFieldTypeEnum.TAGS"> <mat-option [value]="descriptionTemplateFieldTypeEnum.TAGS">

View File

@ -8,7 +8,7 @@ export enum ViewStyleType{
FreeText = "freetext", FreeText = "freetext",
RadioBox = "radiobox", RadioBox = "radiobox",
DatePicker = "datePicker", DatePicker = "datePicker",
InternalDmpEntities = "internalDmpEntities", InternalPlanEntities = "InternalPlanEntities",
ExternalDatasets = "externalDatasets", ExternalDatasets = "externalDatasets",
DataRepositories = "dataRepositories", DataRepositories = "dataRepositories",
PubRepositories = "pubRepositories", PubRepositories = "pubRepositories",

View File

@ -167,12 +167,12 @@ export class MaintenanceTasksComponent extends BaseComponent implements OnInit {
.afterClosed() .afterClosed()
.subscribe(confirm => { .subscribe(confirm => {
if (confirm) { if (confirm) {
this.doSendDmpTouchEvents(ev); this.doSendPlanTouchEvents(ev);
} }
}); });
} }
private doSendDmpTouchEvents(ev: Event) { private doSendPlanTouchEvents(ev: Event) {
(ev.target as HTMLButtonElement).disabled = true; (ev.target as HTMLButtonElement).disabled = true;
this.maintenanceService.sendPlanTouchEvents().pipe(takeUntil(this._destroyed)).subscribe( this.maintenanceService.sendPlanTouchEvents().pipe(takeUntil(this._destroyed)).subscribe(
_ => { _ => {

View File

@ -1,5 +1,5 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row dmp-blueprint-editor"> <div class="row plan-blueprint-editor">
<div class="col-md-10 offset-md-1"> <div class="col-md-10 offset-md-1">
<div class="row align-items-center mt-4 mb-4" *ngIf="formGroup"> <div class="row align-items-center mt-4 mb-4" *ngIf="formGroup">
<div class="col-md col-12"> <div class="col-md col-12">
@ -41,7 +41,7 @@
</mat-form-field> </mat-form-field>
</div> </div>
<h4 class="col-12">{{'PLAN-BLUEPRINT-EDITOR.FIELDS.SECTIONS' | translate}} <h4 class="col-12">{{'PLAN-BLUEPRINT-EDITOR.FIELDS.SECTIONS' | translate}}
<mat-error *ngIf="formGroup.get('definition').get('sections').hasError('dmpBlueprintSystemFieldRequired')"> {{'PLAN-BLUEPRINT-EDITOR.SYSTEM-FIELDS-REQUIRED' | translate}} </mat-error> <mat-error *ngIf="formGroup.get('definition').get('sections').hasError('planBlueprintSystemFieldRequired')"> {{'PLAN-BLUEPRINT-EDITOR.SYSTEM-FIELDS-REQUIRED' | translate}} </mat-error>
</h4> </h4>
<div class="col-12" cdkDropList (cdkDropListDropped)="dropSections($event)"> <div class="col-12" cdkDropList (cdkDropListDropped)="dropSections($event)">
<div *ngFor="let section of formGroup.get('definition').get('sections').controls; let sectionIndex=index;" class="row mb-3" cdkDrag [cdkDragDisabled]="formGroup.disabled"> <div *ngFor="let section of formGroup.get('definition').get('sections').controls; let sectionIndex=index;" class="row mb-3" cdkDrag [cdkDragDisabled]="formGroup.disabled">
@ -109,13 +109,13 @@
<mat-form-field class="mt-3 w-100"> <mat-form-field class="mt-3 w-100">
<mat-label>{{'PLAN-BLUEPRINT-EDITOR.FIELDS.CATEGORY' | translate}}</mat-label> <mat-label>{{'PLAN-BLUEPRINT-EDITOR.FIELDS.CATEGORY' | translate}}</mat-label>
<mat-select [formControl]="field.get('category')" [disabled]="field.disabled" (selectionChange)="fieldCategoryChanged(sectionIndex, fieldIndex)"> <mat-select [formControl]="field.get('category')" [disabled]="field.disabled" (selectionChange)="fieldCategoryChanged(sectionIndex, fieldIndex)">
<mat-option *ngFor="let fieldCategory of dmpBlueprintFieldCategoryEnum" [value]="fieldCategory">{{enumUtils.toPlanBlueprintFieldCategoryString(fieldCategory)}}</mat-option> <mat-option *ngFor="let fieldCategory of planBlueprintFieldCategoryEnum" [value]="fieldCategory">{{enumUtils.toPlanBlueprintFieldCategoryString(fieldCategory)}}</mat-option>
</mat-select> </mat-select>
<mat-error *ngIf="field.get('category').hasError('backendError')">{{field.get('category').getError('backendError').message}}</mat-error> <mat-error *ngIf="field.get('category').hasError('backendError')">{{field.get('category').getError('backendError').message}}</mat-error>
<mat-error *ngIf="field.get('category').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="field.get('category').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>
<div class="col-12 col-xl-4" *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.System"> <div class="col-12 col-xl-4" *ngIf="field.get('category').value === planBlueprintSectionFieldCategory.System">
<mat-form-field class="mt-3 w-100"> <mat-form-field class="mt-3 w-100">
<mat-label>{{'PLAN-BLUEPRINT-EDITOR.FIELDS.SYSTEM-FIELD-TYPE' | translate}}</mat-label> <mat-label>{{'PLAN-BLUEPRINT-EDITOR.FIELDS.SYSTEM-FIELD-TYPE' | translate}}</mat-label>
<mat-select [formControl]="field.get('systemFieldType')" [disabled]="field.disabled"> <mat-select [formControl]="field.get('systemFieldType')" [disabled]="field.disabled">
@ -125,7 +125,7 @@
<mat-error *ngIf="field.get('systemFieldType').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="field.get('systemFieldType').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>
<div class="col-12 col-xl-4" *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.Extra"> <div class="col-12 col-xl-4" *ngIf="field.get('category').value === planBlueprintSectionFieldCategory.Extra">
<mat-form-field class="mt-3 w-100"> <mat-form-field class="mt-3 w-100">
<mat-label>{{'PLAN-BLUEPRINT-EDITOR.FIELDS.DATA-TYPE' | translate}}</mat-label> <mat-label>{{'PLAN-BLUEPRINT-EDITOR.FIELDS.DATA-TYPE' | translate}}</mat-label>
<mat-select [formControl]="field.get('dataType')"> <mat-select [formControl]="field.get('dataType')">
@ -137,7 +137,7 @@
<mat-error *ngIf="field.get('dataType').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="field.get('dataType').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>
<div class="col-12 col-xl-4" *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.ReferenceType"> <div class="col-12 col-xl-4" *ngIf="field.get('category').value === planBlueprintSectionFieldCategory.ReferenceType">
<mat-form-field class="mt-3 w-100"> <mat-form-field class="mt-3 w-100">
<mat-label>{{'PLAN-BLUEPRINT-EDITOR.FIELDS.REFERENCE-TYPE' | translate}}</mat-label> <mat-label>{{'PLAN-BLUEPRINT-EDITOR.FIELDS.REFERENCE-TYPE' | translate}}</mat-label>
<app-single-auto-complete placeholder="{{'PLAN-BLUEPRINT-EDITOR.FIELDS.REFERENCE-TYPE' | translate}}" [required]="true" [formControl]="field.get('referenceTypeId')" [configuration]="referenceTypeService.singleAutocompleteConfiguration"></app-single-auto-complete> <app-single-auto-complete placeholder="{{'PLAN-BLUEPRINT-EDITOR.FIELDS.REFERENCE-TYPE' | translate}}" [required]="true" [formControl]="field.get('referenceTypeId')" [configuration]="referenceTypeService.singleAutocompleteConfiguration"></app-single-auto-complete>
@ -184,7 +184,7 @@
<mat-error *ngIf="field.get('required').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="field.get('required').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</div> </div>
<div class="col-auto col-xl-2"> <div class="col-auto col-xl-2">
<div *ngIf="field.get('category').value === dmpBlueprintSectionFieldCategory.ReferenceType"> <div *ngIf="field.get('category').value === planBlueprintSectionFieldCategory.ReferenceType">
<mat-checkbox [disabled]="formGroup.disabled" [checked]="field.get('multipleSelect').value" (change)="field.get('multipleSelect').setValue($event.checked)"><span>{{'PLAN-BLUEPRINT-EDITOR.FIELDS.FIELD-MULTIPLE-SELECT' | translate}}</span></mat-checkbox> <mat-checkbox [disabled]="formGroup.disabled" [checked]="field.get('multipleSelect').value" (change)="field.get('multipleSelect').setValue($event.checked)"><span>{{'PLAN-BLUEPRINT-EDITOR.FIELDS.FIELD-MULTIPLE-SELECT' | translate}}</span></mat-checkbox>
<mat-error *ngIf="field.get('multipleSelect')?.hasError('backendError')">{{field.get('multipleSelect')?.getError('backendError').message}}</mat-error> <mat-error *ngIf="field.get('multipleSelect')?.hasError('backendError')">{{field.get('multipleSelect')?.getError('backendError').message}}</mat-error>
<mat-error *ngIf="field.get('multipleSelect')?.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error> <mat-error *ngIf="field.get('multipleSelect')?.hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>

View File

@ -4,7 +4,7 @@
margin-bottom: 0 !important; margin-bottom: 0 !important;
} }
.dmp-blueprint-editor { .plan-blueprint-editor {
// margin-top: 1.3rem; // margin-top: 1.3rem;
// margin-left: 1em; // margin-left: 1em;
// margin-right: 3em; // margin-right: 3em;

View File

@ -65,12 +65,12 @@ export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditor
hoveredSectionIndex: number = -1; hoveredSectionIndex: number = -1;
hoveredDescriptionTemplateIndex: number = -1; hoveredDescriptionTemplateIndex: number = -1;
dmpBlueprintSectionFieldCategory = PlanBlueprintFieldCategory; planBlueprintSectionFieldCategory = PlanBlueprintFieldCategory;
dmpBlueprintSystemFieldType = PlanBlueprintSystemFieldType; planBlueprintSystemFieldType = PlanBlueprintSystemFieldType;
public planBlueprintSystemFieldTypeEnum = this.enumUtils.getEnumValues<PlanBlueprintSystemFieldType>(PlanBlueprintSystemFieldType); public planBlueprintSystemFieldTypeEnum = this.enumUtils.getEnumValues<PlanBlueprintSystemFieldType>(PlanBlueprintSystemFieldType);
dmpBlueprintExtraFieldDataType = PlanBlueprintExtraFieldDataType; planBlueprintExtraFieldDataType = PlanBlueprintExtraFieldDataType;
public planBlueprintExtraFieldDataTypeEnum = this.enumUtils.getEnumValues<PlanBlueprintExtraFieldDataType>(PlanBlueprintExtraFieldDataType); public planBlueprintExtraFieldDataTypeEnum = this.enumUtils.getEnumValues<PlanBlueprintExtraFieldDataType>(PlanBlueprintExtraFieldDataType);
public dmpBlueprintFieldCategoryEnum = this.enumUtils.getEnumValues<PlanBlueprintFieldCategory>(PlanBlueprintFieldCategory); public planBlueprintFieldCategoryEnum = this.enumUtils.getEnumValues<PlanBlueprintFieldCategory>(PlanBlueprintFieldCategory);
descriptionTempalteGroupSingleAutocompleteConfiguration: SingleAutoCompleteConfiguration = { descriptionTempalteGroupSingleAutocompleteConfiguration: SingleAutoCompleteConfiguration = {
initialItems: (data?: any) => this.descriptionTemplateService.query(this.descriptionTemplateService.buildDescriptionTempalteGroupAutocompleteLookup([IsActive.Active], null, null, null, this.getUsedDescriptionTemplateGroupIds())).pipe(map(x => x.items)), initialItems: (data?: any) => this.descriptionTemplateService.query(this.descriptionTemplateService.buildDescriptionTempalteGroupAutocompleteLookup([IsActive.Active], null, null, null, this.getUsedDescriptionTemplateGroupIds())).pipe(map(x => x.items)),
filterFn: (searchQuery: string, data?: any) => this.descriptionTemplateService.query(this.descriptionTemplateService.buildDescriptionTempalteGroupAutocompleteLookup([IsActive.Active], searchQuery, null, null, this.getUsedDescriptionTemplateGroupIds() ? this.getUsedDescriptionTemplateGroupIds() : null)).pipe(map(x => x.items)), filterFn: (searchQuery: string, data?: any) => this.descriptionTemplateService.query(this.descriptionTemplateService.buildDescriptionTempalteGroupAutocompleteLookup([IsActive.Active], searchQuery, null, null, this.getUsedDescriptionTemplateGroupIds() ? this.getUsedDescriptionTemplateGroupIds() : null)).pipe(map(x => x.items)),
@ -126,7 +126,7 @@ export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditor
public enumUtils: EnumUtils, public enumUtils: EnumUtils,
private planBlueprintService: PlanBlueprintService, private planBlueprintService: PlanBlueprintService,
private logger: LoggingService, private logger: LoggingService,
private dmpBlueprintEditorService: PlanBlueprintEditorService, private planBlueprintEditorService: PlanBlueprintEditorService,
private fileUtils: FileUtils, private fileUtils: FileUtils,
public descriptionTemplateService: DescriptionTemplateService, public descriptionTemplateService: DescriptionTemplateService,
public referenceTypeService: ReferenceTypeService, public referenceTypeService: ReferenceTypeService,
@ -190,14 +190,14 @@ export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditor
if (data && data.id) this.checkLock(data.id, LockTargetType.PlanBlueprint, 'PLAN-BLUEPRINT-EDITOR.LOCKED-DIALOG.TITLE', 'PLAN-BLUEPRINT-EDITOR.LOCKED-DIALOG.MESSAGE'); if (data && data.id) this.checkLock(data.id, LockTargetType.PlanBlueprint, 'PLAN-BLUEPRINT-EDITOR.LOCKED-DIALOG.TITLE', 'PLAN-BLUEPRINT-EDITOR.LOCKED-DIALOG.MESSAGE');
} catch (error) { } catch (error) {
this.logger.error('Could not parse dmpBlueprint item: ' + data + error); this.logger.error('Could not parse planBlueprint item: ' + data + error);
this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error); this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error);
} }
} }
buildForm() { buildForm() {
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.authService.hasPermission(AppPermission.EditPlanBlueprint)); this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.authService.hasPermission(AppPermission.EditPlanBlueprint));
this.dmpBlueprintEditorService.setValidationErrorModel(this.editorModel.validationErrorModel); this.planBlueprintEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
if (this.isFinalized || this.isDeleted) { if (this.isFinalized || this.isDeleted) {
this.formGroup.disable(); this.formGroup.disable();
} }
@ -517,28 +517,28 @@ export class PlanBlueprintEditorComponent extends BaseEditor<PlanBlueprintEditor
} }
hasTitle(): boolean { hasTitle(): boolean {
const dmpBlueprint: PlanBlueprintPersist = this.formGroup.value; const planBlueprint: PlanBlueprintPersist = this.formGroup.value;
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category == PlanBlueprintFieldCategory.System) && (field as SystemFieldInSection).systemFieldType === PlanBlueprintSystemFieldType.Title)); return planBlueprint.definition.sections.some(section => section.fields.some(field => (field.category == PlanBlueprintFieldCategory.System) && (field as SystemFieldInSection).systemFieldType === PlanBlueprintSystemFieldType.Title));
} }
hasDescription(): boolean { hasDescription(): boolean {
const dmpBlueprint: PlanBlueprintPersist = this.formGroup.value; const planBlueprint: PlanBlueprintPersist = this.formGroup.value;
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category == PlanBlueprintFieldCategory.System) && (field as SystemFieldInSection).systemFieldType === PlanBlueprintSystemFieldType.Description)); return planBlueprint.definition.sections.some(section => section.fields.some(field => (field.category == PlanBlueprintFieldCategory.System) && (field as SystemFieldInSection).systemFieldType === PlanBlueprintSystemFieldType.Description));
} }
hasLanguage(): boolean { hasLanguage(): boolean {
const dmpBlueprint: PlanBlueprintPersist = this.formGroup.value; const planBlueprint: PlanBlueprintPersist = this.formGroup.value;
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category == PlanBlueprintFieldCategory.System) && (field as SystemFieldInSection).systemFieldType === PlanBlueprintSystemFieldType.Language)); return planBlueprint.definition.sections.some(section => section.fields.some(field => (field.category == PlanBlueprintFieldCategory.System) && (field as SystemFieldInSection).systemFieldType === PlanBlueprintSystemFieldType.Language));
} }
hasAccess(): boolean { hasAccess(): boolean {
const dmpBlueprint: PlanBlueprintPersist = this.formGroup.value; const planBlueprint: PlanBlueprintPersist = this.formGroup.value;
return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category == PlanBlueprintFieldCategory.System) && (field as SystemFieldInSection).systemFieldType === PlanBlueprintSystemFieldType.AccessRights)); return planBlueprint.definition.sections.some(section => section.fields.some(field => (field.category == PlanBlueprintFieldCategory.System) && (field as SystemFieldInSection).systemFieldType === PlanBlueprintSystemFieldType.AccessRights));
} }
hasDescriptionTemplates(): boolean { hasDescriptionTemplates(): boolean {
const dmpBlueprint: PlanBlueprintPersist = this.formGroup.value; const planBlueprint: PlanBlueprintPersist = this.formGroup.value;
return dmpBlueprint.definition.sections.some(section => section.hasTemplates == true); return planBlueprint.definition.sections.some(section => section.hasTemplates == true);
} }
private showValidationErrorsDialog(projectOnly?: boolean, errmess?: string[]) { private showValidationErrorsDialog(projectOnly?: boolean, errmess?: string[]) {

View File

@ -1,4 +1,4 @@
.dmp-blueprint-listing-filters { .plan-blueprint-listing-filters {
} }

View File

@ -1,5 +1,5 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row dmp-blueprint-listing"> <div class="row plan-blueprint-listing">
<div class="col-md-10 offset-md-1"> <div class="col-md-10 offset-md-1">
<div class="row mb-4 mt-4"> <div class="row mb-4 mt-4">
<div class="col"> <div class="col">

View File

@ -3,7 +3,7 @@
border-radius: 4px; border-radius: 4px;
} }
.dmp-blueprint-listing { .plan-blueprint-listing {
// margin-top: 1.3rem; // margin-top: 1.3rem;
// margin-left: 1rem; // margin-left: 1rem;
// margin-right: 2rem; // margin-right: 2rem;

View File

@ -53,7 +53,7 @@ export class AnnotationDialogComponent extends BaseComponent {
private formBuilder: FormBuilder = new FormBuilder(); private formBuilder: FormBuilder = new FormBuilder();
public annotationStatusFormGroup: UntypedFormGroup; public annotationStatusFormGroup: UntypedFormGroup;
public listingStatuses: Status[] = []; public listingStatuses: Status[] = [];
public dmpUsersMentionNames: string[] = []; public planUsersMentionNames: string[] = [];
@ViewChild('annotationStatus') annotationStatus: MatSelectionList; @ViewChild('annotationStatus') annotationStatus: MatSelectionList;
@ -76,7 +76,7 @@ export class AnnotationDialogComponent extends BaseComponent {
this.entityId = data.entityId; this.entityId = data.entityId;
this.anchor = data.anchor; this.anchor = data.anchor;
this.entityType = data.entityType; this.entityType = data.entityType;
this.dmpUsersMentionNames = data.planUsers.map(x => x.user.name); this.planUsersMentionNames = data.planUsers.map(x => x.user.name);
dialogRef.backdropClick().pipe(takeUntil(this._destroyed)).subscribe(() => dialogRef.close(this.changesMade)); dialogRef.backdropClick().pipe(takeUntil(this._destroyed)).subscribe(() => dialogRef.close(this.changesMade));
} }

View File

@ -25,26 +25,26 @@
</div> </div>
</div> </div>
<div class="card col-auto mt-0" [style.display]="isIntroCardVisible ? 'block' : 'none'"> <div class="card col-auto mt-0" [style.display]="isIntroCardVisible ? 'block' : 'none'">
<a *ngIf="this.hasDmps()" class="col-auto d-flex" (click)="dismissIntroCard()"><span class="ml-auto mt-3 material-icons clear-icon">clear</span></a> <a *ngIf="this.hasPlans()" class="col-auto d-flex" (click)="dismissIntroCard()"><span class="ml-auto mt-3 material-icons clear-icon">clear</span></a>
<p *ngIf="!this.hasDmps()" class="card-title mb-0 pt-4">{{'DASHBOARD.PLAN-QUESTION' | translate}}</p> <p *ngIf="!this.hasPlans()" class="card-title mb-0 pt-4">{{'DASHBOARD.PLAN-QUESTION' | translate}}</p>
<p *ngIf="!this.hasDmps()" class="card-content mb-0">{{'DASHBOARD.INFO-PLAN-TEXT' | translate}}</p> <p *ngIf="!this.hasPlans()" class="card-content mb-0">{{'DASHBOARD.INFO-PLAN-TEXT' | translate}}</p>
<p *ngIf="!this.hasDmps()" class="card-content pt-3 mb-0"> <p *ngIf="!this.hasPlans()" class="card-content pt-3 mb-0">
{{'DASHBOARD.NEW-QUESTION' | translate}} <a href="https://www.openaire.eu/how-to-create-a-data-management-plan" target="_blank"><u>{{'DASHBOARD.OPEN-AIR-GUIDE' | translate}}</u></a> {{'DASHBOARD.LEARN-MORE' | translate}} {{'DASHBOARD.NEW-QUESTION' | translate}} <a href="https://www.openaire.eu/how-to-create-a-data-management-plan" target="_blank"><u>{{'DASHBOARD.OPEN-AIR-GUIDE' | translate}}</u></a> {{'DASHBOARD.LEARN-MORE' | translate}}
</p> </p>
<p *ngIf="this.hasDmps()" class="card-content mb-0 pt-0">{{'DASHBOARD.PLAN-ABOUT-BEG' | translate}} <p *ngIf="this.hasPlans()" class="card-content mb-0 pt-0">{{'DASHBOARD.PLAN-ABOUT-BEG' | translate}}
<b>{{'DASHBOARD.DESCRIPTIONS-DASHBOARD-TEXT' | translate}}</b> <b>{{'DASHBOARD.DESCRIPTIONS-DASHBOARD-TEXT' | translate}}</b>
{{'DASHBOARD.PLAN-ABOUT-END' | translate}} {{'DASHBOARD.PLAN-ABOUT-END' | translate}}
</p> </p>
<div class="row d-flex align-items-center"> <div class="row d-flex align-items-center">
<div *ngIf="!this.hasDmps()" class="col-auto p-0 add-description-btn d-flex"> <div *ngIf="!this.hasPlans()" class="col-auto p-0 add-description-btn d-flex">
<div class="pr-2"> <div class="pr-2">
<button type="button" class="align-self-center normal-btn" (click)="openNewPlanDialog()">{{'DASHBOARD.START-YOUR-FIRST-PLAN' | translate}}</button> <button type="button" class="align-self-center normal-btn" (click)="openNewPlanDialog()">{{'DASHBOARD.START-YOUR-FIRST-PLAN' | translate}}</button>
</div> </div>
</div> </div>
<div *ngIf="this.hasDmps()" class="col-auto p-0 new-description-tour add-description-btn col-auto d-flex"> <div *ngIf="this.hasPlans()" class="col-auto p-0 new-description-tour add-description-btn col-auto d-flex">
<div class="pr-2"> <div class="pr-2">
<button mat-raised-button type="button" class="align-self-center yellow-btn" (click)="addNewDescription()">{{'DASHBOARD.ACTIONS.ADD-DESCRIPTION' | translate}}</button> <button mat-raised-button type="button" class="align-self-center yellow-btn" (click)="addNewDescription()">{{'DASHBOARD.ACTIONS.ADD-DESCRIPTION' | translate}}</button>
</div> </div>
@ -55,26 +55,26 @@
</div> </div>
</div> </div>
</div> </div>
<div *ngIf="this.hasDmps()" class="col"> <div *ngIf="this.hasPlans()" class="col">
<div class="latest-activity-title">{{'DASHBOARD.LATEST-ACTIVITY' | translate}}</div> <div class="latest-activity-title">{{'DASHBOARD.LATEST-ACTIVITY' | translate}}</div>
<mat-tab-group color="#00000" mat-stretch-tabs="false" mat-align-tabs="start" class="my-mat-tab remove-border-bottom" [selectedIndex]="indexFromCurrentType" (selectedTabChange)="currentType = $event.tab.ariaLabel"> <mat-tab-group color="#00000" mat-stretch-tabs="false" mat-align-tabs="start" class="my-mat-tab remove-border-bottom" [selectedIndex]="indexFromCurrentType" (selectedTabChange)="currentType = $event.tab.ariaLabel">
<mat-tab aria-label="recent" label="{{'DASHBOARD.ALL' | translate}}"> <mat-tab aria-label="recent" label="{{'DASHBOARD.ALL' | translate}}">
<app-recent-edited-activity [isActive]="currentType == 'recent'" [includeDmps]="true" [includeDescriptions]="true"></app-recent-edited-activity> <app-recent-edited-activity [isActive]="currentType == 'recent'" [includePlans]="true" [includeDescriptions]="true"></app-recent-edited-activity>
</mat-tab> </mat-tab>
<mat-tab aria-label="drafts" label="{{'DASHBOARD.DRAFTS' | translate}}"> <mat-tab aria-label="drafts" label="{{'DASHBOARD.DRAFTS' | translate}}">
<app-recent-edited-activity [isActive]="currentType == 'drafts'" [includeDmps]="true" [includeDescriptions]="true" [onlyDrafts]="true" type="drafts" [selectedType]="currentType"></app-recent-edited-activity> <app-recent-edited-activity [isActive]="currentType == 'drafts'" [includePlans]="true" [includeDescriptions]="true" [onlyDrafts]="true" type="drafts" [selectedType]="currentType"></app-recent-edited-activity>
</mat-tab>> </mat-tab>>
<mat-tab aria-label="dmps" label="{{'DASHBOARD.PLANS' | translate}}"> <mat-tab aria-label="plans" label="{{'DASHBOARD.PLANS' | translate}}">
<app-recent-edited-activity [isActive]="currentType == 'dmps'" [includeDmps]="true" type="dmps" [selectedType]="currentType"></app-recent-edited-activity> <app-recent-edited-activity [isActive]="currentType == 'plans'" [includePlans]="true" type="plans" [selectedType]="currentType"></app-recent-edited-activity>
</mat-tab> </mat-tab>
<mat-tab aria-label="descriptions" label="{{'DASHBOARD.DESCRIPTIONS' | translate}}"> <mat-tab aria-label="descriptions" label="{{'DASHBOARD.DESCRIPTIONS' | translate}}">
<app-recent-edited-activity [isActive]="currentType == 'descriptions'" [includeDescriptions]="true" type="descriptions" [selectedType]="currentType" [hasDmps]="this.hasDmps()" (addNewDescription)="addNewDescription($event)"></app-recent-edited-activity> <app-recent-edited-activity [isActive]="currentType == 'descriptions'" [includeDescriptions]="true" type="descriptions" [selectedType]="currentType" [hasPlans]="this.hasPlans()" (addNewDescription)="addNewDescription($event)"></app-recent-edited-activity>
</mat-tab> </mat-tab>
</mat-tab-group> </mat-tab-group>
</div> </div>
</div> </div>
<!-- Right Sidebar --> <!-- Right Sidebar -->
<div *ngIf="!this.hasDmps()" class="col-12 col-xl-2 mb-4 stats"> <div *ngIf="!this.hasPlans()" class="col-12 col-xl-2 mb-4 stats">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<div class="personal-usage" style="width: fit-content;"> <div class="personal-usage" style="width: fit-content;">
@ -101,7 +101,7 @@
</div> </div>
</div> </div>
</div> </div>
<div *ngIf="this.hasDmps()" class="col-12 col-xl-2 mb-4 stats"> <div *ngIf="this.hasPlans()" class="col-12 col-xl-2 mb-4 stats">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<div class="personal-usage" style="width: fit-content;"><span>{{'DASHBOARD.PERSONAL-USAGE' | translate}}</span></div> <div class="personal-usage" style="width: fit-content;"><span>{{'DASHBOARD.PERSONAL-USAGE' | translate}}</span></div>
@ -162,7 +162,7 @@
</div> </div>
</div> </div>
<div class="col-12 col-xl-auto mb-4 stats"> <div class="col-12 col-xl-auto mb-4 stats">
<div *ngIf="!hasDmps()" class="row flex-xl-column"> <div *ngIf="!hasPlans()" class="row flex-xl-column">
<div class="col-12"> <div class="col-12">
<div class="personal-usage"><span>{{'DASHBOARD.PUBLIC-USAGE' | translate}}</span></div> <div class="personal-usage"><span>{{'DASHBOARD.PUBLIC-USAGE' | translate}}</span></div>
</div> </div>
@ -184,7 +184,7 @@
</div> </div>
</div> </div>
<div *ngIf="hasDmps()" class="row flex-xl-column"> <div *ngIf="hasPlans()" class="row flex-xl-column">
<div class="col-12"> <div class="col-12">
<div class="personal-usage"><span>{{'DASHBOARD.PUBLIC-USAGE' | translate}}</span></div> <div class="personal-usage"><span>{{'DASHBOARD.PUBLIC-USAGE' | translate}}</span></div>
</div> </div>

View File

@ -155,7 +155,7 @@
padding-left: 3rem; padding-left: 3rem;
} }
.dmp-card, .plan-card,
.description-card { .description-card {
min-width: 712px; min-width: 712px;
/* min-height: 308px; */ /* min-height: 308px; */
@ -182,7 +182,7 @@ input[type="text"] {
padding-left: 15px; padding-left: 15px;
} }
.dmp-label { .plan-label {
background: var(--primary-color) 0% 0% no-repeat padding-box; background: var(--primary-color) 0% 0% no-repeat padding-box;
border-radius: 4px 0px; border-radius: 4px 0px;
opacity: 1; opacity: 1;
@ -213,7 +213,7 @@ input[type="text"] {
// padding-bottom: 0.4rem; // padding-bottom: 0.4rem;
} }
.dmp-subtitle, .plan-subtitle,
.description-subtitle { .description-subtitle {
.icon-align { .icon-align {
@ -225,7 +225,7 @@ input[type="text"] {
} }
.description-card-actions, .description-card-actions,
.dmp-card-actions { .plan-card-actions {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
border-top: 1px solid #dbdbdb; border-top: 1px solid #dbdbdb;
@ -234,24 +234,24 @@ input[type="text"] {
} }
.description-card-actions a, .description-card-actions a,
.dmp-card-actions a { .plan-card-actions a {
color: #848484 !important; color: #848484 !important;
text-decoration: none !important; text-decoration: none !important;
} }
.description-card-actions a:hover, .description-card-actions a:hover,
.dmp-card-actions a:hover { .plan-card-actions a:hover {
color: var(--primary-color) !important; color: var(--primary-color) !important;
} }
.dmp-description-descriptions-title { .plan-description-descriptions-title {
color: #000000; color: #000000;
opacity: 0.6; opacity: 0.6;
padding-top: 1.5rem; padding-top: 1.5rem;
padding-bottom: 0.8rem; padding-bottom: 0.8rem;
} }
.dmp-description-descriptions-name { .plan-description-descriptions-name {
color: #000000; color: #000000;
opacity: 0.6; opacity: 0.6;
font-weight: 700; font-weight: 700;

View File

@ -57,7 +57,7 @@ export class DashboardComponent extends BaseComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.route.queryParams.subscribe(params => { this.route.queryParams.subscribe(params => {
let type = params['type']; let type = params['type'];
if (type || type == "recent" || (type == "drafts" && this.isAuthenticated()) || type == "dmps" || type == "descriptions") { if (type || type == "recent" || (type == "drafts" && this.isAuthenticated()) || type == "plans" || type == "descriptions") {
this.currentType = type; this.currentType = type;
} else { } else {
this.currentType = "recent"; this.currentType = "recent";
@ -98,7 +98,7 @@ export class DashboardComponent extends BaseComponent implements OnInit {
if (this.currentType == "drafts") { if (this.currentType == "drafts") {
return 1; return 1;
} }
if (this.currentType == "dmps") { if (this.currentType == "plans") {
return this.isAuthenticated() ? 2 : 1; return this.isAuthenticated() ? 2 : 1;
} }
if (this.currentType == "descriptions") { if (this.currentType == "descriptions") {
@ -126,7 +126,7 @@ export class DashboardComponent extends BaseComponent implements OnInit {
} }
} }
public hasDmps(): boolean { public hasPlans(): boolean {
if (this.dashboardStatistics) { if (this.dashboardStatistics) {
return this.dashboardStatistics.planCount !== 0 return this.dashboardStatistics.planCount !== 0
|| this.dashboardStatistics.descriptionCount !== 0 || this.dashboardStatistics.descriptionCount !== 0
@ -167,7 +167,7 @@ export class DashboardComponent extends BaseComponent implements OnInit {
useOrb: true, useOrb: true,
steps: [ steps: [
{ {
selector: '.new-dmp-dialog', selector: '.new-plan-dialog',
content: 'Step 1', content: 'Step 1',
orientation: Orientation.BottomRight, orientation: Orientation.BottomRight,
isStepUnique: false, isStepUnique: false,
@ -199,10 +199,10 @@ export class DashboardComponent extends BaseComponent implements OnInit {
] ]
}; };
public setDashboardTourDmpText(): void { public setDashboardTourPlanText(): void {
const dmpText = this.language.instant('DASHBOARD.TOUR-GUIDE.PLAN') + '\n\n' + const planText = this.language.instant('DASHBOARD.TOUR-GUIDE.PLAN') + '\n\n' +
this.language.instant('DASHBOARD.TOUR-GUIDE.START-NEW'); this.language.instant('DASHBOARD.TOUR-GUIDE.START-NEW');
this.dashboardTour.steps[0].title = dmpText; this.dashboardTour.steps[0].title = planText;
} }
public setDashboardImportFileText(): void { public setDashboardImportFileText(): void {
@ -222,7 +222,7 @@ export class DashboardComponent extends BaseComponent implements OnInit {
} }
openDashboardTour() { openDashboardTour() {
this.setDashboardTourDmpText(); this.setDashboardTourPlanText();
this.setDashboardImportFileText(); this.setDashboardImportFileText();
this.setDashboardStartWizardText(); this.setDashboardStartWizardText();
this.setDescriptionText(); this.setDescriptionText();

View File

@ -31,14 +31,14 @@
<!-- End of Search Filter --> <!-- End of Search Filter -->
</div> </div>
<div *ngFor="let item of listingItems; let i = index"> <div *ngFor="let item of listingItems; let i = index">
<app-dmp-listing-item-component *ngIf="item.plan" [showDivider]="i != (listingItems.length - 1)" [dmp]="item.plan" [isPublic]="false"></app-dmp-listing-item-component> <app-plan-listing-item-component *ngIf="item.plan" [showDivider]="i != (listingItems.length - 1)" [plan]="item.plan" [isPublic]="false"></app-plan-listing-item-component>
<app-description-listing-item-component *ngIf="item?.description" [showDivider]="i != (listingItems.length - 1)" [description]="item?.description" [isPublic]="false" ></app-description-listing-item-component> <app-description-listing-item-component *ngIf="item?.description" [showDivider]="i != (listingItems.length - 1)" [description]="item?.description" [isPublic]="false" ></app-description-listing-item-component>
</div> </div>
<div class="text-muted d-flex justify-content-center mt-5" *ngIf="listingItems && listingItems.length > 0 && this.lookup.page.offset >= currentPage*pageSize"> <div class="text-muted d-flex justify-content-center mt-5" *ngIf="listingItems && listingItems.length > 0 && this.lookup.page.offset >= currentPage*pageSize">
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}} {{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
</div> </div>
<div class="row justify-content-center mt-5" *ngIf="listingItems?.length == 0 && onlyDescriptions && hasDmps"> <div class="row justify-content-center mt-5" *ngIf="listingItems?.length == 0 && onlyDescriptions && hasPlans">
<div class="col-auto p-0 add-description"> <div class="col-auto p-0 add-description">
<button mat-raised-button type="button" class="yellow-btn" (click)="addDescription()">{{'DASHBOARD.ACTIONS.ADD-DESCRIPTION' | translate}}</button> <button mat-raised-button type="button" class="yellow-btn" (click)="addDescription()">{{'DASHBOARD.ACTIONS.ADD-DESCRIPTION' | translate}}</button>
</div> </div>

View File

@ -13,7 +13,7 @@ input[type="text"] {
padding-left: 15px; padding-left: 15px;
} }
.dmp-label { .plan-label {
background: var(--primary-color) 0% 0% no-repeat padding-box; background: var(--primary-color) 0% 0% no-repeat padding-box;
border-radius: 4px 0px; border-radius: 4px 0px;
opacity: 1; opacity: 1;
@ -31,7 +31,7 @@ input[type="text"] {
} }
.description-card-actions, .description-card-actions,
.dmp-card-actions { .plan-card-actions {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
border-top: 1px solid #dbdbdb; border-top: 1px solid #dbdbdb;
@ -40,7 +40,7 @@ input[type="text"] {
} }
.description-card-actions, .description-card-actions,
.dmp-card-actions { .plan-card-actions {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
border-top: 1px solid #dbdbdb; border-top: 1px solid #dbdbdb;
@ -49,24 +49,24 @@ input[type="text"] {
} }
.description-card-actions a, .description-card-actions a,
.dmp-card-actions a { .plan-card-actions a {
color: #848484 !important; color: #848484 !important;
text-decoration: none !important; text-decoration: none !important;
} }
.description-card-actions a:hover, .description-card-actions a:hover,
.dmp-card-actions a:hover { .plan-card-actions a:hover {
color: var(--primary-color) !important; color: var(--primary-color) !important;
} }
.dmp-description-descriptions-title { .plan-description-descriptions-title {
color: #000000; color: #000000;
opacity: 0.6; opacity: 0.6;
padding-top: 1.5rem; padding-top: 1.5rem;
padding-bottom: 0.8rem; padding-bottom: 0.8rem;
} }
.dmp-description-descriptions-name { .plan-description-descriptions-name {
color: #000000; color: #000000;
opacity: 0.6; opacity: 0.6;
font-weight: 700; font-weight: 700;

View File

@ -44,18 +44,18 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
@Input() type: string; @Input() type: string;
@Input() selectedType: string; @Input() selectedType: string;
@Input() includeDescriptions: boolean = false; @Input() includeDescriptions: boolean = false;
@Input() includeDmps: boolean = false; @Input() includePlans: boolean = false;
@Input() onlyDrafts: boolean = false; @Input() onlyDrafts: boolean = false;
@Input() hasDmps: boolean = false; @Input() hasPlans: boolean = false;
@Output() addNewDescription: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); @Output() addNewDescription: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
get onlyPlans(): boolean { get onlyPlans(): boolean {
return this.includeDmps && !this.includeDescriptions; return this.includePlans && !this.includeDescriptions;
} }
get onlyDescriptions(): boolean { get onlyDescriptions(): boolean {
return !this.includeDmps && this.includeDescriptions; return !this.includePlans && this.includeDescriptions;
} }
pageLessSize= this.pageSize; pageLessSize= this.pageSize;
@ -166,7 +166,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
this.lookup.like = this.formGroup.get('like').value; this.lookup.like = this.formGroup.get('like').value;
this.lookup.project = { this.lookup.project = {
fields : [ fields : [
...(this.includeDmps ? this._getPlanLookup() : []), ...(this.includePlans ? this._getPlanLookup() : []),
...(this.includeDescriptions ? this._getDescriptionLookup() : []) ...(this.includeDescriptions ? this._getDescriptionLookup() : [])
] ]
}; };

View File

@ -7,7 +7,7 @@
<div class="row mt-3"> <div class="row mt-3">
<div class="col-12"> <div class="col-12">
<mat-form-field class="w-100"> <mat-form-field class="w-100">
<app-single-auto-complete [formControl]="data.formGroup.get('planId')" placeholder="{{'DESCRIPTION-COPY-DIALOG.SELECT-PLAN' | translate}}" [configuration]="dmpAutoCompleteConfiguration"> <app-single-auto-complete [formControl]="data.formGroup.get('planId')" placeholder="{{'DESCRIPTION-COPY-DIALOG.SELECT-PLAN' | translate}}" [configuration]="planAutoCompleteConfiguration">
</app-single-auto-complete> </app-single-auto-complete>
</mat-form-field> </mat-form-field>
</div> </div>

View File

@ -26,10 +26,9 @@ import { DescriptionTemplatesInSection, PlanBlueprint, PlanBlueprintDefinition,
}) })
export class DescriptionCopyDialogComponent { export class DescriptionCopyDialogComponent {
dmpModel: Plan;
sections: PlanBlueprintDefinitionSection[] = []; sections: PlanBlueprintDefinitionSection[] = [];
descriptionDescriptionTemplateLabel: String; descriptionDescriptionTemplateLabel: String;
dmpAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { //TODO: add filter to only get DMPs that have connection with the same Description Template group. planAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { //TODO: add filter to only get plans that have connection with the same Description Template group.
initialItems: (data?: any) => this.planService.query(this.buildPlanLookup(null,null,null, this.planDescriptionTemplateLookup)).pipe(map(x => x.items)), initialItems: (data?: any) => this.planService.query(this.buildPlanLookup(null,null,null, this.planDescriptionTemplateLookup)).pipe(map(x => x.items)),
filterFn: (searchQuery: string, data?: any) => this.planService.query(this.buildPlanLookup(searchQuery, null, null, this.planDescriptionTemplateLookup)).pipe(map(x => x.items)), filterFn: (searchQuery: string, data?: any) => this.planService.query(this.buildPlanLookup(searchQuery, null, null, this.planDescriptionTemplateLookup)).pipe(map(x => x.items)),
getSelectedItem: (selectedItem: any) => this.planService.query(this.buildPlanLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])), getSelectedItem: (selectedItem: any) => this.planService.query(this.buildPlanLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])),
@ -83,16 +82,16 @@ export class DescriptionCopyDialogComponent {
ngOnInit() { ngOnInit() {
} }
findSection(dmp: Plan){ findSection(plan: Plan){
const availableSectionIds = dmp.planDescriptionTemplates?.filter(x => x.descriptionTemplateGroupId === this.data.descriptionTemplate.groupId && x.isActive == IsActive.Active).map(y => y.sectionId); const availableSectionIds = plan.planDescriptionTemplates?.filter(x => x.descriptionTemplateGroupId === this.data.descriptionTemplate.groupId && x.isActive == IsActive.Active).map(y => y.sectionId);
this.sections = dmp.blueprint.definition.sections.filter(x => x.hasTemplates == true && availableSectionIds?.includes(x.id)) || []; this.sections = plan.blueprint.definition.sections.filter(x => x.hasTemplates == true && availableSectionIds?.includes(x.id)) || [];
if(this.sections.length == 1){ if(this.sections.length == 1){
this.data.formGroup.get('sectionId').setValue(this.sections[0].id); this.data.formGroup.get('sectionId').setValue(this.sections[0].id);
}else { }else {
this.data.formGroup.get('sectionId').setValue(null); this.data.formGroup.get('sectionId').setValue(null);
} }
return dmp.id return plan.id
} }
cancel() { cancel() {

View File

@ -57,14 +57,14 @@
color: var(--primary-color-3) !important; color: var(--primary-color-3) !important;
} }
.dmp-link { .plan-link {
color: #3fafac; color: #3fafac;
font-weight: 400; font-weight: 400;
font-size: 16px; font-size: 16px;
cursor: pointer; cursor: pointer;
} }
.dmp-link:hover { .plan-link:hover {
text-decoration: underline; text-decoration: underline;
} }
} }

View File

@ -15,9 +15,9 @@
<ng-template #viewOnlyTemplate> <ng-template #viewOnlyTemplate>
<div class="description-title">{{'DESCRIPTION-EDITOR.TITLE-PREVIEW-DESCRIPTION' | translate}}</div> <div class="description-title">{{'DESCRIPTION-EDITOR.TITLE-PREVIEW-DESCRIPTION' | translate}}</div>
</ng-template> </ng-template>
<div *ngIf="item?.plan?.id" class="d-flex flex-direction-row dmp-info"> <div *ngIf="item?.plan?.id" class="d-flex flex-direction-row plan-info">
<div class="col-auto description-to-dmp">{{'DESCRIPTION-EDITOR.TO-PLAN' | translate}}</div> <div class="col-auto description-to-plan">{{'DESCRIPTION-EDITOR.TO-PLAN' | translate}}</div>
<div class="dmp-title p-0">:&nbsp;{{ item?.plan?.label }}</div> <div class="plan-title p-0">:&nbsp;{{ item?.plan?.label }}</div>
<div class="col-auto d-flex align-items-center"> <div class="col-auto d-flex align-items-center">
<a [routerLink]="routerUtils.generateUrl(['/plans/overview/', item.plan.id])" target="_blank" class="pointer open-in-new-icon"> <a [routerLink]="routerUtils.generateUrl(['/plans/overview/', item.plan.id])" target="_blank" class="pointer open-in-new-icon">
<mat-icon class="size-18">open_in_new</mat-icon> <mat-icon class="size-18">open_in_new</mat-icon>
@ -86,11 +86,11 @@
<div class="row editor-content"> <div class="row editor-content">
<div style="width: 22em;" class="d-flex flex-column"> <div style="width: 22em;" class="d-flex flex-column">
<div class="stepper-back row"> <div class="stepper-back row">
<div class="col-auto d-flex align-items-center back-to-dmp" (click)="backToDmp(this.formGroup.get('planId').value)"> <div class="col-auto d-flex align-items-center back-to-plan" (click)="backToPlan(this.formGroup.get('planId').value)">
<mat-icon class="back-icon pointer">chevron_left</mat-icon> <mat-icon class="back-icon pointer">chevron_left</mat-icon>
<span class="pointer">{{'DESCRIPTION-EDITOR.ACTIONS.BACK-TO' | translate}}</span> <span class="pointer">{{'DESCRIPTION-EDITOR.ACTIONS.BACK-TO' | translate}}</span>
</div> </div>
<div class="col-auto dmp-label ml-1">{{'DESCRIPTION-EDITOR.PLAN' | translate}}</div> <div class="col-auto plan-label ml-1">{{'DESCRIPTION-EDITOR.PLAN' | translate}}</div>
</div> </div>
<div class="row stepper-title"> <div class="row stepper-title">
<div class="col-12 pl-0 mb-1"><span>{{'DESCRIPTION-EDITOR.TOC.TITLE' | translate}}</span></div> <div class="col-12 pl-0 mb-1"><span>{{'DESCRIPTION-EDITOR.TOC.TITLE' | translate}}</span></div>
@ -178,7 +178,7 @@
[validationErrorModel]="editorModel.validationErrorModel" [validationErrorModel]="editorModel.validationErrorModel"
[isNew]="isNew || isCopy" [isNew]="isNew || isCopy"
[canReview]="canReview" [canReview]="canReview"
[dmpUsers]="item?.plan?.planUsers ?? []" [planUsers]="item?.plan?.planUsers ?? []"
></app-description-form> ></app-description-form>
</div> </div>
</div> </div>

View File

@ -202,7 +202,7 @@
align-items: center; align-items: center;
} }
.description-to-dmp { .description-to-plan {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0; padding: 0;
@ -213,11 +213,11 @@
line-height: 25px; line-height: 25px;
} }
.dmp-info { .plan-info {
padding-top: 0.75rem; padding-top: 0.75rem;
} }
.dmp-label { .plan-label {
min-width: 67px; min-width: 67px;
height: 37px; height: 37px;
background: var(--primary-color) 0% 0% no-repeat padding-box; background: var(--primary-color) 0% 0% no-repeat padding-box;
@ -229,7 +229,7 @@
justify-content: center; justify-content: center;
} }
.dmp-title { .plan-title {
text-align: left; text-align: left;
font-weight: 700; font-weight: 700;
font-size: 1rem; font-size: 1rem;
@ -345,7 +345,7 @@
} }
} }
.back-to-dmp:hover { .back-to-plan:hover {
background: #ececec; background: #ececec;
border-radius: 6px; border-radius: 6px;
} }

View File

@ -140,7 +140,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
const planSectionId = params['planSectionId']; const planSectionId = params['planSectionId'];
const isPublicDescription = params['public']; const isPublicDescription = params['public'];
const newDmpId = params['newDmpId']; const newPlanId = params['newPlanId'];
this.scrollToField = this.route.snapshot.data['scrollToField'] ?? false this.scrollToField = this.route.snapshot.data['scrollToField'] ?? false
this.anchorFieldsetId = params['fieldsetId'] ?? null; this.anchorFieldsetId = params['fieldsetId'] ?? null;
@ -151,7 +151,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
this.viewOnly = isPublicDescription; this.viewOnly = isPublicDescription;
//Regular Editor case //Regular Editor case
if (itemId != null && newDmpId == null) { if (itemId != null && newPlanId == null) {
this.checkLock(this.item.id, LockTargetType.Description, 'DESCRIPTION-EDITOR.LOCKED-DIALOG.TITLE', 'DESCRIPTION-EDITOR.LOCKED-DIALOG.MESSAGE'); this.checkLock(this.item.id, LockTargetType.Description, 'DESCRIPTION-EDITOR.LOCKED-DIALOG.TITLE', 'DESCRIPTION-EDITOR.LOCKED-DIALOG.MESSAGE');
} }
@ -333,7 +333,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
const planId = this.formGroup.get('planId').value; const planId = this.formGroup.get('planId').value;
this.formGroup = null; this.formGroup = null;
this.backToDmp(planId); this.backToPlan(planId);
}); });
} }
@ -414,7 +414,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
this.formService.validateAllFormFields(this.formGroup); this.formService.validateAllFormFields(this.formGroup);
} }
backToDmp(planId) { backToPlan(planId) {
this.router.navigate([this.routerUtils.generateUrl(['/plans/', 'edit/', planId])]); this.router.navigate([this.routerUtils.generateUrl(['/plans/', 'edit/', planId])]);
} }
@ -756,12 +756,12 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
}); });
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) { if (result) {
const dmpUserRemovePersist: DescriptionStatusPersist = { const planUserRemovePersist: DescriptionStatusPersist = {
id: this.formGroup.get('id').value, id: this.formGroup.get('id').value,
status: DescriptionStatus.Draft, status: DescriptionStatus.Draft,
hash: this.formGroup.get('hash').value hash: this.formGroup.get('hash').value
}; };
this.descriptionService.persistStatus(dmpUserRemovePersist, DescriptionEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed)) this.descriptionService.persistStatus(planUserRemovePersist, DescriptionEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed))
.subscribe(data => { .subscribe(data => {
this.isFinalized = false; this.isFinalized = false;
this.refreshData(); this.refreshData();

View File

@ -35,7 +35,7 @@ export class DescriptionFormFieldSetComponent extends BaseComponent {
@Input() hideAnnotations: boolean = false; @Input() hideAnnotations: boolean = false;
@Input() canReview: boolean = false; @Input() canReview: boolean = false;
@Input() numbering: string; @Input() numbering: string;
@Input() dmpUsers: PlanUser[] = []; @Input() planUsers: PlanUser[] = [];
get isMultiplicityEnabled() { get isMultiplicityEnabled() {
return this.fieldSet.hasMultiplicity && this.fieldSet.multiplicity != null; return this.fieldSet.hasMultiplicity && this.fieldSet.multiplicity != null;
@ -186,7 +186,7 @@ export class DescriptionFormFieldSetComponent extends BaseComponent {
entityId: this.descriptionId, entityId: this.descriptionId,
anchor: fieldSetId, anchor: fieldSetId,
entityType: AnnotationEntityType.Description, entityType: AnnotationEntityType.Description,
planUsers: this.dmpUsers planUsers: this.planUsers
} }
}); });
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(changesMade => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(changesMade => {

View File

@ -25,7 +25,7 @@
[isChild]="false" [isChild]="false"
[hideAnnotations]="isNew" [hideAnnotations]="isNew"
[canReview]="canReview" [canReview]="canReview"
[dmpUsers]="dmpUsers" [planUsers]="planUsers"
></app-description-form-field-set> ></app-description-form-field-set>
</div> </div>
</div> </div>

View File

@ -26,7 +26,7 @@ export class DescriptionFormSectionComponent extends BaseComponent implements On
@Input() visibilityRulesService: VisibilityRulesService; @Input() visibilityRulesService: VisibilityRulesService;
@Input() path: string; @Input() path: string;
@Input() descriptionId: Guid; @Input() descriptionId: Guid;
@Input() dmpUsers: PlanUser[] = []; @Input() planUsers: PlanUser[] = [];
// @Input() descriptionTemplateId: String; // @Input() descriptionTemplateId: String;

View File

@ -15,7 +15,7 @@
</mat-expansion-panel-header> </mat-expansion-panel-header>
<ng-container *ngFor="let section of page.sections; let i = index;"> <ng-container *ngFor="let section of page.sections; let i = index;">
<div class="row" *ngIf="visibilityRulesService.isVisibleMap[section.id]"> <div class="row" *ngIf="visibilityRulesService.isVisibleMap[section.id]">
<app-description-form-section class="col-12" [section]="section" [canReview]="canReview" [path]="(z+1)+'.'+(i+1)" [pathName]="'pages.'+z+'.sections.'+i" [propertiesFormGroup]="propertiesFormGroup" [descriptionId]="descriptionId" [visibilityRulesService]="visibilityRulesService" (askedToScroll)="onAskedToScroll(expansionPanel, $event)" [linkToScroll]="linkToScroll" [validationErrorModel]="validationErrorModel" [isNew]="isNew" [dmpUsers]="dmpUsers"></app-description-form-section> <app-description-form-section class="col-12" [section]="section" [canReview]="canReview" [path]="(z+1)+'.'+(i+1)" [pathName]="'pages.'+z+'.sections.'+i" [propertiesFormGroup]="propertiesFormGroup" [descriptionId]="descriptionId" [visibilityRulesService]="visibilityRulesService" (askedToScroll)="onAskedToScroll(expansionPanel, $event)" [linkToScroll]="linkToScroll" [validationErrorModel]="validationErrorModel" [isNew]="isNew" [planUsers]="planUsers"></app-description-form-section>
</div> </div>
</ng-container> </ng-container>
</mat-expansion-panel> </mat-expansion-panel>

View File

@ -27,7 +27,7 @@ export class DescriptionFormComponent extends BaseComponent implements OnInit, O
@Input() datasetDescription: String; @Input() datasetDescription: String;
@Input() linkToScroll: LinkToScroll; @Input() linkToScroll: LinkToScroll;
@Input() validationErrorModel: ValidationErrorModel; @Input() validationErrorModel: ValidationErrorModel;
@Input() dmpUsers: PlanUser[] = []; @Input() planUsers: PlanUser[] = [];
@Output() formChanged: EventEmitter<any> = new EventEmitter(); @Output() formChanged: EventEmitter<any> = new EventEmitter();

View File

@ -31,7 +31,7 @@ export class PrefillDescriptionDialogComponent extends BaseComponent implements
prefillSelected: boolean = false; prefillSelected: boolean = false;
prefillForm: UntypedFormGroup; prefillForm: UntypedFormGroup;
dmp: Plan; plan: Plan;
planSectionId: Guid; planSectionId: Guid;
availableDescriptionTemplates: DescriptionTemplate[] = []; availableDescriptionTemplates: DescriptionTemplate[] = [];
@ -43,13 +43,13 @@ export class PrefillDescriptionDialogComponent extends BaseComponent implements
@Inject(MAT_DIALOG_DATA) public data: any) { @Inject(MAT_DIALOG_DATA) public data: any) {
super(); super();
this.dmp = data.plan; this.plan = data.plan;
this.planSectionId = data.planSectionId; this.planSectionId = data.planSectionId;
this.availableDescriptionTemplates = this.dmp.planDescriptionTemplates.filter(x => x.sectionId == this.planSectionId && x.isActive == IsActive.Active).map(x => x.currentDescriptionTemplate); this.availableDescriptionTemplates = this.plan.planDescriptionTemplates.filter(x => x.sectionId == this.planSectionId && x.isActive == IsActive.Active).map(x => x.currentDescriptionTemplate);
} }
ngOnInit() { ngOnInit() {
const availablePrefillingSourcesIds = this.dmp.blueprint.definition.sections.filter(x => x.id === this.planSectionId)[0].prefillingSources?.map(x => x.id) || null; const availablePrefillingSourcesIds = this.plan.blueprint.definition.sections.filter(x => x.id === this.planSectionId)[0].prefillingSources?.map(x => x.id) || null;
this.singlePrefillingSourceAutoCompleteConfiguration = this.prefillingSourceService.getSingleAutocompleteConfiguration(availablePrefillingSourcesIds); this.singlePrefillingSourceAutoCompleteConfiguration = this.prefillingSourceService.getSingleAutocompleteConfiguration(availablePrefillingSourcesIds);
this.progressIndicationService.getProgressIndicationObservable().pipe(takeUntil(this._destroyed)).subscribe(x => { this.progressIndicationService.getProgressIndicationObservable().pipe(takeUntil(this._destroyed)).subscribe(x => {

View File

@ -34,7 +34,7 @@ export class DescriptionEditorEntityResolver extends BaseEditorResolver {
public static lookupFields(): string[] { public static lookupFields(): string[] {
return [ return [
...DescriptionEditorEntityResolver.descriptionLookupFields(), ...DescriptionEditorEntityResolver.descriptionLookupFields(),
...DescriptionEditorEntityResolver.dmpLookupFields(nameof<Description>(x => x.plan)), ...DescriptionEditorEntityResolver.planLookupFields(nameof<Description>(x => x.plan)),
...DescriptionEditorEntityResolver.descriptionTemplateLookupFieldsForDescrption(), ...DescriptionEditorEntityResolver.descriptionTemplateLookupFieldsForDescrption(),
] ]
} }
@ -115,7 +115,7 @@ export class DescriptionEditorEntityResolver extends BaseEditorResolver {
] ]
} }
public static dmpLookupFields(prefix?: string): string[] { public static planLookupFields(prefix?: string): string[] {
return [ return [
(prefix ? prefix + '.' : '') + [nameof<Plan>(x => x.id)].join('.'), (prefix ? prefix + '.' : '') + [nameof<Plan>(x => x.id)].join('.'),
(prefix ? prefix + '.' : '') + [nameof<Plan>(x => x.label)].join('.'), (prefix ? prefix + '.' : '') + [nameof<Plan>(x => x.label)].join('.'),
@ -176,20 +176,20 @@ export class DescriptionEditorEntityResolver extends BaseEditorResolver {
} }
return this.descriptionService.getSingle(Guid.parse(id), fields).pipe(tap(d => this.breadcrumbService.addIdResolvedValue(d.id.toString(), d.label))); return this.descriptionService.getSingle(Guid.parse(id), fields).pipe(tap(d => this.breadcrumbService.addIdResolvedValue(d.id.toString(), d.label)));
} else if (planId != null && planSectionId != null && copyPlanId == null) { } else if (planId != null && planSectionId != null && copyPlanId == null) {
return this.planService.getSingle(Guid.parse(planId), DescriptionEditorEntityResolver.dmpLookupFields()) return this.planService.getSingle(Guid.parse(planId), DescriptionEditorEntityResolver.planLookupFields())
.pipe(tap(x => { .pipe(tap(x => {
this.breadcrumbService.addExcludedParam(planId, true); this.breadcrumbService.addExcludedParam(planId, true);
this.breadcrumbService.addIdResolvedValue(planSectionId, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW")); this.breadcrumbService.addIdResolvedValue(planSectionId, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW"));
}), takeUntil(this._destroyed), map(dmp => { }), takeUntil(this._destroyed), map(plan => {
const description: Description = {}; const description: Description = {};
description.plan = dmp; description.plan = plan;
description.planDescriptionTemplate = { description.planDescriptionTemplate = {
sectionId: Guid.parse(planSectionId) sectionId: Guid.parse(planSectionId)
} }
return description; return description;
})); }));
} else if (copyPlanId != null && id != null && planSectionId != null) { } else if (copyPlanId != null && id != null && planSectionId != null) {
return this.planService.getSingle(Guid.parse(copyPlanId), DescriptionEditorEntityResolver.dmpLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(dmp => { return this.planService.getSingle(Guid.parse(copyPlanId), DescriptionEditorEntityResolver.planLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(plan => {
return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorEntityResolver.cloneLookupFields()) return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorEntityResolver.cloneLookupFields())
.pipe(tap(x => { .pipe(tap(x => {
this.breadcrumbService.addExcludedParam(copyPlanId, true) this.breadcrumbService.addExcludedParam(copyPlanId, true)
@ -200,9 +200,9 @@ export class DescriptionEditorEntityResolver extends BaseEditorResolver {
description.id = null; description.id = null;
description.hash = null; description.hash = null;
description.status = DescriptionStatus.Draft; description.status = DescriptionStatus.Draft;
description.plan = dmp; description.plan = plan;
description.planDescriptionTemplate = { description.planDescriptionTemplate = {
id: dmp.planDescriptionTemplates.filter(x => x.sectionId == Guid.parse(planSectionId) && x.descriptionTemplateGroupId == description.descriptionTemplate.groupId)[0].id, id: plan.planDescriptionTemplates.filter(x => x.sectionId == Guid.parse(planSectionId) && x.descriptionTemplateGroupId == description.descriptionTemplate.groupId)[0].id,
sectionId: Guid.parse(planSectionId) sectionId: Guid.parse(planSectionId)
} }
return description; return description;

View File

@ -46,13 +46,13 @@ export class DescriptionEditorPermissionsResolver extends BaseEditorResolver {
})); }));
} else if (planId != null && planSectionId != null && copyPlanId == null) { } else if (planId != null && planSectionId != null && copyPlanId == null) {
return this.planService.getSingle(Guid.parse(planId), DescriptionEditorEntityResolver.dmpLookupFields()) return this.planService.getSingle(Guid.parse(planId), DescriptionEditorEntityResolver.planLookupFields())
.pipe(tap(x => { .pipe(tap(x => {
this.breadcrumbService.addExcludedParam(planId, true); this.breadcrumbService.addExcludedParam(planId, true);
this.breadcrumbService.addIdResolvedValue(planSectionId, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW")); this.breadcrumbService.addIdResolvedValue(planSectionId, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW"));
}), takeUntil(this._destroyed), map(dmp => { }), takeUntil(this._destroyed), map(plan => {
const description: Description = {}; const description: Description = {};
description.plan = dmp; description.plan = plan;
description.planDescriptionTemplate = { description.planDescriptionTemplate = {
sectionId: Guid.parse(planSectionId) sectionId: Guid.parse(planSectionId)
} }
@ -67,7 +67,7 @@ export class DescriptionEditorPermissionsResolver extends BaseEditorResolver {
return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed)); return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed));
})); }));
} else if (copyPlanId != null && id != null && planSectionId != null) { } else if (copyPlanId != null && id != null && planSectionId != null) {
return this.planService.getSingle(Guid.parse(copyPlanId), DescriptionEditorEntityResolver.dmpLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(dmp => { return this.planService.getSingle(Guid.parse(copyPlanId), DescriptionEditorEntityResolver.planLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(plan => {
//TODO //TODO
return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorEntityResolver.cloneLookupFields()) return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorEntityResolver.cloneLookupFields())
.pipe(tap(x => { .pipe(tap(x => {
@ -79,9 +79,9 @@ export class DescriptionEditorPermissionsResolver extends BaseEditorResolver {
description.id = null; description.id = null;
description.hash = null; description.hash = null;
description.status = DescriptionStatus.Draft; description.status = DescriptionStatus.Draft;
description.plan = dmp; description.plan = plan;
description.planDescriptionTemplate = { description.planDescriptionTemplate = {
id: dmp.planDescriptionTemplates.filter(x => x.sectionId == Guid.parse(planSectionId) && x.descriptionTemplateGroupId == description.descriptionTemplate.groupId)[0].id, id: plan.planDescriptionTemplates.filter(x => x.sectionId == Guid.parse(planSectionId) && x.descriptionTemplateGroupId == description.descriptionTemplate.groupId)[0].id,
sectionId: Guid.parse(planSectionId) sectionId: Guid.parse(planSectionId)
} }
return description; return description;

View File

@ -16,7 +16,7 @@
padding-bottom: 2em; padding-bottom: 2em;
} }
.explore-dmp-content { .explore-plan-content {
padding: 30px 15px; padding: 30px 15px;
} }

View File

@ -54,7 +54,7 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
planId: string; planId: string;
status: Number; status: Number;
totalCount: number; totalCount: number;
dmpSearchEnabled = true; plansearchEnabled = true;
listingItems: any[] = []; listingItems: any[] = [];
hasLoadedListingItems: boolean = false; hasLoadedListingItems: boolean = false;
isPublic: boolean = false; isPublic: boolean = false;
@ -207,7 +207,7 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
protected setupColumns() { } protected setupColumns() { }
public dashboardTour: GuidedTour = { public dashboardTour: GuidedTour = {
tourId: 'dmp-description-tour', tourId: 'plan-description-tour',
useOrb: true, useOrb: true,
steps: [ steps: [
{ {
@ -290,12 +290,12 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
} }
public restartTour(): void { public restartTour(): void {
this.setDashboardTourDmpText(); this.setDashboardTourPlanText();
this.setDashboardTourDescriptionText(); this.setDashboardTourDescriptionText();
this.guidedTourService.startTour(this.dashboardTour); this.guidedTourService.startTour(this.dashboardTour);
} }
public setDashboardTourDmpText(): void { public setDashboardTourPlanText(): void {
this.planText = this.language.instant('PLAN-LISTING.TEXT-INFO') + '\n\n' + this.planText = this.language.instant('PLAN-LISTING.TEXT-INFO') + '\n\n' +
this.language.instant('PLAN-LISTING.TEXT-INFO-QUESTION') + ' ' + this.language.instant('PLAN-LISTING.TEXT-INFO-QUESTION') + ' ' +
this.language.instant('PLAN-LISTING.LINK-ZENODO') + ' ' + this.language.instant('PLAN-LISTING.LINK-ZENODO') + ' ' +
@ -391,13 +391,13 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
lookup.descriptionTemplateSubQuery.ids = descriptionTemplates; lookup.descriptionTemplateSubQuery.ids = descriptionTemplates;
} else lookup.descriptionTemplateSubQuery = null; } else lookup.descriptionTemplateSubQuery = null;
// Dmps // Plans
let dmps = formGroup.get("associatedDmpIds")?.value ?? null; let addDmps = dmps && dmps?.length > 0; let plans = formGroup.get("associatedPlanIds")?.value ?? null; let addPlans = plans && plans?.length > 0;
let roles = formGroup.get("role")?.value !== null ? [formGroup.get("role")?.value] : null; let addRoles = roles && roles?.length > 0; let roles = formGroup.get("role")?.value !== null ? [formGroup.get("role")?.value] : null; let addRoles = roles && roles?.length > 0;
if (addDmps || addRoles) { if (addPlans || addRoles) {
lookup.planSubQuery = DescriptionFilterService.initializePlanLookup(); lookup.planSubQuery = DescriptionFilterService.initializePlanLookup();
if (addDmps) lookup.planSubQuery.ids = dmps?.length > 0 ? dmps : null; if (addPlans) lookup.planSubQuery.ids = plans?.length > 0 ? plans : null;
if (addRoles) { if (addRoles) {
lookup.planSubQuery.planUserSubQuery = DescriptionFilterService.initializePlanUserLookup(); lookup.planSubQuery.planUserSubQuery = DescriptionFilterService.initializePlanUserLookup();
@ -434,7 +434,7 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
status: [lookup.statuses?.length > 0 ? lookup.statuses[0] : null], status: [lookup.statuses?.length > 0 ? lookup.statuses[0] : null],
role: lookup.planSubQuery?.planUserSubQuery?.userRoles ? lookup.planSubQuery?.planUserSubQuery?.userRoles[0] : [], role: lookup.planSubQuery?.planUserSubQuery?.userRoles ? lookup.planSubQuery?.planUserSubQuery?.userRoles[0] : [],
descriptionTemplates: lookup.descriptionTemplateSubQuery?.ids ? [lookup.descriptionTemplateSubQuery?.ids] : [], descriptionTemplates: lookup.descriptionTemplateSubQuery?.ids ? [lookup.descriptionTemplateSubQuery?.ids] : [],
associatedDmpIds: lookup.planSubQuery?.ids ? [lookup.planSubQuery?.ids] : [], associatedPlanIds: lookup.planSubQuery?.ids ? [lookup.planSubQuery?.ids] : [],
tags: lookup.descriptionTagSubQuery?.tagIds ? [lookup.descriptionTagSubQuery?.tagIds] : [], tags: lookup.descriptionTagSubQuery?.tagIds ? [lookup.descriptionTagSubQuery?.tagIds] : [],
}); });
} }

View File

@ -13,7 +13,7 @@ const routes: Routes = [
}, },
}, },
{ {
path: 'dmp/:planId', path: 'plan/:planId',
component: DescriptionListingComponent, component: DescriptionListingComponent,
canActivate: [AuthGuard], canActivate: [AuthGuard],
data: { data: {

View File

@ -1,5 +1,5 @@
<div class="dmp-criteria"> <div class="plan-criteria">
<div class="filters container-fluid"> <div class="filters container-fluid">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-10"> <div class="col-10">
@ -32,16 +32,16 @@
</div> </div>
<!-- End of Related Dataset Templates Filters --> <!-- End of Related Dataset Templates Filters -->
<!-- Related DMP Filters --> <!-- Related Plan Filters -->
<div class="col-10"> <div class="col-10">
<h6 class="category-title">{{'DESCRIPTION-LISTING.FILTERS.ASSOCIATED-PLANS.NAME' | translate}}</h6> <h6 class="category-title">{{'DESCRIPTION-LISTING.FILTERS.ASSOCIATED-PLANS.NAME' | translate}}</h6>
<mat-form-field class="w-100"> <mat-form-field class="w-100">
<mat-label>{{'DESCRIPTION-LISTING.FILTERS.ASSOCIATED-PLANS.PLACEHOLDER' | translate }}</mat-label> <mat-label>{{'DESCRIPTION-LISTING.FILTERS.ASSOCIATED-PLANS.PLACEHOLDER' | translate }}</mat-label>
<app-multiple-auto-complete [formControl]="formGroup.get('associatedDmpIds')" [configuration]="dmpAutoCompleteConfiguration"></app-multiple-auto-complete> <app-multiple-auto-complete [formControl]="formGroup.get('associatedPlanIds')" [configuration]="planAutoCompleteConfiguration"></app-multiple-auto-complete>
</mat-form-field> </mat-form-field>
<hr> <hr>
</div> </div>
<!-- End of Related DMP Filters --> <!-- End of Related Plan Filters -->
<!-- All Versions Filter--> <!-- All Versions Filter-->
<!-- TODO --> <!-- TODO -->
@ -57,10 +57,10 @@
<h6 class="category-title">{{'DESCRIPTION-LISTING.FILTERS.ROLE.NAME' | translate }}</h6> <h6 class="category-title">{{'DESCRIPTION-LISTING.FILTERS.ROLE.NAME' | translate }}</h6>
<mat-radio-group aria-label="Select an option" [formControl]="formGroup.get('role')" class="row"> <mat-radio-group aria-label="Select an option" [formControl]="formGroup.get('role')" class="row">
<mat-radio-button [value]="null" [checked]="formGroup.get('role').value == null" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.ANY' | translate }}</mat-radio-button> <mat-radio-button [value]="null" [checked]="formGroup.get('role').value == null" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.ANY' | translate }}</mat-radio-button>
<mat-radio-button [value]="dmpRole.Owner" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.OWNER' | translate }}</mat-radio-button> <mat-radio-button [value]="planRole.Owner" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.OWNER' | translate }}</mat-radio-button>
<mat-radio-button [value]="dmpRole.Viewer" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.VIEWER' | translate }}</mat-radio-button> <mat-radio-button [value]="planRole.Viewer" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.VIEWER' | translate }}</mat-radio-button>
<mat-radio-button [value]="dmpRole.DescriptionContributor" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.DESCRIPTION-CONTRIBUTOR' | translate }}</mat-radio-button> <mat-radio-button [value]="planRole.DescriptionContributor" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.DESCRIPTION-CONTRIBUTOR' | translate }}</mat-radio-button>
<mat-radio-button [value]="dmpRole.Reviewer" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.REVIEWER' | translate }}</mat-radio-button> <mat-radio-button [value]="planRole.Reviewer" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.REVIEWER' | translate }}</mat-radio-button>
</mat-radio-group> </mat-radio-group>
<hr> <hr>
</div> </div>

View File

@ -41,11 +41,11 @@ export class DescriptionFilterComponent extends BaseCriteriaComponent implements
public filteringTagsAsync = false; public filteringTagsAsync = false;
statuses = DescriptionStatus; statuses = DescriptionStatus;
dmpRole = PlanUserRole; planRole = PlanUserRole;
options: UntypedFormGroup; options: UntypedFormGroup;
descriptionTemplateAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; descriptionTemplateAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
dmpAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; planAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
tagAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; tagAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
referenceTypeAutocompleteConfiguration: SingleAutoCompleteConfiguration; referenceTypeAutocompleteConfiguration: SingleAutoCompleteConfiguration;
referenceAutocompleteConfiguration: Map<string, MultipleAutoCompleteConfiguration>; referenceAutocompleteConfiguration: Map<string, MultipleAutoCompleteConfiguration>;
@ -71,7 +71,7 @@ export class DescriptionFilterComponent extends BaseCriteriaComponent implements
if (changes['filterFormGroup']) { if (changes['filterFormGroup']) {
this.descriptionTemplateAutoCompleteConfiguration = this.descriptionTemplateService.buildMultipleAutocompleteConfiguration(); this.descriptionTemplateAutoCompleteConfiguration = this.descriptionTemplateService.buildMultipleAutocompleteConfiguration();
this.dmpAutoCompleteConfiguration = this.planService.multipleAutocompleteConfiguration; this.planAutoCompleteConfiguration = this.planService.multipleAutocompleteConfiguration;
this.tagAutoCompleteConfiguration = this.tagService.multipleAutocompleteConfiguration; this.tagAutoCompleteConfiguration = this.tagService.multipleAutocompleteConfiguration;
this.referenceTypeAutocompleteConfiguration = this.getReferenceTypeAutocompleteConfiguration(); this.referenceTypeAutocompleteConfiguration = this.getReferenceTypeAutocompleteConfiguration();
this.referenceAutocompleteConfiguration = new Map<string, MultipleAutoCompleteConfiguration>(); this.referenceAutocompleteConfiguration = new Map<string, MultipleAutoCompleteConfiguration>();

View File

@ -8,8 +8,8 @@
<div *ngIf="description.status === descriptionStatusEnum.Finalized" class="col-auto description-title">{{description.label}}</div> <div *ngIf="description.status === descriptionStatusEnum.Finalized" class="col-auto description-title">{{description.label}}</div>
<div *ngIf="description.status === descriptionStatusEnum.Draft" class="col-auto description-title-draft">{{description.label}}</div> <div *ngIf="description.status === descriptionStatusEnum.Draft" class="col-auto description-title-draft">{{description.label}}</div>
<div class="description-subtitle"> <div class="description-subtitle">
<span *ngIf="isUserDMPRelated()" class="col-auto">{{ enumUtils.toPlanUserRolesString(planService.getCurrentUserRolesInPlan(description?.plan?.planUsers)) }}</span> <span *ngIf="isUserPlanRelated()" class="col-auto">{{ enumUtils.toPlanUserRolesString(planService.getCurrentUserRolesInPlan(description?.plan?.planUsers)) }}</span>
<span *ngIf="isUserDMPRelated()">.</span> <span *ngIf="isUserPlanRelated()">.</span>
<span class="col-auto" *ngIf="description.status === descriptionStatusEnum.Finalized && description.plan.accessType === planAccessTypeEnum.Public"><span class="material-icons icon-align">public</span>{{'DESCRIPTION-LISTING.STATES.PUBLIC' | translate}}</span> <span class="col-auto" *ngIf="description.status === descriptionStatusEnum.Finalized && description.plan.accessType === planAccessTypeEnum.Public"><span class="material-icons icon-align">public</span>{{'DESCRIPTION-LISTING.STATES.PUBLIC' | translate}}</span>
<span *ngIf="description.status === descriptionStatusEnum.Finalized && description.plan.accessType != planAccessTypeEnum.Public" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toDescriptionStatusString(description.status) }}</span> <span *ngIf="description.status === descriptionStatusEnum.Finalized && description.plan.accessType != planAccessTypeEnum.Public" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toDescriptionStatusString(description.status) }}</span>
<span *ngIf="description.status === descriptionStatusEnum.Draft" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toDescriptionStatusString(description.status) }}</span> <span *ngIf="description.status === descriptionStatusEnum.Draft" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toDescriptionStatusString(description.status) }}</span>
@ -18,19 +18,19 @@
</div> </div>
<div class="d-flex flex-direction-row pt-3 pb-3"> <div class="d-flex flex-direction-row pt-3 pb-3">
<div class="col-auto description-subtitle pr-0">{{'DESCRIPTION-LISTING.PART-OF' | translate}} <div class="col-auto description-subtitle pr-0">{{'DESCRIPTION-LISTING.PART-OF' | translate}}
<div class="col-auto dmp-label ml-3">{{'DESCRIPTION-LISTING.PLAN' | translate}}</div> <div class="col-auto plan-label ml-3">{{'DESCRIPTION-LISTING.PLAN' | translate}}</div>
</div> </div>
<div class="col dmp-title">{{description.plan?.label}}</div> <div class="col plan-title">{{description.plan?.label}}</div>
</div> </div>
</a> </a>
<div class="description-card-actions"> <div class="description-card-actions">
<a class="col-auto border-right pointer" *ngIf="fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Description) && fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Description).length > 0" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DESCRIPTION-LISTING.ACTIONS.EXPORT' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Description) && fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Description).length > 0" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DESCRIPTION-LISTING.ACTIONS.EXPORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="canInvitePlanUsers" (click)="openShareDialog()"><span class="material-icons icon-align pr-2">group_add</span>{{'DESCRIPTION-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="canInvitePlanUsers" (click)="openShareDialog()"><span class="material-icons icon-align pr-2">group_add</span>{{'DESCRIPTION-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="copyToDmp(description)"><span class="material-icons icon-align pr-2">file_copy</span>{{'DESCRIPTION-LISTING.ACTIONS.COPY-DESCRIPTION' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="copyToPlan(description)"><span class="material-icons icon-align pr-2">file_copy</span>{{'DESCRIPTION-LISTING.ACTIONS.COPY-DESCRIPTION' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="canDelete" (click)="deleteClicked(description.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'DESCRIPTION-LISTING.ACTIONS.DELETE' | translate }}</a> <a class="col-auto border-right pointer" *ngIf="canDelete" (click)="deleteClicked(description.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'DESCRIPTION-LISTING.ACTIONS.DELETE' | translate }}</a>
</div> </div>
<mat-menu #actionsMenu="matMenu"> <mat-menu #actionsMenu="matMenu">
<button *ngIf="isAuthenticated()" mat-menu-item (click)="copyToDmp(description)" class="menu-item"> <button *ngIf="isAuthenticated()" mat-menu-item (click)="copyToPlan(description)" class="menu-item">
<mat-icon>file_copy</mat-icon>{{'DESCRIPTION-LISTING.ACTIONS.COPY-DESCRIPTION' | translate}} <mat-icon>file_copy</mat-icon>{{'DESCRIPTION-LISTING.ACTIONS.COPY-DESCRIPTION' | translate}}
</button> </button>
<button *ngIf="canDelete" mat-menu-item (click)="deleteClicked(description.id)" class="menu-item"> <button *ngIf="canDelete" mat-menu-item (click)="deleteClicked(description.id)" class="menu-item">

View File

@ -77,7 +77,7 @@ p {
color: #08bd63; color: #08bd63;
} }
.dmp-card, .plan-card,
.description-card { .description-card {
min-width: 712px; min-width: 712px;
/* min-height: 308px; */ /* min-height: 308px; */
@ -112,7 +112,7 @@ input[type="text"] {
opacity: 0.6; opacity: 0.6;
} }
.dmp-label { .plan-label {
background: var(--primary-color) 0% 0% no-repeat padding-box; background: var(--primary-color) 0% 0% no-repeat padding-box;
border-radius: 4px 0px; border-radius: 4px 0px;
opacity: 1; opacity: 1;
@ -135,7 +135,7 @@ input[type="text"] {
color: #212121; color: #212121;
} }
.dmp-title, .plan-title,
.description-title { .description-title {
text-align: left; text-align: left;
font-weight: 600; font-weight: 600;
@ -174,7 +174,7 @@ input[type="text"] {
// padding-bottom: 0.4rem; // padding-bottom: 0.4rem;
} }
.dmp-subtitle, .plan-subtitle,
.description-subtitle { .description-subtitle {
.icon-align { .icon-align {
@ -186,7 +186,7 @@ input[type="text"] {
} }
.description-card-actions, .description-card-actions,
.dmp-card-actions { .plan-card-actions {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
border-top: 1px solid #dbdbdb; border-top: 1px solid #dbdbdb;
@ -195,24 +195,24 @@ input[type="text"] {
} }
.description-card-actions a, .description-card-actions a,
.dmp-card-actions a { .plan-card-actions a {
color: #848484 !important; color: #848484 !important;
text-decoration: none !important; text-decoration: none !important;
} }
.description-card-actions a:hover, .description-card-actions a:hover,
.dmp-card-actions a:hover { .plan-card-actions a:hover {
color: var(--primary-color) !important; color: var(--primary-color) !important;
} }
.dmp-description-descriptions-title { .plan-description-descriptions-title {
color: #000000; color: #000000;
opacity: 0.6; opacity: 0.6;
padding-top: 1.5rem; padding-top: 1.5rem;
padding-bottom: 0.8rem; padding-bottom: 0.8rem;
} }
.dmp-description-descriptions-name { .plan-description-descriptions-name {
color: #000000; color: #000000;
opacity: 0.6; opacity: 0.6;
font-weight: 700; font-weight: 700;

View File

@ -109,7 +109,7 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
} }
} }
isUserDMPRelated() { isUserPlanRelated() {
const principalId: Guid = this.authService.userId(); const principalId: Guid = this.authService.userId();
return this.description.plan.planUsers?.some(x => (x.user.id === principalId)); return this.description.plan.planUsers?.some(x => (x.user.id === principalId));
} }
@ -122,7 +122,7 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
return this.isPublic ? this.routerUtils.generateUrl(['/explore-descriptions/overview/public/', this.description.id.toString()]) : this.routerUtils.generateUrl(['/descriptions/overview/', this.description.id.toString()]); return this.isPublic ? this.routerUtils.generateUrl(['/explore-descriptions/overview/public/', this.description.id.toString()]) : this.routerUtils.generateUrl(['/descriptions/overview/', this.description.id.toString()]);
} }
getDmpLink(): string[] { getPlanLink(): string[] {
return this.isPublic ? [`/explore-plans/overview/public/${this.description.plan.id}`] : [`/plans/edit/${this.description.plan.id}`]; return this.isPublic ? [`/explore-plans/overview/public/${this.description.plan.id}`] : [`/plans/edit/${this.description.plan.id}`];
} }
@ -135,13 +135,13 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
restoreFocus: false, restoreFocus: false,
data: { data: {
planId: this.description.plan.id, planId: this.description.plan.id,
dmpName: this.description.plan.label, planName: this.description.plan.label,
blueprint: this.description.plan.blueprint blueprint: this.description.plan.blueprint
} }
}); });
} }
copyToDmp(description: Description) { copyToPlan(description: Description) {
const formGroup = this.fb.group({ const formGroup = this.fb.group({
planId: this.fb.control(null, Validators.required), planId: this.fb.control(null, Validators.required),
sectionId: this.fb.control(null, Validators.required), sectionId: this.fb.control(null, Validators.required),

View File

@ -57,7 +57,7 @@
</div> </div>
</ng-template> </ng-template>
<div *ngIf="canEdit" class="col-auto pr-0"> <div *ngIf="canEdit" class="col-auto pr-0">
<button (click)="openCopyToDmpDialog()" mat-mini-fab class="mr-3 actions-btn" matTooltip="{{'DESCRIPTION-OVERVIEW.ACTIONS.CLONE' | translate}}" matTooltipPosition="above"> <button (click)="openCopyToPlanDialog()" mat-mini-fab class="mr-3 actions-btn" matTooltip="{{'DESCRIPTION-OVERVIEW.ACTIONS.CLONE' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-mini-fab-icon">content_copy</mat-icon> <mat-icon class="mat-mini-fab-icon">content_copy</mat-icon>
</button> </button>
</div> </div>
@ -72,8 +72,8 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col-12 col-lg-7"> <div class="col-12 col-lg-7">
<button class="w-100 dmp-btn p-1" (click)="dmpClicked(description.plan)"> <button class="w-100 plan-btn p-1" (click)="planClicked(description.plan)">
<div class="dmp-btn-label"> <div class="plan-btn-label">
{{ this.description.plan.label }} {{ this.description.plan.label }}
</div> </div>
<div class="w-auto"> <div class="w-auto">
@ -213,7 +213,7 @@
</p> </p>
</div> </div>
<div class="col-auto" *ngIf="canInvitePlanUsers && description.plan?.status === planStatusEnum.Draft && planUser.role != planUserRoleEnum.Owner"> <div class="col-auto" *ngIf="canInvitePlanUsers && description.plan?.status === planStatusEnum.Draft && planUser.role != planUserRoleEnum.Owner">
<button (click)="removeUserFromDmp(planUser)" mat-mini-fab matTooltip="{{ 'DESCRIPTION-OVERVIEW.ACTIONS.REMOVE-AUTHOR' | translate}}" matTooltipPosition="above"> <button (click)="removeUserFromPlan(planUser)" mat-mini-fab matTooltip="{{ 'DESCRIPTION-OVERVIEW.ACTIONS.REMOVE-AUTHOR' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-mini-fab-icon">delete</mat-icon> <mat-icon class="mat-mini-fab-icon">delete</mat-icon>
</button> </button>
</div> </div>

View File

@ -59,7 +59,7 @@
align-self: center; align-self: center;
} }
.dmp-btn { .plan-btn {
width: 35em; width: 35em;
min-height: 2.3em; min-height: 2.3em;
background-color: var(--primary-color); background-color: var(--primary-color);
@ -69,8 +69,8 @@
border: none; border: none;
} }
.dmp-btn, .plan-btn,
.dmp-btn > mat-icon { .plan-btn > mat-icon {
color: #ffffff; color: #ffffff;
// opacity: 0.8; // opacity: 0.8;
} }
@ -185,7 +185,7 @@
margin-bottom: 1.875em; margin-bottom: 1.875em;
} }
.dmp-btn-label { .plan-btn-label {
margin-right: 1em; margin-right: 1em;
color: #ffffff; color: #ffffff;
opacity: 0.8; opacity: 0.8;
@ -294,7 +294,7 @@
} }
.description-label, .description-label,
.dmp-btn, .plan-btn,
.doi-panel, .doi-panel,
.researcher { .researcher {
display: flex; display: flex;

View File

@ -248,16 +248,16 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
} else return false; } else return false;
} }
focusOnAuthor(dmpUserId: Guid, order: number): void { focusOnAuthor(planUserId: Guid, order: number): void {
this.authorFocus = `${dmpUserId}-${order}`; this.authorFocus = `${planUserId}-${order}`;
} }
resetAuthorFocus(): void { resetAuthorFocus(): void {
this.authorFocus = null; this.authorFocus = null;
} }
isFocusedOnUser(dmpUserId: Guid, order: number): boolean { isFocusedOnUser(planUserId: Guid, order: number): boolean {
return `${dmpUserId}-${order}` == this.authorFocus; return `${planUserId}-${order}` == this.authorFocus;
} }
openShareDialog() { openShareDialog() {
@ -266,7 +266,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
restoreFocus: false, restoreFocus: false,
data: { data: {
planId: this.description.plan.id, planId: this.description.plan.id,
dmpName: this.description.plan.label, planName: this.description.plan.label,
blueprint: this.description.plan.blueprint blueprint: this.description.plan.blueprint
} }
}); });
@ -308,11 +308,11 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
}); });
} }
dmpClicked(dmp: Plan) { planClicked(plan: Plan) {
if (this.isPublicView) { if (this.isPublicView) {
this.router.navigate([this.routerUtils.generateUrl(['/explore-plans/overview/public/', dmp.id.toString()])]); this.router.navigate([this.routerUtils.generateUrl(['/explore-plans/overview/public/', plan.id.toString()])]);
} else { } else {
this.router.navigate([this.routerUtils.generateUrl(['/plans/overview/', dmp.id.toString()])]); this.router.navigate([this.routerUtils.generateUrl(['/plans/overview/', plan.id.toString()])]);
} }
} }
@ -360,7 +360,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
return sections == null ? '' : sections[0].label; return sections == null ? '' : sections[0].label;
} }
openCopyToDmpDialog() { openCopyToPlanDialog() {
const formGroup = this.fb.group({ const formGroup = this.fb.group({
planId: this.fb.control(null, Validators.required), planId: this.fb.control(null, Validators.required),
sectionId: this.fb.control(null, Validators.required), sectionId: this.fb.control(null, Validators.required),
@ -387,7 +387,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
}); });
} }
removeUserFromDmp(dmpUser: PlanUser) { removeUserFromPlan(planUser: PlanUser) {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, { const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
data: { data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-USER'), message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-USER'),
@ -398,12 +398,12 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
}); });
dialogRef.afterClosed().subscribe(result => { dialogRef.afterClosed().subscribe(result => {
if (result) { if (result) {
const dmpUserRemovePersist: PlanUserRemovePersist = { const planUserRemovePersist: PlanUserRemovePersist = {
id: dmpUser.id, id: planUser.id,
planId: this.description.plan.id, planId: this.description.plan.id,
role: dmpUser.role role: planUser.role
}; };
this.planService.removeUser(dmpUserRemovePersist).pipe(takeUntil(this._destroyed)) this.planService.removeUser(planUserRemovePersist).pipe(takeUntil(this._destroyed))
.subscribe(data => { .subscribe(data => {
this.reloadPage(); this.reloadPage();
}, (error: any) => this.httpErrorHandlingService.handleBackedRequestError(error)); }, (error: any) => this.httpErrorHandlingService.handleBackedRequestError(error));
@ -465,12 +465,12 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
}); });
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) { if (result) {
const dmpUserRemovePersist: DescriptionStatusPersist = { const planUserRemovePersist: DescriptionStatusPersist = {
id: description.id, id: description.id,
status: DescriptionStatus.Draft, status: DescriptionStatus.Draft,
hash: description.hash hash: description.hash
}; };
this.descriptionService.persistStatus(dmpUserRemovePersist).pipe(takeUntil(this._destroyed)) this.descriptionService.persistStatus(planUserRemovePersist).pipe(takeUntil(this._destroyed))
.subscribe(data => { .subscribe(data => {
this.reloadPage(); this.reloadPage();
this.onUpdateCallbackSuccess() this.onUpdateCallbackSuccess()

View File

@ -16,7 +16,7 @@
</div> </div>
<div class="row mt-2"> <div class="row mt-2">
<div class="col-auto pb-4"> <div class="col-auto pb-4">
<span>{{'DASHBOARD.ADD-NEW-DESCRIPTION.OPTIONS-NOT-ENOUGH' | translate}}</span>&nbsp;<span class="new-dmp" (click)="startNewPlan()">{{'DASHBOARD.ADD-NEW-DESCRIPTION.START-NEW-PLAN' | translate}}</span> <span>{{'DASHBOARD.ADD-NEW-DESCRIPTION.OPTIONS-NOT-ENOUGH' | translate}}</span>&nbsp;<span class="new-plan" (click)="startNewPlan()">{{'DASHBOARD.ADD-NEW-DESCRIPTION.START-NEW-PLAN' | translate}}</span>
</div> </div>
</div> </div>
<div class="row"> <div class="row">

View File

@ -92,7 +92,7 @@ min-width: 101px;
flex-direction: row; flex-direction: row;
} }
.new-dmp { .new-plan {
text-align: left; text-align: left;
text-decoration: underline; text-decoration: underline;
letter-spacing: 0px; letter-spacing: 0px;
@ -100,11 +100,11 @@ min-width: 101px;
cursor: pointer; cursor: pointer;
} }
::ng-deep .dmp-form .mat-form-field-appearance-outline .mat-form-field-outline { ::ng-deep .plan-form .mat-form-field-appearance-outline .mat-form-field-outline {
// background: #fafafa !important; // background: #fafafa !important;
} }
::ng-deep .dmp-form .mat-form-field-appearance-outline .mat-form-field-infix { ::ng-deep .plan-form .mat-form-field-appearance-outline .mat-form-field-infix {
// font-size: 1rem; // font-size: 1rem;
// padding: 0.6em 0 1em 0 !important; // padding: 0.6em 0 1em 0 !important;
} }

View File

@ -20,7 +20,7 @@
<div class="collapse navbar-collapse justify-content-end" id="navigation"> <div class="collapse navbar-collapse justify-content-end" id="navigation">
<div class="new-dmp-dialog col-md-auto ml-auto"> <div class="new-plan-dialog col-md-auto ml-auto">
<button type="button" class="normal-btn" (click)="openNewPlanDialog()">{{ 'NAV-BAR.START-NEW-PLAN' | translate }}</button> <button type="button" class="normal-btn" (click)="openNewPlanDialog()">{{ 'NAV-BAR.START-NEW-PLAN' | translate }}</button>
</div> </div>
<div class="col-md-auto pl-0" *ngIf="!(isAuthenticated() && onInvalidUrl())"> <div class="col-md-auto pl-0" *ngIf="!(isAuthenticated() && onInvalidUrl())">

View File

@ -146,7 +146,7 @@ $mat-card-header-size: 40px !default;
border-radius: 6px; border-radius: 6px;
} }
.new-dmp-dialog { .new-plan-dialog {
padding: 0em .5em 0em 0em; padding: 0em .5em 0em 0em;
} }
::ng-deep .mat-option-text { ::ng-deep .mat-option-text {

View File

@ -5,7 +5,7 @@
<mat-divider class="top-divider"></mat-divider> <mat-divider class="top-divider"></mat-divider>
<div class="profile-settings"> <div class="profile-settings">
<a mat-button class="profile mt-2 w-100 ml-0 pl-1 d-inline-block" (click)="navigateToProfile()">{{'USER-DIALOG.USER-PROFILE-SETTINGS' | translate}}</a> <a mat-button class="profile mt-2 w-100 ml-0 pl-1 d-inline-block" (click)="navigateToProfile()">{{'USER-DIALOG.USER-PROFILE-SETTINGS' | translate}}</a>
<a mat-button class="profile mb-2 w-100 ml-0 pl-1 d-inline-block" (click)="navigateToMyDmps()">{{'USER-PROFILE.ASSOCIATED-PLANS' | translate}}</a> <a mat-button class="profile mb-2 w-100 ml-0 pl-1 d-inline-block" (click)="navigateToMyPlans()">{{'USER-PROFILE.ASSOCIATED-PLANS' | translate}}</a>
</div> </div>
<mat-divider></mat-divider> <mat-divider></mat-divider>
<div> <div>

View File

@ -68,7 +68,7 @@ export class UserDialogComponent implements OnInit, OnDestroy {
this.router.navigate([this.routerUtils.generateUrl('/profile')]); this.router.navigate([this.routerUtils.generateUrl('/profile')]);
} }
public navigateToMyDmps() { public navigateToMyPlans() {
this.dialogRef.close(); this.dialogRef.close();
this.router.navigate([this.routerUtils.generateUrl('/plans')]); this.router.navigate([this.routerUtils.generateUrl('/plans')]);
} }

View File

@ -40,7 +40,7 @@
<mat-checkbox [checked]="allDescriptionsCompleted" [indeterminate]="someDescriptionsCompleted" (change)="toggleAllDescriptions($event.checked)">{{ 'PLAN-CLONE-DIALOG.ACTIONS.TOGGLE-DESCRIPTIONS' | translate }}</mat-checkbox> <mat-checkbox [checked]="allDescriptionsCompleted" [indeterminate]="someDescriptionsCompleted" (change)="toggleAllDescriptions($event.checked)">{{ 'PLAN-CLONE-DIALOG.ACTIONS.TOGGLE-DESCRIPTIONS' | translate }}</mat-checkbox>
</mat-card-header> </mat-card-header>
<mat-selection-list #selectedItems [formControl]="formGroup.get('descriptions')"> <mat-selection-list #selectedItems [formControl]="formGroup.get('descriptions')">
<mat-list-option *ngFor="let description of dmp.descriptions;" [value]="description.id"> <mat-list-option *ngFor="let description of plan.descriptions;" [value]="description.id">
<span class="text-truncate" [matTooltip]="description.label">{{description.label}}</span> <span class="text-truncate" [matTooltip]="description.label">{{description.label}}</span>
</mat-list-option> </mat-list-option>
</mat-selection-list> </mat-selection-list>

View File

@ -19,7 +19,7 @@ import { HttpErrorResponse } from '@angular/common/http';
}) })
export class ClonePlanDialogComponent extends BaseComponent { export class ClonePlanDialogComponent extends BaseComponent {
dmp: Plan; plan: Plan;
editorModel: PlanCloneDialogEditorModel; editorModel: PlanCloneDialogEditorModel;
formGroup: UntypedFormGroup; formGroup: UntypedFormGroup;
@ -32,12 +32,12 @@ export class ClonePlanDialogComponent extends BaseComponent {
@Inject(MAT_DIALOG_DATA) public data: any @Inject(MAT_DIALOG_DATA) public data: any
) { ) {
super(); super();
this.dmp = data.plan; this.plan = data.plan;
} }
get allDescriptionsNo(): number{ get allDescriptionsNo(): number{
return this.dmp.descriptions?.length ?? 0; return this.plan.descriptions?.length ?? 0;
} }
get checkedDescrionsNo(): number { get checkedDescrionsNo(): number {
@ -58,7 +58,7 @@ export class ClonePlanDialogComponent extends BaseComponent {
} }
hasDescriptions() { hasDescriptions() {
return this.dmp.descriptions?.length > 0; return this.plan.descriptions?.length > 0;
} }
close() { close() {
@ -73,14 +73,14 @@ export class ClonePlanDialogComponent extends BaseComponent {
if (!this.formGroup.valid) { return; } if (!this.formGroup.valid) { return; }
const value: ClonePlanPersist = this.formGroup.value; const value: ClonePlanPersist = this.formGroup.value;
this.planService.clone(value, PlanEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe( this.planService.clone(value, PlanEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
dmp => this.dialogRef.close(dmp), plan => this.dialogRef.close(plan),
error => this.onCallbackError(error) error => this.onCallbackError(error)
); );
} }
toggleAllDescriptions(event: any) { toggleAllDescriptions(event: any) {
if (event === true) { if (event === true) {
this.formGroup.get('descriptions')?.setValue(this.dmp.descriptions?.map(d=> d.id)); this.formGroup.get('descriptions')?.setValue(this.plan.descriptions?.map(d=> d.id));
} else { } else {
this.formGroup.get('descriptions')?.setValue([]); this.formGroup.get('descriptions')?.setValue([]);
} }

View File

@ -26,7 +26,7 @@ import { nameof } from 'ts-simple-nameof';
}) })
export class PlanDepositDropdown extends BaseComponent implements OnInit { export class PlanDepositDropdown extends BaseComponent implements OnInit {
@Input() inputRepos: DepositConfiguration[]; @Input() inputRepos: DepositConfiguration[];
@Input() dmp: Plan; @Input() plan: Plan;
outputRepos = []; outputRepos = [];
logos: Map<string, SafeResourceUrl> = new Map<string, SafeResourceUrl>(); logos: Map<string, SafeResourceUrl> = new Map<string, SafeResourceUrl>();
@Output() outputReposEmitter: EventEmitter<EntityDoi[]> = new EventEmitter<EntityDoi[]>(); @Output() outputReposEmitter: EventEmitter<EntityDoi[]> = new EventEmitter<EntityDoi[]>();
@ -49,8 +49,8 @@ export class PlanDepositDropdown extends BaseComponent implements OnInit {
} }
ngOnInit(): void { ngOnInit(): void {
for (var i = 0; i < this.dmp?.entityDois?.length; i++) { for (var i = 0; i < this.plan?.entityDois?.length; i++) {
this.inputRepos = this.inputRepos.filter(r => this.hasDoi(r, this.dmp.entityDois, i)); this.inputRepos = this.inputRepos.filter(r => this.hasDoi(r, this.plan.entityDois, i));
} }
this.inputRepos.forEach(repo => { this.inputRepos.forEach(repo => {
if (repo.hasLogo) { if (repo.hasLogo) {
@ -76,12 +76,12 @@ export class PlanDepositDropdown extends BaseComponent implements OnInit {
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
switch (result) { switch (result) {
case 0: case 0:
this.showOauth2Dialog(this.depositOauth2DialogService.getLoginUrl(repo), repo, this.dmp); this.showOauth2Dialog(this.depositOauth2DialogService.getLoginUrl(repo), repo, this.plan);
break; break;
case 1: case 1:
const depositRequest: DepositRequest = { const depositRequest: DepositRequest = {
repositoryId: repo.repositoryId, repositoryId: repo.repositoryId,
planId: this.dmp.id, planId: this.plan.id,
authorizationCode: null, authorizationCode: null,
project: this.EntityDoiFields() project: this.EntityDoiFields()
}; };
@ -99,7 +99,7 @@ export class PlanDepositDropdown extends BaseComponent implements OnInit {
} else if (repo.depositType == DepositConfigurationStatus.System) { } else if (repo.depositType == DepositConfigurationStatus.System) {
const depositRequest: DepositRequest = { const depositRequest: DepositRequest = {
repositoryId: repo.repositoryId, repositoryId: repo.repositoryId,
planId: this.dmp.id, planId: this.plan.id,
authorizationCode: null, authorizationCode: null,
project: this.EntityDoiFields() project: this.EntityDoiFields()
}; };
@ -121,14 +121,14 @@ export class PlanDepositDropdown extends BaseComponent implements OnInit {
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('PLAN-EDITOR.SNACK-BAR.UNSUCCESSFUL-DOI'), SnackBarNotificationLevel.Error); this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('PLAN-EDITOR.SNACK-BAR.UNSUCCESSFUL-DOI'), SnackBarNotificationLevel.Error);
} }
showOauth2Dialog(url: string, repo: DepositConfiguration, dmp: Plan) { showOauth2Dialog(url: string, repo: DepositConfiguration, plan: Plan) {
this.depositOauth2DialogService.login(url) this.depositOauth2DialogService.login(url)
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(code => { .subscribe(code => {
if (code !== undefined) { if (code !== undefined) {
const depositRequest: DepositRequest = { const depositRequest: DepositRequest = {
repositoryId: repo.repositoryId, repositoryId: repo.repositoryId,
planId: dmp.id, planId: plan.id,
authorizationCode: code, authorizationCode: code,
project: this.EntityDoiFields() project: this.EntityDoiFields()
}; };

View File

@ -1,18 +1,18 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { AuthService } from '@app/core/services/auth/auth.service'; import { AuthService } from '@app/core/services/auth/auth.service';
import { DmpInvitationService } from '@app/core/services/plan/dmp-invitation.service'; import { PlanInvitationService } from '@app/core/services/plan/plan-invitation.service';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
@Component({ @Component({
selector: 'app-dmp-invitation-accepted-component', selector: 'app-plan-invitation-accepted-component',
templateUrl: 'dmp-invitation-accepted.component.html', templateUrl: 'plan-invitation-accepted.component.html',
}) })
export class InvitationAcceptedComponent extends BaseComponent implements OnInit { export class InvitationAcceptedComponent extends BaseComponent implements OnInit {
constructor( constructor(
private dmpInvitationService: DmpInvitationService, private planInvitationService: PlanInvitationService,
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private authentication: AuthService, private authentication: AuthService,
@ -27,7 +27,7 @@ export class InvitationAcceptedComponent extends BaseComponent implements OnInit
const id = params['id']; const id = params['id'];
if(this.isAuthenticated()){ if(this.isAuthenticated()){
this.dmpInvitationService.exchange(id) this.planInvitationService.exchange(id)
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(result => { .subscribe(result => {
this.router.navigate(['plans/edit/' + result]); this.router.navigate(['plans/edit/' + result]);

View File

@ -1,4 +1,4 @@
<div class="dmp-invitation-dialog container-fluid" *ngIf="formGroup"> <div class="plan-invitation-dialog container-fluid" *ngIf="formGroup">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<h1 class="title">{{'PLAN-USER-INVITATION-DIALOG.TITLE' | translate}}</h1> <h1 class="title">{{'PLAN-USER-INVITATION-DIALOG.TITLE' | translate}}</h1>

View File

@ -1,4 +1,4 @@
.dmp-invitation-dialog { .plan-invitation-dialog {
padding: 2.5rem; padding: 2.5rem;
.form-container { .form-container {

View File

@ -1,4 +1,4 @@
<div class="dmp-criteria"> <div class="plan-criteria">
<div class="filters container-fluid"> <div class="filters container-fluid">
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col-10"> <div class="col-10">
@ -29,16 +29,16 @@
</div> </div>
<!-- End of Related Dataset Templates Filter --> <!-- End of Related Dataset Templates Filter -->
<!-- Dmp Blueprint Filter --> <!-- Plan Blueprint Filter -->
<div class="col-10"> <div class="col-10">
<h6 class="category-title">{{ 'PLAN-LISTING.FILTERS.ASSOCIATED-PLAN-BLUEPRINTS.NAME' | translate}}</h6> <h6 class="category-title">{{ 'PLAN-LISTING.FILTERS.ASSOCIATED-PLAN-BLUEPRINTS.NAME' | translate}}</h6>
<mat-form-field class="w-100"> <mat-form-field class="w-100">
<mat-label>{{ 'PLAN-LISTING.FILTERS.ASSOCIATED-PLAN-BLUEPRINTS.PLACEHOLDER' | translate }}</mat-label> <mat-label>{{ 'PLAN-LISTING.FILTERS.ASSOCIATED-PLAN-BLUEPRINTS.PLACEHOLDER' | translate }}</mat-label>
<app-multiple-auto-complete [formControl]="formGroup.get('dmpBlueprints')" [configuration]="dmpBlueprintAutoCompleteConfiguration"></app-multiple-auto-complete> <app-multiple-auto-complete [formControl]="formGroup.get('planBlueprints')" [configuration]="planBlueprintAutoCompleteConfiguration"></app-multiple-auto-complete>
</mat-form-field> </mat-form-field>
<hr> <hr>
</div> </div>
<!-- End of Dmp Blueprint Filter --> <!-- End of Plan Blueprint Filter -->
<!-- Role Filter --> <!-- Role Filter -->
<div *ngIf="isAuthenticated()" class="col-10"> <div *ngIf="isAuthenticated()" class="col-10">

View File

@ -1,4 +1,4 @@
.dmp-criteria { .plan-criteria {
mat-form-field { mat-form-field {
padding-bottom: 5px; padding-bottom: 5px;
width: 100%; width: 100%;

View File

@ -41,7 +41,7 @@ export class PlanFilterComponent extends BaseCriteriaComponent implements OnInit
maxFileSize: number = 1048576; maxFileSize: number = 1048576;
descriptionTemplateAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; descriptionTemplateAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
dmpBlueprintAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; planBlueprintAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
referenceTypeAutocompleteConfiguration: SingleAutoCompleteConfiguration; referenceTypeAutocompleteConfiguration: SingleAutoCompleteConfiguration;
referenceAutocompleteConfiguration: Map<string, MultipleAutoCompleteConfiguration>; referenceAutocompleteConfiguration: Map<string, MultipleAutoCompleteConfiguration>;
@ -65,7 +65,7 @@ export class PlanFilterComponent extends BaseCriteriaComponent implements OnInit
if (changes['filterFormGroup']) { if (changes['filterFormGroup']) {
this.descriptionTemplateAutoCompleteConfiguration = this.descriptionTemplateService.buildDescriptionTempalteGroupMultipleAutocompleteConfiguration(); this.descriptionTemplateAutoCompleteConfiguration = this.descriptionTemplateService.buildDescriptionTempalteGroupMultipleAutocompleteConfiguration();
this.dmpBlueprintAutoCompleteConfiguration = this.planBlueprintService.multipleAutocompleteConfiguration; this.planBlueprintAutoCompleteConfiguration = this.planBlueprintService.multipleAutocompleteConfiguration;
this.referenceTypeAutocompleteConfiguration = this.getReferenceTypeAutocompleteConfiguration(); this.referenceTypeAutocompleteConfiguration = this.getReferenceTypeAutocompleteConfiguration();
this.referenceAutocompleteConfiguration = new Map<string, MultipleAutoCompleteConfiguration>(); this.referenceAutocompleteConfiguration = new Map<string, MultipleAutoCompleteConfiguration>();

View File

@ -1,56 +1,56 @@
<div class="dmp-card"> <div class="plan-card">
<a [routerLink]="isPublic ? this.routerUtils.generateUrl(['/explore-plans/overview/public/', dmp.id]) : this.routerUtils.generateUrl(['/plans/overview/', dmp.id])" class="pointer"> <a [routerLink]="isPublic ? this.routerUtils.generateUrl(['/explore-plans/overview/public/', plan.id]) : this.routerUtils.generateUrl(['/plans/overview/', plan.id])" class="pointer">
<div class="d-flex flex-direction-row"> <div class="d-flex flex-direction-row">
<div class="col-auto dmp-label">{{ 'PLAN-LISTING.PLAN' | translate }}</div> <div class="col-auto plan-label">{{ 'PLAN-LISTING.PLAN' | translate }}</div>
<div *ngIf="!isPublic" class="col-auto ml-auto edited-date">{{ 'PLAN-LISTING.EDITED' | translate }}: {{ dmp.updatedAt | dateTimeFormatter: "d MMMM y" }}</div> <div *ngIf="!isPublic" class="col-auto ml-auto edited-date">{{ 'PLAN-LISTING.EDITED' | translate }}: {{ plan.updatedAt | dateTimeFormatter: "d MMMM y" }}</div>
<div *ngIf="isPublic" class="col-auto ml-auto edited-date">{{ 'PLAN-LISTING.PUBLISHED' | translate }}: {{ dmp.finalizedAt | dateTimeFormatter: "d MMMM y" }}</div> <div *ngIf="isPublic" class="col-auto ml-auto edited-date">{{ 'PLAN-LISTING.PUBLISHED' | translate }}: {{ plan.finalizedAt | dateTimeFormatter: "d MMMM y" }}</div>
</div> </div>
<div class="col-auto" [ngClass]="{'dmp-title': !isDraft, 'dmp-title-draft': isDraft}">{{dmp.label}}</div> <div class="col-auto" [ngClass]="{'plan-title': !isDraft, 'plan-title-draft': isDraft}">{{plan.label}}</div>
<div class="dmp-subtitle"> <div class="plan-subtitle">
<span *ngIf="isUserPlanRelated()" class="col-auto">{{ enumUtils.toPlanUserRolesString(planService.getCurrentUserRolesInPlan(dmp?.planUsers)) }}</span> <span *ngIf="isUserPlanRelated()" class="col-auto">{{ enumUtils.toPlanUserRolesString(planService.getCurrentUserRolesInPlan(plan?.planUsers)) }}</span>
<span *ngIf="isUserPlanRelated()">.</span> <span *ngIf="isUserPlanRelated()">.</span>
<span class="col-auto" *ngIf="dmp.status === planStatusEnum.Finalized && isPublic"><span class="material-icons icon-align">public</span>{{'TYPES.PLAN-VISIBILITY.PUBLIC' | translate}}</span> <span class="col-auto" *ngIf="plan.status === planStatusEnum.Finalized && isPublic"><span class="material-icons icon-align">public</span>{{'TYPES.PLAN-VISIBILITY.PUBLIC' | translate}}</span>
<span *ngIf="dmp.status === planStatusEnum.Finalized && !isPublic" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toPlanStatusString(dmp.status) }}</span> <span *ngIf="plan.status === planStatusEnum.Finalized && !isPublic" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toPlanStatusString(plan.status) }}</span>
<span *ngIf="dmp.status === planStatusEnum.Draft" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toPlanStatusString(dmp.status) }}</span> <span *ngIf="plan.status === planStatusEnum.Draft" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toPlanStatusString(plan.status) }}</span>
<span>.</span> <span>.</span>
<span class="col-auto">{{'PLAN-LISTING.VERSION' | translate}} {{dmp.version}}</span> <span class="col-auto">{{'PLAN-LISTING.VERSION' | translate}} {{plan.version}}</span>
<span>.</span> <span>.</span>
<span class="col">{{ 'PLAN-LISTING.GRANT' | translate }}: {{referenceService.getReferencesForTypesFirstSafe(dmp?.planReferences, [this.referenceTypeService.getGrantReferenceType()])?.reference?.label}}</span> <span class="col">{{ 'PLAN-LISTING.GRANT' | translate }}: {{referenceService.getReferencesForTypesFirstSafe(plan?.planReferences, [this.referenceTypeService.getGrantReferenceType()])?.reference?.label}}</span>
</div> </div>
<div class="col-auto dmp-description-descriptions-title">{{'PLAN-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ dmp.descriptions?.length }}) <div class="col-auto plan-description-descriptions-title">{{'PLAN-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ plan.descriptions?.length }})
</div> </div>
<div *ngFor="let description of dmp.descriptions; let i = index; let last = last" [ngClass]="{'pb-3': i === dmp.descriptions?.length - 1}"> <div *ngFor="let description of plan.descriptions; let i = index; let last = last" [ngClass]="{'pb-3': i === plan.descriptions?.length - 1}">
<div *ngIf="i < 3"> <div *ngIf="i < 3">
<div class="col-auto dmp-description-descriptions-name" *ngIf="!last && i !== 2">{{description.label}},</div> <div class="col-auto plan-description-descriptions-name" *ngIf="!last && i !== 2">{{description.label}},</div>
<div class="col-auto dmp-description-descriptions-name" *ngIf="last || i == 2">{{description.label}}</div> <div class="col-auto plan-description-descriptions-name" *ngIf="last || i == 2">{{description.label}}</div>
</div> </div>
</div> </div>
<a class="d-flex justify-content-center pb-3 show-more" *ngIf="dmp.descriptions?.length > 3" [routerLink]="isPublic ? this.routerUtils.generateUrl(['/explore-plans/overview/public/', dmp.id]) : this.routerUtils.generateUrl(['/plans/overview/', dmp.id])"><u>{{'GENERAL.ACTIONS.SHOW-MORE' | translate}}</u></a> <a class="d-flex justify-content-center pb-3 show-more" *ngIf="plan.descriptions?.length > 3" [routerLink]="isPublic ? this.routerUtils.generateUrl(['/explore-plans/overview/public/', plan.id]) : this.routerUtils.generateUrl(['/plans/overview/', plan.id])"><u>{{'GENERAL.ACTIONS.SHOW-MORE' | translate}}</u></a>
</a> </a>
<div class="dmp-card-actions"> <div class="plan-card-actions">
<a class="col-auto border-right pointer" *ngIf="canExportPlan(dmp) && fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Dmp).length > 0" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'PLAN-LISTING.ACTIONS.EXPORT' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="canExportPlan() && fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Plan).length > 0" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'PLAN-LISTING.ACTIONS.EXPORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isDraftDmp(dmp) && canEditPlan(dmp)" [routerLink]="this.routerUtils.generateUrl(['/plans/edit/', dmp.id])" target="_blank"><span class="material-icons icon-align">add</span>{{'PLAN-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="isDraftPlan(plan) && canEditPlan()" [routerLink]="this.routerUtils.generateUrl(['/plans/edit/', plan.id])" target="_blank"><span class="material-icons icon-align">add</span>{{'PLAN-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="canInvitePlanUsers(dmp)" (click)="inviteToDmp()"><span class="material-icons icon-align pr-2">group_add</span>{{'PLAN-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="canInvitePlanUsers()" (click)="inviteToPlan()"><span class="material-icons icon-align pr-2">group_add</span>{{'PLAN-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="canClonePlan(dmp)" (click)="cloneClicked()"><span class="material-icons icon-align pr-2">filter_none</span>{{'PLAN-LISTING.ACTIONS.CLONE' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="canClonePlan()" (click)="cloneClicked()"><span class="material-icons icon-align pr-2">filter_none</span>{{'PLAN-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="!isAuthenticated()" (click)="viewVersions(dmp)"><span class="material-icons icon-align pr-2">library_books</span>{{'PLAN-LISTING.ACTIONS.VIEW-VERSION' | translate}}</a> <a class="col-auto border-right pointer" *ngIf="!isAuthenticated()" (click)="viewVersions(plan)"><span class="material-icons icon-align pr-2">library_books</span>{{'PLAN-LISTING.ACTIONS.VIEW-VERSION' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isDraftDmp(dmp) && canDeletePlan(dmp)" (click)="deleteClicked(dmp.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'PLAN-LISTING.ACTIONS.DELETE' | translate }}</a> <a class="col-auto border-right pointer" *ngIf="isDraftPlan(plan) && canDeletePlan()" (click)="deleteClicked(plan.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'PLAN-LISTING.ACTIONS.DELETE' | translate }}</a>
<a class="col-auto pointer" *ngIf="isAuthenticated()" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a> <a class="col-auto pointer" *ngIf="isAuthenticated()" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a>
</div> </div>
<mat-menu #exportMenu="matMenu" xPosition="before"> <mat-menu #exportMenu="matMenu" xPosition="before">
<button mat-menu-item *ngFor='let fileTransformer of fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Dmp)' (click)="fileTransformerService.exportPlan(dmp.id, fileTransformer.repositoryId, fileTransformer.format)"> <button mat-menu-item *ngFor='let fileTransformer of fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Plan)' (click)="fileTransformerService.exportPlan(plan.id, fileTransformer.repositoryId, fileTransformer.format)">
<i class="fa pr-2" [ngClass]="fileTransformer.hasLogo ? fileTransformer.icon : 'fa-file-o'"></i> <i class="fa pr-2" [ngClass]="fileTransformer.hasLogo ? fileTransformer.icon : 'fa-file-o'"></i>
<span>{{'GENERAL.FILE-TRANSFORMER.' + fileTransformer.format.toUpperCase() | translate}}</span> <span>{{'GENERAL.FILE-TRANSFORMER.' + fileTransformer.format.toUpperCase() | translate}}</span>
</button> </button>
</mat-menu> </mat-menu>
<mat-menu #actionsMenu="matMenu" xPosition="before"> <mat-menu #actionsMenu="matMenu" xPosition="before">
<button *ngIf="canCreateNewVersion(dmp)" mat-menu-item (click)="newVersionClicked()"> <button *ngIf="canCreateNewVersion()" mat-menu-item (click)="newVersionClicked()">
<mat-icon>queue</mat-icon>{{'PLAN-LISTING.ACTIONS.NEW-VERSION' | translate}} <mat-icon>queue</mat-icon>{{'PLAN-LISTING.ACTIONS.NEW-VERSION' | translate}}
</button> </button>
<button mat-menu-item (click)="viewVersions(dmp)"> <button mat-menu-item (click)="viewVersions(plan)">
<mat-icon>library_books</mat-icon>{{'PLAN-LISTING.ACTIONS.VIEW-VERSION' | translate}} <mat-icon>library_books</mat-icon>{{'PLAN-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</button> </button>
<button mat-menu-item *ngIf="isDraftDmp(dmp) && canDeletePlan(dmp)" (click)="deleteClicked(dmp.id)" class="menu-item"> <button mat-menu-item *ngIf="isDraftPlan(plan) && canDeletePlan()" (click)="deleteClicked(plan.id)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'PLAN-LISTING.ACTIONS.DELETE' | translate }} <mat-icon>delete</mat-icon>{{ 'PLAN-LISTING.ACTIONS.DELETE' | translate }}
</button> </button>
</mat-menu> </mat-menu>

View File

@ -111,7 +111,7 @@ p {
min-width: 74px; min-width: 74px;
} }
.dmp-card, .plan-card,
.description-card { .description-card {
min-width: 712px; min-width: 712px;
/* min-height: 308px; */ /* min-height: 308px; */
@ -147,7 +147,7 @@ input[type="text"] {
opacity: 0.6; opacity: 0.6;
} }
.dmp-label { .plan-label {
background: var(--primary-color) 0% 0% no-repeat padding-box; background: var(--primary-color) 0% 0% no-repeat padding-box;
border-radius: 4px 0px; border-radius: 4px 0px;
opacity: 1; opacity: 1;
@ -157,7 +157,7 @@ input[type="text"] {
line-height: 2.4; line-height: 2.4;
} }
.dmp-title, .plan-title,
.description-title { .description-title {
text-align: left; text-align: left;
font-weight: 600; font-weight: 600;
@ -169,7 +169,7 @@ input[type="text"] {
} }
.description-subtitle, .description-subtitle,
.dmp-subtitle { .plan-subtitle {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
text-align: left; text-align: left;
@ -180,7 +180,7 @@ input[type="text"] {
color: #848484; color: #848484;
} }
.dmp-title-draft, .plan-title-draft,
.description-title-draft { .description-title-draft {
text-align: left; text-align: left;
font-weight: 600; font-weight: 600;
@ -196,7 +196,7 @@ input[type="text"] {
vertical-align: middle; vertical-align: middle;
} }
.dmp-subtitle, .plan-subtitle,
.description-subtitle { .description-subtitle {
.icon-align { .icon-align {
@ -208,7 +208,7 @@ input[type="text"] {
} }
.description-card-actions, .description-card-actions,
.dmp-card-actions { .plan-card-actions {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
border-top: 1px solid #dbdbdb; border-top: 1px solid #dbdbdb;
@ -217,24 +217,24 @@ input[type="text"] {
} }
.description-card-actions a, .description-card-actions a,
.dmp-card-actions a { .plan-card-actions a {
color: #848484 !important; color: #848484 !important;
text-decoration: none !important; text-decoration: none !important;
} }
.description-card-actions a:hover, .description-card-actions a:hover,
.dmp-card-actions a:hover { .plan-card-actions a:hover {
color: var(--primary-color) !important; color: var(--primary-color) !important;
} }
.dmp-description-descriptions-title { .plan-description-descriptions-title {
color: #000000; color: #000000;
opacity: 0.6; opacity: 0.6;
padding-top: 1.5rem; padding-top: 1.5rem;
padding-bottom: 0.8rem; padding-bottom: 0.8rem;
} }
.dmp-description-descriptions-name { .plan-description-descriptions-name {
color: #000000; color: #000000;
opacity: 0.6; opacity: 0.6;
font-weight: 700; font-weight: 700;

View File

@ -33,13 +33,13 @@ import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/
import { RouterUtilsService } from '@app/core/services/router/router-utils.service'; import { RouterUtilsService } from '@app/core/services/router/router-utils.service';
@Component({ @Component({
selector: 'app-dmp-listing-item-component', selector: 'app-plan-listing-item-component',
templateUrl: './plan-listing-item.component.html', templateUrl: './plan-listing-item.component.html',
styleUrls: ['./plan-listing-item.component.scss'], styleUrls: ['./plan-listing-item.component.scss'],
}) })
export class PlanListingItemComponent extends BaseComponent implements OnInit { export class PlanListingItemComponent extends BaseComponent implements OnInit {
@Input() dmp: Plan; @Input() plan: Plan;
@Input() showDivider: boolean = true; @Input() showDivider: boolean = true;
@Input() isPublic: boolean; @Input() isPublic: boolean;
@Output() onClick: EventEmitter<Plan> = new EventEmitter(); @Output() onClick: EventEmitter<Plan> = new EventEmitter();
@ -75,16 +75,16 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.analyticsService.trackPageView(AnalyticsService.PlanListingItem); this.analyticsService.trackPageView(AnalyticsService.PlanListingItem);
if (this.dmp.status == PlanStatus.Draft) { if (this.plan.status == PlanStatus.Draft) {
this.isDraft = true; this.isDraft = true;
this.isFinalized = false; this.isFinalized = false;
this.isPublished = false; this.isPublished = false;
} }
else if (this.dmp.status == PlanStatus.Finalized) { else if (this.plan.status == PlanStatus.Finalized) {
this.isDraft = false; this.isDraft = false;
this.isFinalized = true; this.isFinalized = true;
this.isPublished = false; this.isPublished = false;
if (this.dmp.status === PlanStatus.Finalized && this.dmp.accessType === PlanAccessType.Public) { this.isPublished = true } if (this.plan.status === PlanStatus.Finalized && this.plan.accessType === PlanAccessType.Public) { this.isPublished = true }
} }
} }
@ -92,33 +92,33 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
return this.authentication.currentAccountIsAuthenticated(); return this.authentication.currentAccountIsAuthenticated();
} }
inviteToDmp() { inviteToPlan() {
const dialogRef = this.dialog.open(PlanInvitationDialogComponent, { const dialogRef = this.dialog.open(PlanInvitationDialogComponent, {
// height: '250px', // height: '250px',
// width: '700px', // width: '700px',
autoFocus: false, autoFocus: false,
restoreFocus: false, restoreFocus: false,
data: { data: {
planId: this.dmp.id, planId: this.plan.id,
dmpName: this.dmp.label, planName: this.plan.label,
blueprint: this.dmp.blueprint blueprint: this.plan.blueprint
} }
}); });
} }
viewVersions(dmp: Plan) { viewVersions(plan: Plan) {
if (dmp.accessType == PlanAccessType.Public && dmp.status == PlanStatus.Finalized && !this.dmp.authorizationFlags?.some(x => x === AppPermission.EditPlan)) { if (plan.accessType == PlanAccessType.Public && plan.status == PlanStatus.Finalized && !this.plan.authorizationFlags?.some(x => x === AppPermission.EditPlan)) {
let url = this.router.createUrlTree(['/explore-plans/versions/', dmp.groupId]); let url = this.router.createUrlTree(['/explore-plans/versions/', plan.groupId]);
window.open(url.toString(), '_blank'); window.open(url.toString(), '_blank');
} else { } else {
let url = this.router.createUrlTree(['/plans/versions/', dmp.groupId]); let url = this.router.createUrlTree(['/plans/versions/', plan.groupId]);
window.open(url.toString(), '_blank'); window.open(url.toString(), '_blank');
} }
} }
isUserPlanRelated() { isUserPlanRelated() {
const principalId: Guid = this.authentication.userId(); const principalId: Guid = this.authentication.userId();
return this.dmp.planUsers?.some(x => (x.user.id === principalId)); return this.plan.planUsers?.some(x => (x.user.id === principalId));
} }
cloneClicked() { cloneClicked() {
@ -126,7 +126,7 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
maxWidth: '700px', maxWidth: '700px',
maxHeight: '80vh', maxHeight: '80vh',
data: { data: {
plan: this.dmp plan: this.plan
} }
}); });
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: Plan) => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: Plan) => {
@ -142,7 +142,7 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
maxWidth: '700px', maxWidth: '700px',
maxHeight: '80vh', maxHeight: '80vh',
data: { data: {
plan: this.dmp plan: this.plan
} }
}); });
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: Plan) => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: Plan) => {
@ -168,11 +168,11 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
openDeleteDialog(id: Guid) { openDeleteDialog(id: Guid) {
let dialogRef: any; let dialogRef: any;
if (this.dmp.descriptions && this.dmp.descriptions.length > 0){ if (this.plan.descriptions && this.plan.descriptions.length > 0){
dialogRef = this.dialog.open(PlanDeleteDialogComponent, { dialogRef = this.dialog.open(PlanDeleteDialogComponent, {
maxWidth: '300px', maxWidth: '300px',
data: { data: {
descriptions: this.dmp.descriptions, descriptions: this.plan.descriptions,
} }
}); });
} else { } else {
@ -210,7 +210,7 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
}); });
} }
isDraftDmp(activity: Plan) { isDraftPlan(activity: Plan) {
return activity.status == PlanStatus.Draft; return activity.status == PlanStatus.Draft;
} }
@ -230,35 +230,35 @@ export class PlanListingItemComponent extends BaseComponent implements OnInit {
this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error);
} }
canEditPlan(dmp: Plan): boolean { canEditPlan(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.EditPlan) || this.authentication.hasPermission(AppPermission.EditPlan)) && this.isPublic == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.EditPlan) || this.authentication.hasPermission(AppPermission.EditPlan)) && this.isPublic == false && this.plan.belongsToCurrentTenant != false;
} }
canCreateNewVersion(dmp: Plan): boolean { canCreateNewVersion(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.CreateNewVersionPlan) || this.authentication.hasPermission(AppPermission.CreateNewVersionPlan)) && this.dmp.versionStatus === PlanVersionStatus.Current && this.isPublic == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.CreateNewVersionPlan) || this.authentication.hasPermission(AppPermission.CreateNewVersionPlan)) && this.plan.versionStatus === PlanVersionStatus.Current && this.isPublic == false && this.plan.belongsToCurrentTenant != false;
} }
canDeletePlan(dmp: Plan): boolean { canDeletePlan(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.DeletePlan) || this.authentication.hasPermission(AppPermission.DeletePlan)) && this.isPublic == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.DeletePlan) || this.authentication.hasPermission(AppPermission.DeletePlan)) && this.isPublic == false && this.plan.belongsToCurrentTenant != false;
} }
canClonePlan(dmp: Plan): boolean { canClonePlan(): boolean {
return this.dmp.authorizationFlags?.some(x => x === AppPermission.ClonePlan) || this.authentication.hasPermission(AppPermission.ClonePlan); return this.plan.authorizationFlags?.some(x => x === AppPermission.ClonePlan) || this.authentication.hasPermission(AppPermission.ClonePlan);
} }
canFinalizePlan(dmp: Plan): boolean { canFinalizePlan(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.FinalizePlan) || this.authentication.hasPermission(AppPermission.FinalizePlan)) && this.isPublic == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.FinalizePlan) || this.authentication.hasPermission(AppPermission.FinalizePlan)) && this.isPublic == false && this.plan.belongsToCurrentTenant != false;
} }
canExportPlan(dmp: Plan): boolean { canExportPlan(): boolean {
return this.dmp.authorizationFlags?.some(x => x === AppPermission.ExportPlan) || this.authentication.hasPermission(AppPermission.ExportPlan); return this.plan.authorizationFlags?.some(x => x === AppPermission.ExportPlan) || this.authentication.hasPermission(AppPermission.ExportPlan);
} }
canInvitePlanUsers(dmp: Plan): boolean { canInvitePlanUsers(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.InvitePlanUsers) || this.authentication.hasPermission(AppPermission.InvitePlanUsers)) && this.isPublic == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.InvitePlanUsers) || this.authentication.hasPermission(AppPermission.InvitePlanUsers)) && this.isPublic == false && this.plan.belongsToCurrentTenant != false;
} }
canAssignPlanUsers(dmp: Plan): boolean { canAssignPlanUsers(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.AssignPlanUsers) || this.authentication.hasPermission(AppPermission.AssignPlanUsers)) && this.isPublic == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.AssignPlanUsers) || this.authentication.hasPermission(AppPermission.AssignPlanUsers)) && this.isPublic == false && this.plan.belongsToCurrentTenant != false;
} }
} }

View File

@ -4,7 +4,7 @@
<div *ngIf="hasLoadedListingItems && !hasListingItems && !hasFilters" class="col-12 card mt-0"> <div *ngIf="hasLoadedListingItems && !hasListingItems && !hasFilters" class="col-12 card mt-0">
<div class="card-content info-text mb-0"> <div class="card-content info-text mb-0">
<p>{{'PLAN-LISTING.TEXT-INFO' | translate}}</p> <p>{{'PLAN-LISTING.TEXT-INFO' | translate}}</p>
<p class="mt-4 pt-2">{{'PLAN-LISTING.TEXT-INFO-QUESTION' | translate}} <a class="zenodo-link" href="https://zenodo.org/communities/liber-dmp-cat/?page=1&size=20" target="_blank">{{'PLAN-LISTING.LINK-ZENODO' | translate}}</a> {{'PLAN-LISTING.GET-IDEA' | translate}}</p> <p class="mt-4 pt-2">{{'PLAN-LISTING.TEXT-INFO-QUESTION' | translate}} <a class="zenodo-link" href="https://zenodo.org/communities/liber-plan-cat/?page=1&size=20" target="_blank">{{'PLAN-LISTING.LINK-ZENODO' | translate}}</a> {{'PLAN-LISTING.GET-IDEA' | translate}}</p>
<div class="d-flex"> <div class="d-flex">
<div *ngIf="!isPublic" class="col left-content" (click)="restartTour()">{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}</div> <div *ngIf="!isPublic" class="col left-content" (click)="restartTour()">{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }}</div>
<img class="col-auto ml-auto laptop-img" src="../../../assets/images/dashboard-popup.png"> <img class="col-auto ml-auto laptop-img" src="../../../assets/images/dashboard-popup.png">
@ -62,7 +62,7 @@
</div> </div>
<div class="col-md-12 col-sm-12 col-md-9"> <div class="col-md-12 col-sm-12 col-md-9">
<div *ngFor="let item of listingItems; let i = index"> <div *ngFor="let item of listingItems; let i = index">
<app-dmp-listing-item-component [showDivider]="i != (listingItems.length - 1)" [dmp]="item" [isPublic]="isPublic"></app-dmp-listing-item-component> <app-plan-listing-item-component [showDivider]="i != (listingItems.length - 1)" [plan]="item" [isPublic]="isPublic"></app-plan-listing-item-component>
</div> </div>
<div *ngIf="hasListingItems && this.lookup?.page?.offset < this.totalCount - 1 && this.pageSize < this.totalCount - 1" class="d-flex justify-content-center"> <div *ngIf="hasListingItems && this.lookup?.page?.offset < this.totalCount - 1 && this.pageSize < this.totalCount - 1" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button> <button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>

View File

@ -42,7 +42,7 @@
color: #999999 !important; color: #999999 !important;
} }
.dmp-label { .plan-label {
color: #089dbb !important; color: #089dbb !important;
} }
@ -78,7 +78,7 @@
padding-bottom: 2em; padding-bottom: 2em;
} }
.explore-dmp-content { .explore-plan-content {
padding: 30px 15px; padding: 30px 15px;
} }

View File

@ -150,11 +150,11 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
} }
public dashboardTour: GuidedTour = { public dashboardTour: GuidedTour = {
tourId: 'dmp-description-tour', tourId: 'plan-description-tour',
useOrb: true, useOrb: true,
steps: [ steps: [
{ {
selector: '.dmp-tour', selector: '.plan-tour',
content: 'Step 1', content: 'Step 1',
orientation: Orientation.Right, orientation: Orientation.Right,
isStepUnique: false isStepUnique: false
@ -194,8 +194,8 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
if (!result) { return []; } if (!result) { return []; }
this.totalCount = result.count; this.totalCount = result.count;
if (this.lookup?.page?.offset === 0) this.listingItems = []; if (this.lookup?.page?.offset === 0) this.listingItems = [];
const dmps = this._filterDmp([...result.items]); const plans = this._filterPlan([...result.items]);
this.listingItems.push(...dmps); this.listingItems.push(...plans);
this.hasLoadedListingItems = true; this.hasLoadedListingItems = true;
})); }));
} }
@ -299,12 +299,12 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight
} }
public setDashboardTourDmpText(): void { public setDashboardTourPlanText(): void {
const dmpText = this.language.instant('PLAN-LISTING.TEXT-INFO') + '\n\n' + const planText = this.language.instant('PLAN-LISTING.TEXT-INFO') + '\n\n' +
this.language.instant('PLAN-LISTING.TEXT-INFO-QUESTION') + ' ' + this.language.instant('PLAN-LISTING.TEXT-INFO-QUESTION') + ' ' +
this.language.instant('PLAN-LISTING.LINK-ZENODO') + ' ' + this.language.instant('PLAN-LISTING.LINK-ZENODO') + ' ' +
this.language.instant('PLAN-LISTING.GET-IDEA'); this.language.instant('PLAN-LISTING.GET-IDEA');
this.dashboardTour.steps[0].title = dmpText; this.dashboardTour.steps[0].title = planText;
} }
public setDashboardTourDescriptionText(): void { public setDashboardTourDescriptionText(): void {
@ -315,7 +315,7 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
} }
public restartTour(): void { public restartTour(): void {
this.setDashboardTourDmpText(); this.setDashboardTourPlanText();
this.setDashboardTourDescriptionText(); this.setDashboardTourDescriptionText();
this.guidedTourService.startTour(this.dashboardTour); this.guidedTourService.startTour(this.dashboardTour);
} }
@ -365,13 +365,13 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
// Blueprints // Blueprints
let dmpBlueprints = formGroup.get("dmpBlueprints")?.value ?? null; let planBlueprints = formGroup.get("planBlueprints")?.value ?? null;
if (dmpBlueprints && dmpBlueprints?.length > 0) { if (planBlueprints && planBlueprints?.length > 0) {
lookup.planBlueprintSubQuery = PlanFilterService.initializePlanBlueprintLookup(); lookup.planBlueprintSubQuery = PlanFilterService.initializePlanBlueprintLookup();
lookup.planBlueprintSubQuery.ids = dmpBlueprints; lookup.planBlueprintSubQuery.ids = planBlueprints;
} else lookup.planBlueprintSubQuery = null; } else lookup.planBlueprintSubQuery = null;
// Dmps // plans
let roles = formGroup.get("role")?.value !== null ? [formGroup.get("role")?.value] : null; let roles = formGroup.get("role")?.value !== null ? [formGroup.get("role")?.value] : null;
if (roles && roles?.length > 0) { if (roles && roles?.length > 0) {
lookup.planUserSubQuery = PlanFilterService.initializePlanUserLookup(); lookup.planUserSubQuery = PlanFilterService.initializePlanUserLookup();
@ -399,7 +399,7 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
return (new UntypedFormBuilder()).group({ return (new UntypedFormBuilder()).group({
status: [lookup.statuses?.length > 0 ? lookup.statuses[0] : null], status: [lookup.statuses?.length > 0 ? lookup.statuses[0] : null],
descriptionTemplates: lookup.planDescriptionTemplateSubQuery?.descriptionTemplateGroupIds ? [lookup.planDescriptionTemplateSubQuery?.descriptionTemplateGroupIds] : [], descriptionTemplates: lookup.planDescriptionTemplateSubQuery?.descriptionTemplateGroupIds ? [lookup.planDescriptionTemplateSubQuery?.descriptionTemplateGroupIds] : [],
dmpBlueprints: lookup.planBlueprintSubQuery?.ids ? [lookup.planBlueprintSubQuery?.ids]: [], planBlueprints: lookup.planBlueprintSubQuery?.ids ? [lookup.planBlueprintSubQuery?.ids]: [],
role: lookup.planUserSubQuery?.userRoles ? lookup.planUserSubQuery?.userRoles[0] : null, role: lookup.planUserSubQuery?.userRoles ? lookup.planUserSubQuery?.userRoles[0] : null,
}); });
} }
@ -416,11 +416,11 @@ export class PlanListingComponent extends BaseListingComponent<BasePlan, PlanLoo
return count; return count;
} }
private _filterDmp(dmps: BasePlan[]): BasePlan[] { private _filterPlan(plans: BasePlan[]): BasePlan[] {
dmps.forEach((dmp: BasePlan) => { plans.forEach((plan: BasePlan) => {
dmp.descriptions = dmp.descriptions?.filter(d => d.isActive == IsActive.Active) ?? []; plan.descriptions = plan.descriptions?.filter(d => d.isActive == IsActive.Active) ?? [];
}) })
return dmps; return plans;
} }
private get _lookupFields(): string[] { private get _lookupFields(): string[] {

View File

@ -52,7 +52,7 @@
<mat-checkbox [checked]="allDescriptionsCompleted" [indeterminate]="someDescriptionsCompleted" (change)="toggleAllDescriptions($event.checked)">{{ 'PLAN-NEW-VERSION-DIALOG.ACTIONS.TOGGLE-DESCRIPTIONS' | translate }}</mat-checkbox> <mat-checkbox [checked]="allDescriptionsCompleted" [indeterminate]="someDescriptionsCompleted" (change)="toggleAllDescriptions($event.checked)">{{ 'PLAN-NEW-VERSION-DIALOG.ACTIONS.TOGGLE-DESCRIPTIONS' | translate }}</mat-checkbox>
</mat-card-header> </mat-card-header>
<mat-selection-list #selectedItems (selectionChange)="descriptionSelectionChanged($event)"> <mat-selection-list #selectedItems (selectionChange)="descriptionSelectionChanged($event)">
<ng-container *ngFor="let description of dmp.descriptions;"> <ng-container *ngFor="let description of plan.descriptions;">
<mat-list-option [value]="description.id" [selected]="isDefaultSelected(formGroup.get('descriptions'), description.id)" class="h-auto"> <mat-list-option [value]="description.id" [selected]="isDefaultSelected(formGroup.get('descriptions'), description.id)" class="h-auto">
<div class="mat-mdc-form-field-bottom-align w-100"></div> <div class="mat-mdc-form-field-bottom-align w-100"></div>
<mat-form-field class="w-100" (click)="selectTemplate($event)" floatLabel="never"> <mat-form-field class="w-100" (click)="selectTemplate($event)" floatLabel="never">

View File

@ -7,7 +7,7 @@ import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/serv
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { map, takeUntil } from 'rxjs/operators'; import { map, takeUntil } from 'rxjs/operators';
import { DmpNewVersionDialogEditorModel } from './plan-new-version-dialog.editor.model'; import { PlanNewVersionDialogEditorModel } from './plan-new-version-dialog.editor.model';
import { PlanBlueprintService } from '@app/core/services/plan/plan-blueprint.service'; import { PlanBlueprintService } from '@app/core/services/plan/plan-blueprint.service';
import { PlanEditorEntityResolver } from '../plan-editor-blueprint/resolvers/plan-editor-enitity.resolver'; import { PlanEditorEntityResolver } from '../plan-editor-blueprint/resolvers/plan-editor-enitity.resolver';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
@ -32,8 +32,8 @@ import { Description } from '@app/core/model/description/description';
}) })
export class NewVersionPlanDialogComponent extends BaseComponent { export class NewVersionPlanDialogComponent extends BaseComponent {
dmp: Plan; plan: Plan;
editorModel: DmpNewVersionDialogEditorModel; editorModel: PlanNewVersionDialogEditorModel;
formGroup: UntypedFormGroup; formGroup: UntypedFormGroup;
selectedBlueprintSections: PlanBlueprintDefinitionSection[]; selectedBlueprintSections: PlanBlueprintDefinitionSection[];
@ -83,8 +83,8 @@ export class NewVersionPlanDialogComponent extends BaseComponent {
@Inject(MAT_DIALOG_DATA) public data: any @Inject(MAT_DIALOG_DATA) public data: any
) { ) {
super(); super();
this.dmp = data.plan; this.plan = data.plan;
this.dmp.planDescriptionTemplates = this.dmp.planDescriptionTemplates?.filter(x => x.isActive === IsActive.Active); this.plan.planDescriptionTemplates = this.plan.planDescriptionTemplates?.filter(x => x.isActive === IsActive.Active);
} }
get allDescriptionsNo(): number{ get allDescriptionsNo(): number{
@ -109,15 +109,15 @@ export class NewVersionPlanDialogComponent extends BaseComponent {
ngOnInit() { ngOnInit() {
this.selectedBlueprintSections = this.dmp.blueprint?.definition?.sections?.filter(x => x.hasTemplates) || null; this.selectedBlueprintSections = this.plan.blueprint?.definition?.sections?.filter(x => x.hasTemplates) || null;
this.editorModel = new DmpNewVersionDialogEditorModel().fromModel(this.dmp, this.dmp.blueprint); this.editorModel = new PlanNewVersionDialogEditorModel().fromModel(this.plan, this.plan.blueprint);
this.formGroup = this.editorModel.buildForm(); this.formGroup = this.editorModel.buildForm();
} }
selectedBlueprintChanged(item: PlanBlueprint): void{ selectedBlueprintChanged(item: PlanBlueprint): void{
this.selectedBlueprintSections = item.definition?.sections?.filter(x => x.hasTemplates) || null; this.selectedBlueprintSections = item.definition?.sections?.filter(x => x.hasTemplates) || null;
if(this.selectedBlueprintSections && this.hasDescriptions()) { if(this.selectedBlueprintSections && this.hasDescriptions()) {
this.formGroup = this.editorModel.fromModel(this.dmp, item, this.formGroup.get('label').value, this.formGroup.get('description').value).buildForm(); this.formGroup = this.editorModel.fromModel(this.plan, item, this.formGroup.get('label').value, this.formGroup.get('description').value).buildForm();
} }
} }
@ -170,7 +170,7 @@ export class NewVersionPlanDialogComponent extends BaseComponent {
} }
hasDescriptions() { hasDescriptions() {
return this.dmp.descriptions?.length > 0; return this.plan.descriptions?.length > 0;
} }
close() { close() {
@ -188,7 +188,7 @@ export class NewVersionPlanDialogComponent extends BaseComponent {
formData.descriptions = formData.descriptions.filter(x => x.blueprintSectionId != null) formData.descriptions = formData.descriptions.filter(x => x.blueprintSectionId != null)
} }
this.planService.newVersion(formData, PlanEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe( this.planService.newVersion(formData, PlanEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
dmp => this.dialogRef.close(dmp), plan => this.dialogRef.close(plan),
error => this.onCallbackError(error) error => this.onCallbackError(error)
); );

View File

@ -6,12 +6,12 @@ import { ValidationErrorModel } from '@common/forms/validation/error-model/valid
import { Validation, ValidationContext } from '@common/forms/validation/validation-context'; import { Validation, ValidationContext } from '@common/forms/validation/validation-context';
import { Guid } from "@common/types/guid"; import { Guid } from "@common/types/guid";
export class DmpNewVersionDialogEditorModel implements NewVersionPlanPersist { export class PlanNewVersionDialogEditorModel implements NewVersionPlanPersist {
id: Guid; id: Guid;
label: string; label: string;
description: String; description: String;
blueprintId: Guid; blueprintId: Guid;
descriptions: NewVersionDmpDescriptionEditorModel[] = []; descriptions: NewVersionPlanDescriptionEditorModel[] = [];
hash?: string; hash?: string;
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
@ -19,7 +19,7 @@ export class DmpNewVersionDialogEditorModel implements NewVersionPlanPersist {
constructor() { } constructor() { }
public fromModel(item: Plan, blueprint: PlanBlueprint, label?: string, description?: string): DmpNewVersionDialogEditorModel { public fromModel(item: Plan, blueprint: PlanBlueprint, label?: string, description?: string): PlanNewVersionDialogEditorModel {
if (item) { if (item) {
this.id = item.id; this.id = item.id;
this.label = label != undefined ? label : item.label; this.label = label != undefined ? label : item.label;
@ -32,16 +32,16 @@ export class DmpNewVersionDialogEditorModel implements NewVersionPlanPersist {
// initialize because blueprint changed // initialize because blueprint changed
this.descriptions = []; this.descriptions = [];
if (item.planDescriptionTemplates?.length > 0 && blueprint.id === item.blueprint.id) { // dmp's first blueprint if (item.planDescriptionTemplates?.length > 0 && blueprint.id === item.blueprint.id) { // plan's first blueprint
item.descriptions.forEach(description => { item.descriptions.forEach(description => {
this.descriptions.push(new NewVersionDmpDescriptionEditorModel(this.validationErrorModel).fromModel(description.id, description.planDescriptionTemplate.sectionId)); this.descriptions.push(new NewVersionPlanDescriptionEditorModel(this.validationErrorModel).fromModel(description.id, description.planDescriptionTemplate.sectionId));
}) })
} else { // in case the user changes the blueprint from the dropdown and the new blueprint has prefilled templates } else { // in case the user changes the blueprint from the dropdown and the new blueprint has prefilled templates
const selectedBlueprintSections = blueprint.definition?.sections?.filter(x => x.hasTemplates) || null; const selectedBlueprintSections = blueprint.definition?.sections?.filter(x => x.hasTemplates) || null;
if (selectedBlueprintSections != null){ if (selectedBlueprintSections != null){
item.descriptions.forEach(description => { item.descriptions.forEach(description => {
const matchingSection = selectedBlueprintSections.find(blueprintSection => blueprintSection.descriptionTemplates != null && blueprintSection.descriptionTemplates.map(y => y.descriptionTemplateGroupId).includes(description.descriptionTemplate.groupId)) || null; const matchingSection = selectedBlueprintSections.find(blueprintSection => blueprintSection.descriptionTemplates != null && blueprintSection.descriptionTemplates.map(y => y.descriptionTemplateGroupId).includes(description.descriptionTemplate.groupId)) || null;
this.descriptions.push(new NewVersionDmpDescriptionEditorModel(this.validationErrorModel).fromModel(description.id, matchingSection != null ? matchingSection.id : null)); this.descriptions.push(new NewVersionPlanDescriptionEditorModel(this.validationErrorModel).fromModel(description.id, matchingSection != null ? matchingSection.id : null));
}) })
} }
} }
@ -86,7 +86,7 @@ export class DmpNewVersionDialogEditorModel implements NewVersionPlanPersist {
} }
} }
export class NewVersionDmpDescriptionEditorModel implements NewVersionPlanDescriptionPersist { export class NewVersionPlanDescriptionEditorModel implements NewVersionPlanDescriptionPersist {
descriptionId: Guid; descriptionId: Guid;
blueprintSectionId: Guid; blueprintSectionId: Guid;
@ -96,7 +96,7 @@ export class NewVersionDmpDescriptionEditorModel implements NewVersionPlanDescri
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() public validationErrorModel: ValidationErrorModel = new ValidationErrorModel()
) { } ) { }
fromModel(descriptionId: Guid, blueprintSectionId: Guid): NewVersionDmpDescriptionEditorModel { fromModel(descriptionId: Guid, blueprintSectionId: Guid): NewVersionPlanDescriptionEditorModel {
this.descriptionId = descriptionId; this.descriptionId = descriptionId;
this.blueprintSectionId = blueprintSectionId; this.blueprintSectionId = blueprintSectionId;
@ -110,7 +110,7 @@ export class NewVersionDmpDescriptionEditorModel implements NewVersionPlanDescri
}): UntypedFormGroup { }): UntypedFormGroup {
let { context = null, disabled = false, rootPath } = params ?? {} let { context = null, disabled = false, rootPath } = params ?? {}
if (context == null) { if (context == null) {
context = NewVersionDmpDescriptionEditorModel.createValidationContext({ context = NewVersionPlanDescriptionEditorModel.createValidationContext({
validationErrorModel: this.validationErrorModel, validationErrorModel: this.validationErrorModel,
rootPath rootPath
}); });

View File

@ -1,6 +1,6 @@
<div class="start-new-dmp-dialog-wrapper"> <div class="start-new-plan-dialog-wrapper">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<div class="pl-0 col-auto"><a class="logo"><img class="logo" src="../../../assets/images/new-dmp-logo.png" onerror="this.style.display='none'"></a></div> <div class="pl-0 col-auto"><a class="logo"><img class="logo" src="../../../assets/images/new-plan-logo.png" onerror="this.style.display='none'"></a></div>
<div class="col-auto close-btn" (click)="close()"> <div class="col-auto close-btn" (click)="close()">
<mat-icon class="close-icon">close</mat-icon> <mat-icon class="close-icon">close</mat-icon>
</div> </div>

View File

@ -3,7 +3,7 @@
padding: 24px; padding: 24px;
} }
.start-new-dmp-dialog-wrapper { .start-new-plan-dialog-wrapper {
width: 33.0rem; width: 33.0rem;
min-height: 14rem; min-height: 14rem;
padding: 0.28rem 0.34rem 0.875rem 0.625rem; padding: 0.28rem 0.34rem 0.875rem 0.625rem;

View File

@ -7,7 +7,7 @@ import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/serv
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { DmpUploadDialogComponent } from '../upload-dialogue/plan-upload-dialog.component'; import { PlanUploadDialogComponent } from '../upload-dialogue/plan-upload-dialog.component';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { RouterUtilsService } from '@app/core/services/router/router-utils.service'; import { RouterUtilsService } from '@app/core/services/router/router-utils.service';
@ -58,7 +58,7 @@ export class StartNewPlanDialogComponent extends BaseComponent {
} }
uploadFile(event) { uploadFile(event) {
const dialogRef = this.dialog.open(DmpUploadDialogComponent, { const dialogRef = this.dialog.open(PlanUploadDialogComponent, {
width: '528px', width: '528px',
data: { data: {
fileList: FileList, fileList: FileList,

View File

@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
import { FormattingModule } from '@app/core/formatting.module'; import { FormattingModule } from '@app/core/formatting.module';
import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonFormsModule } from '@common/forms/common-forms.module';
import { CommonUiModule } from '@common/ui/common-ui.module'; import { CommonUiModule } from '@common/ui/common-ui.module';
import { DmpUploadDialogModule } from '../upload-dialogue/plan-upload-dialog.module'; import { PlanUploadDialogModule } from '../upload-dialogue/plan-upload-dialog.module';
import { StartNewPlanDialogComponent } from './start-new-plan-dialog.component'; import { StartNewPlanDialogComponent } from './start-new-plan-dialog.component';
@NgModule({ @NgModule({
@ -10,7 +10,7 @@ import { StartNewPlanDialogComponent } from './start-new-plan-dialog.component';
CommonUiModule, CommonUiModule,
CommonFormsModule, CommonFormsModule,
FormattingModule, FormattingModule,
DmpUploadDialogModule PlanUploadDialogModule
], ],
declarations: [ declarations: [
StartNewPlanDialogComponent, StartNewPlanDialogComponent,

View File

@ -6,7 +6,7 @@ import { Guid } from "@common/types/guid";
import { PlanCommonModelConfig, PreprocessingPlanModel } from "@app/core/model/plan/plan-import"; import { PlanCommonModelConfig, PreprocessingPlanModel } from "@app/core/model/plan/plan-import";
import { DescriptionCommonModelConfig, PreprocessingDescriptionModel } from "@app/core/model/description/description-import"; import { DescriptionCommonModelConfig, PreprocessingDescriptionModel } from "@app/core/model/description/description-import";
export class DmpImportRdaConfigEditorModel implements PlanCommonModelConfig{ export class PlanImportRdaConfigEditorModel implements PlanCommonModelConfig{
fileId: Guid; fileId: Guid;
label: string; label: string;
blueprintId: Guid; blueprintId: Guid;
@ -18,7 +18,7 @@ export class DmpImportRdaConfigEditorModel implements PlanCommonModelConfig{
constructor() { } constructor() { }
fromModel(item: PreprocessingPlanModel, fileId: Guid): DmpImportRdaConfigEditorModel { fromModel(item: PreprocessingPlanModel, fileId: Guid): PlanImportRdaConfigEditorModel {
this.fileId = fileId; this.fileId = fileId;
if (item){ if (item){
this.label = item.label + '.json'; this.label = item.label + '.json';

View File

@ -8,7 +8,7 @@ import { PlanService } from '@app/core/services/plan/plan.service';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { map, takeUntil } from 'rxjs/operators'; import { map, takeUntil } from 'rxjs/operators';
import { DmpImportRdaConfigEditorModel } from './plan-common-model-config.editor.model'; import { PlanImportRdaConfigEditorModel } from './plan-common-model-config.editor.model';
import { UntypedFormArray, UntypedFormGroup } from '@angular/forms'; import { UntypedFormArray, UntypedFormGroup } from '@angular/forms';
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service'; import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
import { FormService } from '@common/forms/form-service'; import { FormService } from '@common/forms/form-service';
@ -24,9 +24,9 @@ import { TranslateService } from '@ngx-translate/core';
templateUrl: './plan-upload-dialog.component.html', templateUrl: './plan-upload-dialog.component.html',
styleUrls: ['./plan-upload-dialog.component.scss'] styleUrls: ['./plan-upload-dialog.component.scss']
}) })
export class DmpUploadDialogComponent extends BaseComponent { export class PlanUploadDialogComponent extends BaseComponent {
planTitle: string; planTitle: string;
dmpBlueprints: any[] = []; planBlueprints: any[] = [];
files: File[] = []; files: File[] = [];
selectedBlueprintSections: PlanBlueprintDefinitionSection[]; selectedBlueprintSections: PlanBlueprintDefinitionSection[];
formGroup: UntypedFormGroup; formGroup: UntypedFormGroup;
@ -44,7 +44,7 @@ export class DmpUploadDialogComponent extends BaseComponent {
constructor( constructor(
public dialogRef: MatDialogRef<DmpUploadDialogComponent>, public dialogRef: MatDialogRef<PlanUploadDialogComponent>,
private _service: PlanService, private _service: PlanService,
private dialog: MatDialog, private dialog: MatDialog,
private httpClient: HttpClient, private httpClient: HttpClient,
@ -63,7 +63,7 @@ export class DmpUploadDialogComponent extends BaseComponent {
} }
ngOnInit() { ngOnInit() {
this.analyticsService.trackPageView(AnalyticsService.DmpUploadDialog); this.analyticsService.trackPageView(AnalyticsService.PlanUploadDialog);
} }
cancel() { cancel() {
@ -78,7 +78,7 @@ export class DmpUploadDialogComponent extends BaseComponent {
confirm() { confirm() {
this.data.success = true; this.data.success = true;
this.data.planTitle = this.planTitle; this.data.planTitle = this.planTitle;
this.data.planBlueprints = this.dmpBlueprints; this.data.planBlueprint = this.planBlueprints;
if (this.files.length > 0 && this.files[0].type.includes('/json') && this.formGroup){ if (this.files.length > 0 && this.files[0].type.includes('/json') && this.formGroup){
this.formService.removeAllBackEndErrors(this.formGroup); this.formService.removeAllBackEndErrors(this.formGroup);
@ -121,7 +121,7 @@ export class DmpUploadDialogComponent extends BaseComponent {
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe( .subscribe(
(preprocessingData) => { (preprocessingData) => {
this.formGroup = new DmpImportRdaConfigEditorModel().fromModel(preprocessingData, storageFile[0].id,).buildForm(); this.formGroup = new PlanImportRdaConfigEditorModel().fromModel(preprocessingData, storageFile[0].id,).buildForm();
}, },
(error) => this.onCallbackEror(error.error) (error) => this.onCallbackEror(error.error)
); );

View File

@ -3,7 +3,7 @@ import { FormattingModule } from '@app/core/formatting.module';
import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonFormsModule } from '@common/forms/common-forms.module';
import { CommonUiModule } from '@common/ui/common-ui.module'; import { CommonUiModule } from '@common/ui/common-ui.module';
import { NgxDropzoneModule } from 'ngx-dropzone'; import { NgxDropzoneModule } from 'ngx-dropzone';
import { DmpUploadDialogComponent } from './plan-upload-dialog.component'; import { PlanUploadDialogComponent } from './plan-upload-dialog.component';
import { ReactiveFormsModule } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms';
import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module'; import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module';
@ -17,10 +17,10 @@ import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.mod
NgxDropzoneModule NgxDropzoneModule
], ],
declarations: [ declarations: [
DmpUploadDialogComponent, PlanUploadDialogComponent,
], ],
exports: [ exports: [
DmpUploadDialogComponent, PlanUploadDialogComponent,
] ]
}) })
export class DmpUploadDialogModule { } export class PlanUploadDialogModule { }

View File

@ -1,6 +1,6 @@
<div class="main-content dmp-overview pl-5 pr-5"> <div class="main-content plan-overview pl-5 pr-5">
<div class="container-fluid pl-0 pr-0"> <div class="container-fluid pl-0 pr-0">
<div *ngIf="dmp"> <div *ngIf="plan">
<div class="row"> <div class="row">
<div class="col-12 pl-2 mb-3"> <div class="col-12 pl-2 mb-3">
<app-navigation-breadcrumb /> <app-navigation-breadcrumb />
@ -15,43 +15,43 @@
<div class="row"> <div class="row">
<div class="col-12 col-lg-8 pl-2"> <div class="col-12 col-lg-8 pl-2">
<div class="row align-items-center"> <div class="row align-items-center">
<div class="col-auto"><span class="dmp-logo">{{ 'PLAN-OVERVIEW.TITLE' | translate }}</span></div> <div class="col-auto"><span class="plan-logo">{{ 'PLAN-OVERVIEW.TITLE' | translate }}</span></div>
<div class="col-auto pr-0 d-flex"><span class="dmp-label">{{ dmp.label }}</span></div> <div class="col-auto pr-0 d-flex"><span class="plan-label">{{ plan.label }}</span></div>
<div class="col-auto pr-0 d-flex"><span class="mb-1" style="font-weight: 700;">.</span></div> <div class="col-auto pr-0"><span style="font-weight: 700;">.</span></div>
<div class="col-auto d-flex"><button mat-button [matMenuTriggerFor]="versions" style="border-radius: 100px; background-color: #eaeaea;"> <div class="col-auto d-flex"><button mat-button [matMenuTriggerFor]="versions" style="border-radius: 100px; background-color: #eaeaea;">
<div class="pl-2 pr-1 d-flex align-items-center">{{'PLAN-OVERVIEW.VERSION' | translate}} {{selectedDmpVersion?.version}} <mat-icon class="ml-1">arrow_drop_down</mat-icon></div> <div class="pl-2 pr-1 d-flex align-items-center">{{'PLAN-OVERVIEW.VERSION' | translate}} {{selectedPlanVersion?.version}} <mat-icon class="ml-1">arrow_drop_down</mat-icon></div>
</button></div> </button></div>
<mat-menu #versions="matMenu"> <mat-menu #versions="matMenu">
<button mat-menu-item *ngFor="let version of dmp?.otherPlanVersions" (click)="versionChanged(version.id)" >Version {{version?.version}}</button> <button mat-menu-item *ngFor="let version of plan?.otherPlanVersions" (click)="versionChanged(version.id)" >Version {{version?.version}}</button>
</mat-menu> </mat-menu>
</div> </div>
<div class="row align-items-center mt-3 mb-4 label-txt"> <div class="row align-items-center mt-3 mb-4 label-txt">
<div *ngIf="isUserDmpRelated()" class="col-auto d-flex"> <div *ngIf="isUserPlanRelated()" class="col-auto d-flex">
<p class="ml-0 mb-0 label2-txt">{{ enumUtils.toPlanUserRolesString(planService.getCurrentUserRolesInPlan(dmp?.planUsers)) }} <p class="ml-0 mb-0 label2-txt">{{ enumUtils.toPlanUserRolesString(planService.getCurrentUserRolesInPlan(plan?.planUsers)) }}
</div> </div>
<div *ngIf="isUserDmpRelated() && (isPublishedDmp() || isLocked)" class="col-auto"><span>.</span></div> <div *ngIf="isUserPlanRelated() && (isPublishedPlan() || isLocked)" class="col-auto"><span>.</span></div>
<div *ngIf="isPublishedDmp()" class="col-auto d-flex flex-row"> <div *ngIf="isPublishedPlan()" class="col-auto d-flex flex-row">
<mat-icon class="status-icon">public</mat-icon> <mat-icon class="status-icon">public</mat-icon>
{{'PLAN-OVERVIEW.PUBLIC' | translate}} {{'PLAN-OVERVIEW.PUBLIC' | translate}}
</div> </div>
<div *ngIf="isPublishedDmp() && isLocked" class="col-auto"><span>.</span></div> <div *ngIf="isPublishedPlan() && isLocked" class="col-auto"><span>.</span></div>
<div *ngIf="isLocked" class="col-auto d-flex flex-row"> <div *ngIf="isLocked" class="col-auto d-flex flex-row">
<mat-icon class="status-icon">lock_outline</mat-icon> <mat-icon class="status-icon">lock_outline</mat-icon>
{{'PLAN-OVERVIEW.LOCKED' | translate}} {{'PLAN-OVERVIEW.LOCKED' | translate}}
</div> </div>
<div class="col-auto d-flex">{{'PLAN-OVERVIEW.EDITED' | translate}} : <div class="col-auto d-flex">{{'PLAN-OVERVIEW.EDITED' | translate}} :
{{dmp.updatedAt | dateTimeFormatter: "d MMMM y"}} {{plan.updatedAt | dateTimeFormatter: "d MMMM y"}}
</div> </div>
<div class="col-auto d-flex"> <div class="col-auto d-flex">
<div *ngIf="dmp.status== planStatusEnum.Finalized" class="d-flex flex-row uppercase"> <div *ngIf="plan.status== planStatusEnum.Finalized" class="d-flex flex-row uppercase">
<mat-icon class="status-icon">check</mat-icon> <mat-icon class="status-icon">check</mat-icon>
{{'PLAN-OVERVIEW.FINALISED' | translate}} {{'PLAN-OVERVIEW.FINALISED' | translate}}
</div> </div>
</div> </div>
</div> </div>
<div class="row" *ngIf="!lockStatus || canClonePlan() || (canDeletePlan() && !isLocked)"> <div class="row" *ngIf="!lockStatus || canClonePlan() || (canDeletePlan() && !isLocked)">
<div *ngIf="canEditPlan(dmp) && !lockStatus; else previewButton" class="col-auto pr-0"> <div *ngIf="canEditPlan(plan) && !lockStatus; else previewButton" class="col-auto pr-0">
<button (click)="editClicked()" mat-mini-fab class="d-flex justify-content-center align-items-center" matTooltip="{{'PLAN-OVERVIEW.ACTIONS.EDIT' | translate}}" matTooltipPosition="above"> <button (click)="editClicked()" mat-mini-fab class="d-flex justify-content-center align-items-center" matTooltip="{{'PLAN-OVERVIEW.ACTIONS.EDIT' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-mini-fab-icon">create</mat-icon> <mat-icon class="mat-mini-fab-icon">create</mat-icon>
</button> </button>
@ -74,9 +74,9 @@
</button> </button>
</div> </div>
</div> </div>
<ng-container *ngIf="referenceService.hasRerefenceOfTypes(dmp?.planReferences, [this.referenceTypeService.getGrantReferenceType()])"> <ng-container *ngIf="referenceService.hasRerefenceOfTypes(plan?.planReferences, [this.referenceTypeService.getGrantReferenceType()])">
<div class="row header"><div class="col-auto">{{'PLAN-OVERVIEW.GRANT' | translate}}</div></div> <div class="row header"><div class="col-auto">{{'PLAN-OVERVIEW.GRANT' | translate}}</div></div>
<div class="row dmp-label"><div class="col-auto">{{referenceService.getReferencesForTypesFirstSafe(dmp?.planReferences, [this.referenceTypeService.getGrantReferenceType()])?.reference?.label}}</div></div> <div class="row plan-label"><div class="col-auto">{{referenceService.getReferencesForTypesFirstSafe(plan?.planReferences, [this.referenceTypeService.getGrantReferenceType()])?.reference?.label}}</div></div>
</ng-container> </ng-container>
<div class="row header"><div class="col-auto">{{'DESCRIPTION-OVERVIEW.RESEARCHERS' | translate}}</div></div> <div class="row header"><div class="col-auto">{{'DESCRIPTION-OVERVIEW.RESEARCHERS' | translate}}</div></div>
<div class="row"> <div class="row">
@ -102,22 +102,22 @@
<div *ngIf="!researchers || researchers.length === 0" class="col-12"><span class="material-icons">horizontal_rule</span></div> <div *ngIf="!researchers || researchers.length === 0" class="col-12"><span class="material-icons">horizontal_rule</span></div>
</div> </div>
<div class="row header"><div class="col-12">{{'PLAN-OVERVIEW.DESCRIPTION' | translate}}</div></div> <div class="row header"><div class="col-12">{{'PLAN-OVERVIEW.DESCRIPTION' | translate}}</div></div>
<div class="row" *ngIf="dmp.description"> <div class="row" *ngIf="plan.description">
<div class="col-12"> <div class="col-12">
<p class="desc-txt" [innerHTML]="dmp.description"></p> <p class="desc-txt" [innerHTML]="plan.description"></p>
</div> </div>
</div> </div>
<div class="row" *ngIf="!dmp.description"> <div class="row" *ngIf="!plan.description">
<div class="col-12"> <div class="col-12">
<span class="material-icons">horizontal_rule</span> <span class="material-icons">horizontal_rule</span>
</div> </div>
</div> </div>
<div class="row header"><div class="col-12">{{'PLAN-OVERVIEW.DESCRIPTIONS' | translate}}</div></div> <div class="row header"><div class="col-12">{{'PLAN-OVERVIEW.DESCRIPTIONS' | translate}}</div></div>
<div class="row mb-4"> <div class="row mb-4">
<ng-container *ngFor="let description of dmp.descriptions"> <ng-container *ngFor="let description of plan.descriptions">
<div class="col-12 col-lg-7 mt-1"> <div class="col-12 col-lg-7 mt-1">
<a class="w-100 description" [routerLink]="isPublicView ? this.routerUtils.generateUrl(['/descriptions/overview/public/', description.id]) : this.routerUtils.generateUrl(['/descriptions/overview/' + description.id])" target="_blank"> <a class="w-100 description" [routerLink]="isPublicView ? this.routerUtils.generateUrl(['/descriptions/overview/public/', description.id]) : this.routerUtils.generateUrl(['/descriptions/overview/' + description.id])" target="_blank">
<button class="w-100" [ngClass]="{'dmp-btn': description.status === descriptionStatusEnum.Draft, 'dmp-finalized-btn': description.status === descriptionStatusEnum.Finalized}"> <button class="w-100" [ngClass]="{'plan-btn': description.status === descriptionStatusEnum.Draft, 'plan-finalized-btn': description.status === descriptionStatusEnum.Finalized}">
<div matTooltip="{{ description.label }}" class="d-flex align-items-center justify-content-between"> <div matTooltip="{{ description.label }}" class="d-flex align-items-center justify-content-between">
<div class="description-btn-label">{{ description.label }}</div> <div class="description-btn-label">{{ description.label }}</div>
<mat-icon>launch</mat-icon> <mat-icon>launch</mat-icon>
@ -126,19 +126,19 @@
</a> </a>
</div> </div>
</ng-container> </ng-container>
<div class="col-12" *ngIf="!dmp.descriptions || dmp.descriptions.length === 0"> <div class="col-12" *ngIf="!plan.descriptions || plan.descriptions.length === 0">
<span class="material-icons">horizontal_rule</span> <span class="material-icons">horizontal_rule</span>
</div> </div>
</div> </div>
</div> </div>
<div class="col-12 col-lg-4"> <div class="col-12 col-lg-4">
<ng-container *ngIf="!hasDoi(dmp)"> <ng-container *ngIf="!hasDoi(plan)">
<div class="row mb-3"> <div class="row mb-3">
<div class="col-auto"><span>{{'PLAN-OVERVIEW.DOI-PROVIDED' | translate}}: </span></div> <div class="col-auto"><span>{{'PLAN-OVERVIEW.DOI-PROVIDED' | translate}}: </span></div>
<ng-container *ngIf="selectedModel"> <ng-container *ngIf="selectedModel">
<div class="col"> <div class="col">
<mat-select class="select-repo" [placeholder]="selectedModel.repositoryId"> <mat-select class="select-repo" [placeholder]="selectedModel.repositoryId">
<mat-option *ngFor="let entityDoi of dmp.entityDois" (click)="selectDoi(entityDoi)"> <mat-option *ngFor="let entityDoi of plan.entityDois" (click)="selectDoi(entityDoi)">
{{entityDoi.repositoryId}} {{entityDoi.repositoryId}}
</mat-option> </mat-option>
</mat-select> </mat-select>
@ -147,7 +147,7 @@
</div> </div>
<div class="row align-items-center"> <div class="row align-items-center">
<div class="col-12"> <div class="col-12">
<ng-container *ngIf="dmp.entityDois && selectedModel"> <ng-container *ngIf="plan.entityDois && selectedModel">
<div class="container"> <div class="container">
<div class="row doi-panel mb-3 pt-4 pb-3"> <div class="row doi-panel mb-3 pt-4 pb-3">
<div class="col d-flex align-items-center"> <div class="col d-flex align-items-center">
@ -173,8 +173,8 @@
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<div class="frame mb-3 pt-4 pl-4 pr-5 pb-3"> <div class="frame mb-3 pt-4 pl-4 pr-5 pb-3">
<ng-container *ngIf="isDraftDmp() && canFinalizePlan() && !isLocked"> <ng-container *ngIf="isDraftPlan() && canFinalizePlan() && !isLocked">
<div class="row align-items-center" (click)="finalize(dmp)"> <div class="row align-items-center" (click)="finalize(plan)">
<div class="col-auto pr-0"> <div class="col-auto pr-0">
<button mat-mini-fab class="finalize-btn"> <button mat-mini-fab class="finalize-btn">
<mat-icon class="mat-mini-fab-icon">check</mat-icon> <mat-icon class="mat-mini-fab-icon">check</mat-icon>
@ -190,8 +190,8 @@
</div> </div>
</div> </div>
</ng-container> </ng-container>
<app-plan-deposit-dropdown *ngIf="(hasDoi(dmp) || moreDeposit()) && isFinalizedDmp(dmp) && !this.isPublicView && canDepositPlan(dmp) && inputRepos.length > 0" [inputRepos]="inputRepos" [dmp]="dmp" (outputReposEmitter)="afterDeposit($event)"></app-plan-deposit-dropdown> <app-plan-deposit-dropdown *ngIf="(hasDoi(plan) || moreDeposit()) && isFinalizedPlan(plan) && !this.isPublicView && canDepositPlan(plan) && inputRepos.length > 0" [inputRepos]="inputRepos" [plan]="plan" (outputReposEmitter)="afterDeposit($event)"></app-plan-deposit-dropdown>
<ng-container *ngIf="isFinalizedDmp(dmp) && hasDoi(dmp) && !isPublishedDmp(dmp) && canFinalizePlan(dmp)"> <ng-container *ngIf="isFinalizedPlan(plan) && hasDoi(plan) && !isPublishedPlan(plan) && canFinalizePlan(plan)">
<div (click)="reverseFinalization()" class="row mb-3 align-items-center"> <div (click)="reverseFinalization()" class="row mb-3 align-items-center">
<div class="col-auto pr-0"> <div class="col-auto pr-0">
<button mat-mini-fab class="frame-btn"> <button mat-mini-fab class="frame-btn">
@ -203,7 +203,7 @@
</div> </div>
</div> </div>
</ng-container> </ng-container>
<ng-container *ngIf="canExportPlan() && fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Dmp).length > 0"> <ng-container *ngIf="canExportPlan() && fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Plan).length > 0">
<div class="row mb-3 align-items-center"> <div class="row mb-3 align-items-center">
<div class="col-auto pr-0"> <div class="col-auto pr-0">
<button mat-mini-fab class="frame-btn" [matMenuTriggerFor]="exportMenu"> <button mat-mini-fab class="frame-btn" [matMenuTriggerFor]="exportMenu">
@ -215,7 +215,7 @@
</div> </div>
</div> </div>
</ng-container> </ng-container>
<!-- <ng-container *ngIf="canCreateNewVersion()"> <ng-container *ngIf="canCreateNewVersion()">
<div class="row mb-3 align-items-center" (click)="newVersionClicked()"> <div class="row mb-3 align-items-center" (click)="newVersionClicked()">
<div class="col-auto pr-0"> <div class="col-auto pr-0">
<button mat-mini-fab class="frame-btn"> <button mat-mini-fab class="frame-btn">
@ -226,9 +226,9 @@
<p class="mb-0 pl-2 frame-txt">{{ 'PLAN-OVERVIEW.ACTIONS.NEW-VERSION' | translate }}</p> <p class="mb-0 pl-2 frame-txt">{{ 'PLAN-OVERVIEW.ACTIONS.NEW-VERSION' | translate }}</p>
</div> </div>
</div> </div>
</ng-container> --> </ng-container>
<mat-menu #exportMenu="matMenu" xPosition="before"> <mat-menu #exportMenu="matMenu" xPosition="before">
<button mat-menu-item *ngFor='let fileTransformer of fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Dmp)' (click)="fileTransformerService.exportPlan(dmp.id, fileTransformer.repositoryId, fileTransformer.format)"> <button mat-menu-item *ngFor='let fileTransformer of fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Plan)' (click)="fileTransformerService.exportPlan(plan.id, fileTransformer.repositoryId, fileTransformer.format)">
<i class="fa pr-2" [ngClass]="fileTransformer.icon ? fileTransformer.icon : 'fa-file-o'"></i> <i class="fa pr-2" [ngClass]="fileTransformer.icon ? fileTransformer.icon : 'fa-file-o'"></i>
<span>{{'GENERAL.FILE-TRANSFORMER.' + fileTransformer?.format?.toUpperCase() | translate}}</span> <span>{{'GENERAL.FILE-TRANSFORMER.' + fileTransformer?.format?.toUpperCase() | translate}}</span>
</button> </button>
@ -244,7 +244,7 @@
<p class="header">{{ 'PLAN-OVERVIEW.PLAN-AUTHORS' | translate }}</p> <p class="header">{{ 'PLAN-OVERVIEW.PLAN-AUTHORS' | translate }}</p>
</div> </div>
<div class="col-12"> <div class="col-12">
<div *ngFor="let planUser of dmp.planUsers; let i=index;" class="row authors pt-1" [ngClass]="{'author-focused': authorFocus && isFocusedOnUser(planUser.user?.id, i)}" (mouseover)="focusOnAuthor(planUser.user?.id, i)" (mouseout)="resetAuthorFocus()"> <div *ngFor="let planUser of plan.planUsers; let i=index;" class="row authors pt-1" [ngClass]="{'author-focused': authorFocus && isFocusedOnUser(planUser.user?.id, i)}" (mouseover)="focusOnAuthor(planUser.user?.id, i)" (mouseout)="resetAuthorFocus()">
<div class="col-auto d-flex flex-row pr-0"> <div class="col-auto d-flex flex-row pr-0">
<button class="account_btn mr-3 pl-0"> <button class="account_btn mr-3 pl-0">
<mat-icon class="account-icon" [ngClass]="{'author-icon-focused': authorFocus && authorFocus == planUser.user?.id}">account_circle</mat-icon> <mat-icon class="account-icon" [ngClass]="{'author-icon-focused': authorFocus && authorFocus == planUser.user?.id}">account_circle</mat-icon>
@ -266,15 +266,15 @@
<span *ngIf="planUser.sectionId">{{ getSectionNameById(planUser.sectionId) }}</span> <span *ngIf="planUser.sectionId">{{ getSectionNameById(planUser.sectionId) }}</span>
</p> </p>
</div> </div>
<div *ngIf="canAssignPlanUsers(dmp) && dmp.status === planStatusEnum.Draft && planUser.role != planUserRoleEnum.Owner" class="col-auto"> <div *ngIf="canAssignPlanUsers(plan) && plan.status === planStatusEnum.Draft && planUser.role != planUserRoleEnum.Owner" class="col-auto">
<button (click)="removeUserFromDmp(planUser)" mat-mini-fab matTooltip="{{ 'PLAN-OVERVIEW.ACTIONS.REMOVE-AUTHOR' | translate}}" matTooltipPosition="above"> <button (click)="removeUserFromPlan(planUser)" mat-mini-fab matTooltip="{{ 'PLAN-OVERVIEW.ACTIONS.REMOVE-AUTHOR' | translate}}" matTooltipPosition="above">
<mat-icon class="mat-mini-fab-icon">delete</mat-icon> <mat-icon class="mat-mini-fab-icon">delete</mat-icon>
</button> </button>
</div> </div>
</div> </div>
</div> </div>
<div *ngIf="canInvitePlanUsers()" class="col-12 d-flex align-items-center justify-content-center mt-2"> <div *ngIf="canInvitePlanUsers()" class="col-12 d-flex align-items-center justify-content-center mt-2">
<button mat-raised-button class="invite-btn" (click)="openShareDialog(dmp.id,dmp.label)"> <button mat-raised-button class="invite-btn" (click)="openShareDialog(plan.id,plan.label)">
<mat-icon>group_add</mat-icon> <mat-icon>group_add</mat-icon>
{{'PLAN-OVERVIEW.ACTIONS.INVITE-SHORT' | translate}} {{'PLAN-OVERVIEW.ACTIONS.INVITE-SHORT' | translate}}
</button> </button>

View File

@ -123,7 +123,7 @@
// ********TEXT******** // ********TEXT********
.dmp-logo { .plan-logo {
padding: 10px; padding: 10px;
min-width: 4.8em; min-width: 4.8em;
height: 2.6em; height: 2.6em;
@ -147,7 +147,7 @@
font-weight: 400; font-weight: 400;
} }
.dmp-label { .plan-label {
font-weight: bold; font-weight: bold;
} }
@ -168,7 +168,7 @@
margin-bottom: 0.5em; margin-bottom: 0.5em;
} }
.dmp-label, .plan-label,
.header { .header {
font-size: 1.25em; font-size: 1.25em;
color: #212121; color: #212121;
@ -289,7 +289,7 @@
.mat-mini-fab, .mat-mini-fab,
.mat-mini-fab-icon, .mat-mini-fab-icon,
.status-icon, .status-icon,
.dmp-logo, .plan-logo,
.frame-btn, .frame-btn,
.finalize-btn { .finalize-btn {
display: flex; display: flex;
@ -331,7 +331,7 @@
border-bottom: 1px solid #212121; border-bottom: 1px solid #212121;
} }
.dmp-btn { .plan-btn {
min-height: 2.3em; min-height: 2.3em;
background-color: var(--secondary-color); background-color: var(--secondary-color);
border-radius: 4px; border-radius: 4px;
@ -340,7 +340,7 @@
border: none; border: none;
} }
.dmp-finalized-btn { .plan-finalized-btn {
min-height: 2.3em; min-height: 2.3em;
background-color: #b2f772; background-color: #b2f772;
border-radius: 4px; border-radius: 4px;

View File

@ -52,15 +52,15 @@ import { NewVersionPlanDialogComponent } from '../new-version-dialog/plan-new-ve
import { RouterUtilsService } from '@app/core/services/router/router-utils.service'; import { RouterUtilsService } from '@app/core/services/router/router-utils.service';
@Component({ @Component({
selector: 'app-dmp-overview', selector: 'app-plan-overview',
templateUrl: './plan-overview.component.html', templateUrl: './plan-overview.component.html',
styleUrls: ['./plan-overview.component.scss'] styleUrls: ['./plan-overview.component.scss']
}) })
export class PlanOverviewComponent extends BaseComponent implements OnInit { export class PlanOverviewComponent extends BaseComponent implements OnInit {
dmp: any; plan: any;
selectedBlueprint: PlanBlueprint; selectedBlueprint: PlanBlueprint;
selectedDmpVersion: any; selectedPlanVersion: any;
researchers: PlanReference[] = []; researchers: PlanReference[] = [];
isNew = true; isNew = true;
isFinalized = false; isFinalized = false;
@ -114,7 +114,7 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.analyticsService.trackPageView(AnalyticsService.PlanOverview); this.analyticsService.trackPageView(AnalyticsService.PlanOverview);
// Gets dmp data using parameter id // Gets plan data using parameter id
this.route.params this.route.params
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe((params: Params) => { .subscribe((params: Params) => {
@ -128,28 +128,28 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
.subscribe(data => { .subscribe(data => {
this.breadcrumbService.addIdResolvedValue(data.id?.toString(), data.label); this.breadcrumbService.addIdResolvedValue(data.id?.toString(), data.label);
this.dmp = data; this.plan = data;
this.dmp.planUsers = data.planUsers.filter(x => x.isActive === IsActive.Active); this.plan.planUsers = data.planUsers.filter(x => x.isActive === IsActive.Active);
this.dmp.otherPlanVersions = data.otherPlanVersions?.filter(x => x.isActive === IsActive.Active) || null; this.plan.otherPlanVersions = data.otherPlanVersions?.filter(x => x.isActive === IsActive.Active) || null;
if (this.dmp.descriptions) { if (this.plan.descriptions) {
if (this.dmp.status == PlanStatus.Finalized) { if (this.plan.status == PlanStatus.Finalized) {
this.dmp.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized); this.plan.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized);
} else { } else {
this.dmp.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatus.Canceled); this.plan.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatus.Canceled);
} }
} }
if (data.entityDois && data.entityDois.length > 0) this.dmp.entityDois = data.entityDois.filter(x => x.isActive === IsActive.Active); if (data.entityDois && data.entityDois.length > 0) this.plan.entityDois = data.entityDois.filter(x => x.isActive === IsActive.Active);
this.selectedBlueprint = data.blueprint; this.selectedBlueprint = data.blueprint;
this.researchers = this.referenceService.getReferencesForTypes(this.dmp?.planReferences, [this.referenceTypeService.getResearcherReferenceType()]); this.researchers = this.referenceService.getReferencesForTypes(this.plan?.planReferences, [this.referenceTypeService.getResearcherReferenceType()]);
if (!this.hasDoi()) { if (!this.hasDoi()) {
this.selectedModel = this.dmp.entityDois[0]; this.selectedModel = this.plan.entityDois[0];
} }
this.selectedDmpVersion = this.dmp; this.selectedPlanVersion = this.plan;
this.checkLockStatus(this.dmp.id); this.checkLockStatus(this.plan.id);
// this.setIsUserOwner(); // this.setIsUserOwner();
// const breadCrumbs = []; // const breadCrumbs = [];
// breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-PLANS'), url: "/plans" }); // breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-PLANS'), url: "/plans" });
// breadCrumbs.push({ parentComponentName: 'PlanListingComponent', label: this.dmp.label, url: '/plans/overview/' + this.dmp.id }); // breadCrumbs.push({ parentComponentName: 'PlanListingComponent', label: this.plan.label, url: '/plans/overview/' + this.plan.id });
// this.breadCrumbs = observableOf(breadCrumbs); // this.breadCrumbs = observableOf(breadCrumbs);
}, (error: any) => { }, (error: any) => {
this.httpErrorHandlingService.handleBackedRequestError(error); this.httpErrorHandlingService.handleBackedRequestError(error);
@ -172,12 +172,12 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
this.breadcrumbService.addExcludedParam('public', true); this.breadcrumbService.addExcludedParam('public', true);
this.breadcrumbService.addIdResolvedValue(data.id?.toString(), data.label); this.breadcrumbService.addIdResolvedValue(data.id?.toString(), data.label);
this.dmp = data; this.plan = data;
this.researchers = this.referenceService.getReferencesForTypes(this.dmp?.planReferences, [this.referenceTypeService.getResearcherReferenceType()]); this.researchers = this.referenceService.getReferencesForTypes(this.plan?.planReferences, [this.referenceTypeService.getResearcherReferenceType()]);
if (!this.hasDoi()) { if (!this.hasDoi()) {
this.selectedModel = this.dmp.entityDois[0]; this.selectedModel = this.plan.entityDois[0];
} }
this.selectedDmpVersion = this.dmp; this.selectedPlanVersion = this.plan;
}, (error: any) => { }, (error: any) => {
this.httpErrorHandlingService.handleBackedRequestError(error); this.httpErrorHandlingService.handleBackedRequestError(error);
@ -235,57 +235,57 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
} else return false; } else return false;
} }
focusOnAuthor(dmpUserId: Guid, order: number): void { focusOnAuthor(planUserId: Guid, order: number): void {
this.authorFocus = `${dmpUserId}-${order}`; this.authorFocus = `${planUserId}-${order}`;
} }
resetAuthorFocus(): void { resetAuthorFocus(): void {
this.authorFocus = null; this.authorFocus = null;
} }
isFocusedOnUser(dmpUserId: Guid, order: number): boolean { isFocusedOnUser(planUserId: Guid, order: number): boolean {
return `${dmpUserId}-${order}` == this.authorFocus; return `${planUserId}-${order}` == this.authorFocus;
} }
canEditPlan(): boolean { canEditPlan(): boolean {
return (this.isDraftDmp()) && (this.dmp.authorizationFlags?.some(x => x === AppPermission.EditPlan) || this.authentication.hasPermission(AppPermission.EditPlan)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.isDraftPlan()) && (this.plan.authorizationFlags?.some(x => x === AppPermission.EditPlan) || this.authentication.hasPermission(AppPermission.EditPlan)) && this.isPublicView == false && this.plan.belongsToCurrentTenant != false;
} }
canCreateNewVersion(): boolean { canCreateNewVersion(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.CreateNewVersionPlan) || this.authentication.hasPermission(AppPermission.CreateNewVersionPlan)) && this.dmp.versionStatus === PlanVersionStatus.Current && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.CreateNewVersionPlan) || this.authentication.hasPermission(AppPermission.CreateNewVersionPlan)) && this.plan.versionStatus === PlanVersionStatus.Current && this.isPublicView == false && this.plan.belongsToCurrentTenant != false;
} }
canDeletePlan(): boolean { canDeletePlan(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.DeletePlan) || this.authentication.hasPermission(AppPermission.DeletePlan)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.DeletePlan) || this.authentication.hasPermission(AppPermission.DeletePlan)) && this.isPublicView == false && this.plan.belongsToCurrentTenant != false;
} }
canClonePlan(): boolean { canClonePlan(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.ClonePlan) || this.authentication.hasPermission(AppPermission.ClonePlan)); return (this.plan.authorizationFlags?.some(x => x === AppPermission.ClonePlan) || this.authentication.hasPermission(AppPermission.ClonePlan));
} }
canFinalizePlan(): boolean { canFinalizePlan(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.FinalizePlan) || this.authentication.hasPermission(AppPermission.FinalizePlan)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.FinalizePlan) || this.authentication.hasPermission(AppPermission.FinalizePlan)) && this.isPublicView == false && this.plan.belongsToCurrentTenant != false;
} }
canExportPlan(): boolean { canExportPlan(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.ExportPlan) || this.authentication.hasPermission(AppPermission.ExportPlan)); return (this.plan.authorizationFlags?.some(x => x === AppPermission.ExportPlan) || this.authentication.hasPermission(AppPermission.ExportPlan));
} }
canInvitePlanUsers(): boolean { canInvitePlanUsers(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.InvitePlanUsers) || this.authentication.hasPermission(AppPermission.InvitePlanUsers)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.InvitePlanUsers) || this.authentication.hasPermission(AppPermission.InvitePlanUsers)) && this.isPublicView == false && this.plan.belongsToCurrentTenant != false;
} }
canAssignPlanUsers(): boolean { canAssignPlanUsers(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.AssignPlanUsers) || this.authentication.hasPermission(AppPermission.AssignPlanUsers)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.AssignPlanUsers) || this.authentication.hasPermission(AppPermission.AssignPlanUsers)) && this.isPublicView == false && this.plan.belongsToCurrentTenant != false;
} }
canDepositPlan(): boolean { canDepositPlan(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.DepositPlan) || this.authentication.hasPermission(AppPermission.DepositPlan)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.plan.authorizationFlags?.some(x => x === AppPermission.DepositPlan) || this.authentication.hasPermission(AppPermission.DepositPlan)) && this.isPublicView == false && this.plan.belongsToCurrentTenant != false;
} }
editClicked() { editClicked() {
this.router.navigate([this.routerUtils.generateUrl(['/plans/edit', this.dmp.id], '/')]); this.router.navigate([this.routerUtils.generateUrl(['/plans/edit', this.plan.id], '/')]);
} }
cloneClicked() { cloneClicked() {
@ -293,7 +293,7 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
maxWidth: '700px', maxWidth: '700px',
maxHeight: '80vh', maxHeight: '80vh',
data: { data: {
plan: this.dmp plan: this.plan
} }
}); });
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: Plan) => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: Plan) => {
@ -309,7 +309,7 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
maxWidth: '700px', maxWidth: '700px',
maxHeight: '80vh', maxHeight: '80vh',
data: { data: {
plan: this.dmp plan: this.plan
} }
}); });
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: Plan) => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: Plan) => {
@ -322,11 +322,11 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
deleteClicked() { deleteClicked() {
let dialogRef: any; let dialogRef: any;
if (this.dmp.descriptions && this.dmp.descriptions.length > 0) { if (this.plan.descriptions && this.plan.descriptions.length > 0) {
dialogRef = this.dialog.open(PlanDeleteDialogComponent, { dialogRef = this.dialog.open(PlanDeleteDialogComponent, {
maxWidth: '300px', maxWidth: '300px',
data: { data: {
descriptions: this.dmp.descriptions, descriptions: this.plan.descriptions,
} }
}); });
} else { } else {
@ -343,7 +343,7 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) { if (result) {
this.planService.delete(this.dmp.id) this.planService.delete(this.plan.id)
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe( .subscribe(
complete => { this.onDeleteCallbackSuccess() }, complete => { this.onDeleteCallbackSuccess() },
@ -371,40 +371,40 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
this.httpErrorHandlingService.handleBackedRequestError(error); this.httpErrorHandlingService.handleBackedRequestError(error);
} }
isUserDmpRelated(): boolean { isUserPlanRelated(): boolean {
const principalId: Guid = this.authentication.userId(); const principalId: Guid = this.authentication.userId();
return this.dmp.planUsers?.some(x => (x.user.id === principalId)); return this.plan.planUsers?.some(x => (x.user.id === principalId));
} }
isDraftDmp() { isDraftPlan() {
return this.dmp.status == PlanStatus.Draft; return this.plan.status == PlanStatus.Draft;
} }
isFinalizedDmp(dmp: Plan) { isFinalizedPlan(plan: Plan) {
return dmp.status == PlanStatus.Finalized; return plan.status == PlanStatus.Finalized;
} }
isPublishedDmp() { isPublishedPlan() {
return (this.dmp.status == PlanStatus.Finalized && this.dmp.accessType === PlanAccessType.Public); return (this.plan.status == PlanStatus.Finalized && this.plan.accessType === PlanAccessType.Public);
} }
hasDoi() { hasDoi() {
return (this.dmp.entityDois == null || this.dmp.entityDois.length == 0); return (this.plan.entityDois == null || this.plan.entityDois.length == 0);
} }
afterDeposit(result: EntityDoi[]) { afterDeposit(result: EntityDoi[]) {
if (result.length > 0) { if (result.length > 0) {
this.dmp.entityDois = result; this.plan.entityDois = result;
this.selectedModel = this.dmp.entityDois[this.dmp.entityDois.length - 1]; this.selectedModel = this.plan.entityDois[this.plan.entityDois.length - 1];
} }
} }
get inputRepos() { get inputRepos() {
return this.depositRepos.filter(repo => !this.dmp.entityDois?.find(doi => doi.repositoryId === repo.repositoryId)); return this.depositRepos.filter(repo => !this.plan.entityDois?.find(doi => doi.repositoryId === repo.repositoryId));
} }
moreDeposit() { moreDeposit() {
return (this.dmp.entityDois.length < this.depositRepos.length); return (this.plan.entityDois.length < this.depositRepos.length);
} }
finalize() { finalize() {
@ -413,13 +413,13 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
restoreFocus: false, restoreFocus: false,
autoFocus: false, autoFocus: false,
data: { data: {
plan: this.dmp plan: this.plan
} }
}); });
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: PlanFinalizeDialogOutput) => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: PlanFinalizeDialogOutput) => {
if (result && !result.cancelled) { if (result && !result.cancelled) {
this.planService.finalize(this.dmp.id, result.descriptionsToBeFinalized) this.planService.finalize(this.plan.id, result.descriptionsToBeFinalized)
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(data => { .subscribe(data => {
this.reloadPage(); this.reloadPage();
@ -452,7 +452,7 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
restoreFocus: false, restoreFocus: false,
data: { data: {
planId: rowId, planId: rowId,
dmpName: rowName, planName: rowName,
blueprint: this.selectedBlueprint blueprint: this.selectedBlueprint
} }
}); });
@ -460,9 +460,9 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
selectDoi(entityDoi: EntityDoi) { selectDoi(entityDoi: EntityDoi) {
this.selectedModel = entityDoi; this.selectedModel = entityDoi;
const foundIdx = this.dmp.entityDois.findIndex(el => el.id == entityDoi.id); const foundIdx = this.plan.entityDois.findIndex(el => el.id == entityDoi.id);
this.dmp.entityDois.splice(foundIdx, 1); this.plan.entityDois.splice(foundIdx, 1);
this.dmp.entityDois.unshift(entityDoi); this.plan.entityDois.unshift(entityDoi);
} }
createDoiLink(doiModel: any): string { createDoiLink(doiModel: any): string {
@ -488,7 +488,7 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
}); });
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) { if (result) {
this.planService.undoFinalize(this.dmp.id, PlanEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed)) this.planService.undoFinalize(this.plan.id, PlanEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed))
.subscribe(data => { .subscribe(data => {
this.reloadPage(); this.reloadPage();
this.onUpdateCallbackSuccess() this.onUpdateCallbackSuccess()
@ -510,7 +510,7 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
}); });
} }
removeUserFromDmp(dmpUser: PlanUser) { removeUserFromPlan(planUser: PlanUser) {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, { const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
data: { data: {
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-USER'), message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-USER'),
@ -521,12 +521,12 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
}); });
dialogRef.afterClosed().subscribe(result => { dialogRef.afterClosed().subscribe(result => {
if (result) { if (result) {
const dmpUserRemovePersist: PlanUserRemovePersist = { const planUserRemovePersist: PlanUserRemovePersist = {
id: dmpUser.id, id: planUser.id,
planId: this.dmp.id, planId: this.plan.id,
role: dmpUser.role role: planUser.role
}; };
this.planService.removeUser(dmpUserRemovePersist).pipe(takeUntil(this._destroyed)) this.planService.removeUser(planUserRemovePersist).pipe(takeUntil(this._destroyed))
.subscribe(data => { .subscribe(data => {
this.reloadPage(); this.reloadPage();
this.onUpdateCallbackSuccess() this.onUpdateCallbackSuccess()
@ -566,7 +566,7 @@ export class PlanOverviewComponent extends BaseComponent implements OnInit {
getSectionNameById(sectionId: Guid): string { getSectionNameById(sectionId: Guid): string {
if (sectionId == null) return ''; if (sectionId == null) return '';
let sections: PlanBlueprintDefinitionSection[] = this.dmp?.blueprint?.definition?.sections?.filter((section: PlanBlueprintDefinitionSection) => sectionId === section.id); let sections: PlanBlueprintDefinitionSection[] = this.plan?.blueprint?.definition?.sections?.filter((section: PlanBlueprintDefinitionSection) => sectionId === section.id);
return sections == null ? '' : sections[0].label; return sections == null ? '' : sections[0].label;
} }

View File

@ -1,4 +1,4 @@
<div class="dmp-contact-prefill-dialog"> <div class="plan-contact-prefill-dialog">
<div class="row mt-3"> <div class="row mt-3">
<div mat-dialog-title *ngIf="label"> <div mat-dialog-title *ngIf="label">
<span class="mr-3 title">{{'PLAN-CONTACT-PREFILL-DIALOG.TITLE' | translate}}{{label}}</span> <span class="mr-3 title">{{'PLAN-CONTACT-PREFILL-DIALOG.TITLE' | translate}}{{label}}</span>
@ -13,7 +13,7 @@
<div class="col-12 col-xl mt-3"> <div class="col-12 col-xl mt-3">
<mat-form-field class="w-100"> <mat-form-field class="w-100">
<mat-label>{{'PLAN-CONTACT-PREFILL-DIALOG.FIELDS.USER' | translate}}</mat-label> <mat-label>{{'PLAN-CONTACT-PREFILL-DIALOG.FIELDS.USER' | translate}}</mat-label>
<app-single-auto-complete [formControl]="formGroup" [configuration]="singleAutoCompleteDmpAssociatedUserConfiguration"></app-single-auto-complete> <app-single-auto-complete [formControl]="formGroup" [configuration]="singleAutoCompletePlanAssociatedUserConfiguration"></app-single-auto-complete>
</mat-form-field> </mat-form-field>
</div> </div>
<div class="row" style="justify-content: space-between;"> <div class="row" style="justify-content: space-between;">

View File

@ -1,4 +1,4 @@
.dmp-contact-prefill-dialog { .plan-contact-prefill-dialog {
padding: 24px; padding: 24px;
overflow: hidden; overflow: hidden;

Some files were not shown because too many files have changed in this diff Show More