diff --git a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java index c8ad61c07..1c451b6d2 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java +++ b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java @@ -40,6 +40,7 @@ public class AuditableAction { public static final EventId Dmp_Invite_Users = new EventId(5008, "Dmp_Invite_Users"); public static final EventId Dmp_Invite_Accept = new EventId(5009, "Dmp_Invite_Accept"); public static final EventId Dmp_PublicQuery = new EventId(5010, "Dmp_PublicQuery"); + public static final EventId Dmp_PublicLookup = new EventId(5011, "Dmp_PublicLookup"); public static final EventId Description_Query = new EventId(6000, "Description_Query"); public static final EventId Description_Lookup = new EventId(6001, "Description_Lookup"); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/PublicDescription.java b/dmp-backend/core/src/main/java/eu/eudat/model/PublicDescription.java index ec332e564..fdbdbba82 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/PublicDescription.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/PublicDescription.java @@ -43,6 +43,10 @@ public class PublicDescription { public static final String _descriptionTemplate = "descriptionTemplate"; + private PublicDmp dmp; + + public static final String _dmp = "dmp"; + public UUID getId() { return id; @@ -116,4 +120,12 @@ public class PublicDescription { public void setDescriptionTemplate(PublicDescriptionTemplate descriptionTemplate) { this.descriptionTemplate = descriptionTemplate; } + + public PublicDmp getDmp() { + return dmp; + } + + public void setDmp(PublicDmp dmp) { + this.dmp = dmp; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/PublicDmp.java b/dmp-backend/core/src/main/java/eu/eudat/model/PublicDmp.java index 5a4e5f3f0..a23903658 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/PublicDmp.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/PublicDmp.java @@ -26,6 +26,9 @@ public class PublicDmp { public static final String _description = "description"; + private Instant updatedAt; + public static final String _updatedAt = "updatedAt"; + private Instant finalizedAt; public static final String _finalizedAt = "finalizedAt"; @@ -36,11 +39,14 @@ public class PublicDmp { private List users; - public static final String _users = "users"; + public static final String _dmpUsers = "dmpUsers"; private List dmpReferences; - public static final String _dmpReferences = "_dmpReferences"; + public static final String _dmpReferences = "dmpReferences"; + + private List descriptions; + public static final String _descriptions = "descriptions"; public UUID getId() { return id; @@ -74,6 +80,14 @@ public class PublicDmp { this.description = description; } + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + public Instant getFinalizedAt() { return finalizedAt; } @@ -105,4 +119,12 @@ public class PublicDmp { public void setDmpReferences(List dmpReferences) { this.dmpReferences = dmpReferences; } + + public List getDescriptions() { + return descriptions; + } + + public void setDescriptions(List descriptions) { + this.descriptions = descriptions; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpUserBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpUserBuilder.java index 8f08d51ae..e1942e173 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpUserBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpUserBuilder.java @@ -67,6 +67,7 @@ public class DmpUserBuilder extends BaseBuilder{ if (fields.hasField(this.asIndexer(DmpUser._sectionId))) m.setSectionId(d.getSectionId()); if (fields.hasField(this.asIndexer(DmpUser._createdAt))) m.setCreatedAt(d.getCreatedAt()); if (fields.hasField(this.asIndexer(DmpUser._updatedAt))) m.setUpdatedAt(d.getUpdatedAt()); + if (fields.hasField(this.asIndexer(DmpUser._isActive))) m.setIsActive(d.getIsActive()); if (fields.hasField(this.asIndexer(DmpReference._hash))) m.setHash(this.hashValue(d.getUpdatedAt())); if (!userFields.isEmpty() && userItemsMap != null && userItemsMap.containsKey(d.getUserId())) m.setUser(userItemsMap.get(d.getUserId())); if (!dmpFields.isEmpty() && dmpItemsMap != null && dmpItemsMap.containsKey(d.getDmpId())) m.setDmp(dmpItemsMap.get(d.getDmpId())); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDescriptionBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDescriptionBuilder.java index 1c9b33d22..7d8a3bd9d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDescriptionBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDescriptionBuilder.java @@ -6,6 +6,7 @@ import eu.eudat.data.DescriptionEntity; import eu.eudat.model.*; import eu.eudat.query.DescriptionTemplateQuery; import eu.eudat.query.DmpDescriptionTemplateQuery; +import eu.eudat.query.DmpQuery; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyApplicationException; @@ -56,9 +57,12 @@ public class PublicDescriptionBuilder extends BaseBuilder dmpDescriptionTemplateItemsMap = this.collectDmpDescriptionTemplates(dmpDescriptionTemplateFields, data); - FieldSet descriptionTemplateFields = fields.extractPrefixed(this.asPrefix(Description._descriptionTemplate)); + FieldSet descriptionTemplateFields = fields.extractPrefixed(this.asPrefix(PublicDescription._descriptionTemplate)); Map descriptionTemplateItemsMap = this.collectDescriptionTemplates(descriptionTemplateFields, data); + FieldSet dmpFields = fields.extractPrefixed(this.asPrefix(PublicDescription._dmp)); + Map dmpItemsMap = this.collectDmps(dmpFields, data); + List models = new ArrayList<>(); for (DescriptionEntity d : data) { PublicDescription m = new PublicDescription(); @@ -69,6 +73,7 @@ public class PublicDescriptionBuilder extends BaseBuilder collectDmps(FieldSet fields, List data) throws MyApplicationException { + if (fields.isEmpty() || data.isEmpty()) + return null; + this.logger.debug("checking related - {}", PublicDmp.class.getSimpleName()); + + Map itemMap; + if (!fields.hasOtherField(this.asIndexer(PublicDmp._id))) { + itemMap = this.asEmpty( + data.stream().map(DescriptionEntity::getDmpId).distinct().collect(Collectors.toList()), + x -> { + PublicDmp item = new PublicDmp(); + item.setId(x); + return item; + }, + PublicDmp::getId); + } else { + FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(PublicDmp._id); + DmpQuery q = this.queryFactory.query(DmpQuery.class).authorize(this.authorize).ids(data.stream().map(DescriptionEntity::getDmpId).distinct().collect(Collectors.toList())); + itemMap = this.builderFactory.builder(PublicDmpBuilder.class).authorize(this.authorize).asForeignKey(q, clone, PublicDmp::getId); + } + if (!fields.hasField(PublicDmp._id)) { + itemMap.forEach((id, item) -> { + if (item != null) + item.setId(null); + }); + } + + return itemMap; + } + } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpBuilder.java index 039939be9..b07921a91 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpBuilder.java @@ -1,11 +1,13 @@ package eu.eudat.model.builder; import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.enums.IsActive; import eu.eudat.convention.ConventionService; import eu.eudat.data.DmpEntity; -import eu.eudat.model.PublicDmp; -import eu.eudat.model.PublicDmpReference; +import eu.eudat.model.*; +import eu.eudat.query.DescriptionQuery; import eu.eudat.query.DmpReferenceQuery; +import eu.eudat.query.DmpUserQuery; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyApplicationException; @@ -58,6 +60,12 @@ public class PublicDmpBuilder extends BaseBuilder { FieldSet dmpReferencesFields = fields.extractPrefixed(this.asPrefix(PublicDmp._dmpReferences)); Map> dmpReferenceMap = this.collectDmpReferences(dmpReferencesFields, data); + FieldSet dmpUsersFields = fields.extractPrefixed(this.asPrefix(PublicDmp._dmpUsers)); + Map> dmpUsersMap = this.collectDmpUsers(dmpUsersFields, data); + + FieldSet descriptionsFields = fields.extractPrefixed(this.asPrefix(PublicDmp._descriptions)); + Map> descriptionsMap = this.collectDmpDescriptions(descriptionsFields, data); + for (DmpEntity d : data) { PublicDmp m = new PublicDmp(); if (fields.hasField(this.asIndexer(PublicDmp._id))) m.setId(d.getId()); @@ -65,8 +73,11 @@ public class PublicDmpBuilder extends BaseBuilder { if (fields.hasField(this.asIndexer(PublicDmp._version))) m.setVersion(d.getVersion()); if (fields.hasField(this.asIndexer(PublicDmp._description))) m.setDescription(d.getDescription()); if (fields.hasField(this.asIndexer(PublicDmp._finalizedAt))) m.setFinalizedAt(d.getFinalizedAt()); + if (fields.hasField(this.asIndexer(PublicDmp._updatedAt))) m.setUpdatedAt(d.getUpdatedAt()); if (dmpReferenceMap != null && !dmpReferenceMap.isEmpty() && dmpReferenceMap.containsKey(d.getId())) m.setDmpReferences(dmpReferenceMap.get(d.getId())); + if (dmpUsersMap != null && !dmpUsersMap.isEmpty() && dmpUsersMap.containsKey(d.getId())) m.setUsers(dmpUsersMap.get(d.getId())); + if (descriptionsMap != null && !descriptionsMap.isEmpty() && descriptionsMap.containsKey(d.getId())) m.setDescriptions(descriptionsMap.get(d.getId())); models.add(m); } @@ -93,4 +104,40 @@ public class PublicDmpBuilder extends BaseBuilder { return itemMap; } + private Map> collectDmpUsers(FieldSet fields, List data) throws MyApplicationException { + if (fields.isEmpty() || data.isEmpty()) return null; + this.logger.debug("checking related - {}", PublicDmpUser.class.getSimpleName()); + + Map> itemMap = null; + FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(this.asIndexer(PublicDmpUser._user, PublicDmp._id)); + DmpUserQuery query = this.queryFactory.query(DmpUserQuery.class).authorize(this.authorize).dmpIds(data.stream().map(DmpEntity::getId).distinct().collect(Collectors.toList())); + itemMap = this.builderFactory.builder(PublicDmpUserBuilder.class).authorize(this.authorize).asMasterKey(query, clone, x -> x.getDmp().getId()); + + if (!fields.hasField(this.asIndexer(PublicDmpUser._dmp, PublicDmp._id))) { + itemMap.values().stream().flatMap(List::stream).filter(x -> x != null && x.getDmp() != null).peek(x -> { + x.getDmp().setId(null); + }); + } + + return itemMap; + } + + private Map> collectDmpDescriptions(FieldSet fields, List data) throws MyApplicationException { + if (fields.isEmpty() || data.isEmpty()) return null; + this.logger.debug("checking related - {}", PublicDescription.class.getSimpleName()); + + Map> itemMap; + FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(this.asIndexer(PublicDescription._dmp, PublicDescription._id)); + DescriptionQuery query = this.queryFactory.query(DescriptionQuery.class).authorize(this.authorize).dmpIds(data.stream().map(DmpEntity::getId).distinct().collect(Collectors.toList())); + itemMap = this.builderFactory.builder(PublicDescriptionBuilder.class).authorize(this.authorize).asMasterKey(query, clone, x -> x.getDmp().getId()); + + if (!fields.hasField(this.asIndexer(PublicDescription._dmp, PublicDescription._id))) { + itemMap.values().stream().flatMap(List::stream).filter(x -> x != null && x.getDmp() != null).peek(x -> { + x.getDmp().setId(null); + }); + } + + return itemMap; + } + } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpUserBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpUserBuilder.java index b788b468d..ff6caced0 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpUserBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpUserBuilder.java @@ -81,7 +81,7 @@ public class PublicDmpUserBuilder extends BaseBuilder itemMap; - if (!fields.hasOtherField(this.asIndexer(User._id))) { + if (!fields.hasOtherField(this.asIndexer(PublicUser._id))) { itemMap = this.asEmpty( data.stream().map(DmpUserEntity::getUserId).distinct().collect(Collectors.toList()), x -> { @@ -91,11 +91,11 @@ public class PublicDmpUserBuilder extends BaseBuilder { if (item != null) item.setId(null); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicUserBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicUserBuilder.java index afabc7313..6aa1f0f89 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicUserBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicUserBuilder.java @@ -45,8 +45,8 @@ public class PublicUserBuilder extends BaseBuilder { for (UserEntity d : data) { PublicUser m = new PublicUser(); - if (fields.hasField(this.asIndexer(User._id))) m.setId(d.getId()); - if (fields.hasField(this.asIndexer(User._name))) m.setName(d.getName()); + if (fields.hasField(this.asIndexer(PublicUser._id))) m.setId(d.getId()); + if (fields.hasField(this.asIndexer(PublicUser._name))) m.setName(d.getName()); models.add(m); } this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/PublicDmpCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/PublicDmpCensor.java index e2789271e..f6d15495f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/PublicDmpCensor.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/PublicDmpCensor.java @@ -40,7 +40,7 @@ public class PublicDmpCensor extends BaseCensor { this.authService.authorizeForce(Permission.PublicBrowseDmp); - FieldSet dmpDescriptionsFields = fields.extractPrefixed(this.asIndexerPrefix(PublicDmp._users)); + FieldSet dmpDescriptionsFields = fields.extractPrefixed(this.asIndexerPrefix(PublicDmp._dmpUsers)); this.censorFactory.censor(PublicDmpUserCensor.class).censor(dmpDescriptionsFields); FieldSet dmpReferencesFields = fields.extractPrefixed(this.asIndexerPrefix(PublicDmp._dmpReferences)); this.censorFactory.censor(PublicDmpReferenceCensor.class).censor(dmpReferencesFields); diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DmpUserQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DmpUserQuery.java index afce0e19c..da63138e4 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DmpUserQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DmpUserQuery.java @@ -241,6 +241,7 @@ public class DmpUserQuery extends QueryBase { item.setRole(QueryBase.convertSafe(tuple, columns, DmpUserEntity._role, DmpUserRole.class)); item.setCreatedAt(QueryBase.convertSafe(tuple, columns, DmpUserEntity._createdAt, Instant.class)); item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, DmpUserEntity._updatedAt, Instant.class)); + item.setIsActive(QueryBase.convertSafe(tuple, columns, DmpUserEntity._isActive, IsActive.class)); return item; } @@ -253,6 +254,7 @@ public class DmpUserQuery extends QueryBase { else if (item.match(DmpUser._sectionId)) return DmpUserEntity._sectionId; else if (item.match(DmpUser._createdAt)) return DmpUserEntity._createdAt; else if (item.match(DmpUser._updatedAt)) return DmpUserEntity._updatedAt; + else if (item.match(DmpUser._isActive)) return DmpUserEntity._isActive; else if (item.match(DmpUser._hash)) return DmpUserEntity._updatedAt; else return null; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java index dee5c6a60..def9f8801 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java @@ -212,7 +212,7 @@ public class UserQuery extends QueryBase { else throw new MyNotFoundException("Only user scoped allowed"); Subquery dmpUserDmpQuery = queryUtilsService.buildSubQuery(new BuildSubQueryInput<>( - new BuildSubQueryInput.Builder<>(DmpUserQuery.class, UUID.class, queryContext) + new BuildSubQueryInput.Builder<>(DmpUserEntity.class, UUID.class, queryContext) .keyPathFunc((subQueryRoot) -> subQueryRoot.get(DmpUserEntity._dmpId)) .filterFunc((subQueryRoot, cb) -> cb.and( cb.equal(subQueryRoot.get(DmpUserEntity._userId), userId), @@ -221,7 +221,7 @@ public class UserQuery extends QueryBase { )); Subquery dmpUserUserQuery = queryUtilsService.buildSubQuery(new BuildSubQueryInput<>( - new BuildSubQueryInput.Builder<>(DmpUserQuery.class, UUID.class, queryContext) + new BuildSubQueryInput.Builder<>(DmpUserEntity.class, UUID.class, queryContext) .keyPathFunc((subQueryRoot) -> subQueryRoot.get(DmpUserEntity._userId)) .filterFunc((subQueryRoot, cb) -> cb.and( cb.in(subQueryRoot.get(DmpUserEntity._dmpId)).value(dmpUserDmpQuery) , diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java index 63a9f01bc..f00690ed6 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java @@ -482,7 +482,7 @@ public class DmpServiceImpl implements DmpService { updatedCreatedIds.add(dmpUserEntity.getUserId()); } - List toDelete = existingUsers.stream().filter(x-> updatedCreatedIds.stream().noneMatch(y-> y.equals(x.getId()))).collect(Collectors.toList()); + List toDelete = existingUsers.stream().filter(x-> updatedCreatedIds.stream().noneMatch(y-> y.equals(x.getUserId()))).collect(Collectors.toList()); if (!toDelete.isEmpty()) this.deleterFactory.deleter(DmpUserDeleter.class).delete(toDelete); this.entityManager.flush(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java index 3ce020832..49853397f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionController.java @@ -10,6 +10,7 @@ import eu.eudat.commons.enums.StorageType; import eu.eudat.convention.ConventionService; import eu.eudat.data.StorageFileEntity; import eu.eudat.model.StorageFile; +import eu.eudat.model.builder.PublicDescriptionBuilder; import eu.eudat.model.persist.DescriptionFieldFilePersist; import eu.eudat.model.persist.StorageFilePersist; import eu.eudat.service.storage.StorageFileService; @@ -100,7 +101,7 @@ public class DescriptionController { @PostMapping("public/query") public QueryResult publicQuery(@RequestBody DescriptionLookup lookup) throws MyApplicationException, MyForbiddenException { - logger.debug("querying {}", Description.class.getSimpleName()); + logger.debug("querying {}", PublicDescription.class.getSimpleName()); this.censorFactory.censor(PublicDescriptionCensor.class).censor(lookup.getProject()); @@ -113,14 +114,14 @@ public class DescriptionController { } @GetMapping("public/{id}") - public Description publicGet(@PathVariable("id") UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException { - logger.debug(new MapLogEntry("retrieving" + Description.class.getSimpleName()).And("id", id).And("fields", fieldSet)); + public PublicDescription publicGet(@PathVariable("id") UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException { + logger.debug(new MapLogEntry("retrieving" + PublicDescription.class.getSimpleName()).And("id", id).And("fields", fieldSet)); this.censorFactory.censor(PublicDescriptionCensor.class).censor(fieldSet); DescriptionQuery query = this.queryFactory.query(DescriptionQuery.class).authorize(EnumSet.of(Public)).ids(id).dmpSubQuery(this.queryFactory.query(DmpQuery.class).isActive(IsActive.Active).statuses(DmpStatus.Finalized).accessTypes(DmpAccessType.Public)); - Description model = this.builderFactory.builder(DescriptionBuilder.class).authorize(EnumSet.of(Public)).build(fieldSet, query.firstAs(fieldSet)); + PublicDescription model = this.builderFactory.builder(PublicDescriptionBuilder.class).authorize(EnumSet.of(Public)).build(fieldSet, query.firstAs(fieldSet)); if (model == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale())); this.auditService.track(AuditableAction.Description_PublicLookup, Map.ofEntries( diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java index c3e2ad149..51e07615d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java @@ -2,6 +2,14 @@ package eu.eudat.controllers; import eu.eudat.audit.AuditableAction; import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.enums.DmpAccessType; +import eu.eudat.commons.enums.DmpStatus; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.model.builder.DescriptionBuilder; +import eu.eudat.model.builder.PublicDmpBuilder; +import eu.eudat.model.censorship.PublicDescriptionCensor; +import eu.eudat.query.DescriptionQuery; +import eu.eudat.query.DmpDescriptionTemplateQuery; import gr.cite.tools.validation.ValidationFilterAnnotation; import eu.eudat.model.*; import eu.eudat.model.builder.DmpBuilder; @@ -90,6 +98,25 @@ public class DmpController { return queryResult; } + @GetMapping("public/{id}") + public PublicDmp publicGet(@PathVariable("id") UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException { + logger.debug(new MapLogEntry("retrieving" + Dmp.class.getSimpleName()).And("id", id).And("fields", fieldSet)); + + this.censorFactory.censor(PublicDmpCensor.class).censor(fieldSet); + + DmpQuery query = this.queryFactory.query(DmpQuery.class).authorize(EnumSet.of(Public)).ids(id).isActive(IsActive.Active).statuses(DmpStatus.Finalized).accessTypes(DmpAccessType.Public); + + PublicDmp model = this.builderFactory.builder(PublicDmpBuilder.class).authorize(EnumSet.of(Public)).build(fieldSet, query.firstAs(fieldSet)); + if (model == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + this.auditService.track(AuditableAction.Dmp_PublicLookup, Map.ofEntries( + new AbstractMap.SimpleEntry("id", id), + new AbstractMap.SimpleEntry("fields", fieldSet) + )); + + return model; + } + @PostMapping("query") public QueryResult Query(@RequestBody DmpLookup lookup) throws MyApplicationException, MyForbiddenException { logger.debug("querying {}", Dmp.class.getSimpleName()); diff --git a/dmp-frontend/src/app/core/model/description/description.ts b/dmp-frontend/src/app/core/model/description/description.ts index a3773006b..91fcda4ae 100644 --- a/dmp-frontend/src/app/core/model/description/description.ts +++ b/dmp-frontend/src/app/core/model/description/description.ts @@ -2,7 +2,7 @@ import { DescriptionStatus } from "@app/core/common/enum/description-status"; import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model"; import { Guid } from "@common/types/guid"; import { DescriptionTemplate } from "../description-template/description-template"; -import { Dmp, DmpDescriptionTemplate } from "../dmp/dmp"; +import { Dmp, DmpDescriptionTemplate, PublicDmp } from "../dmp/dmp"; import { Reference, ReferencePersist } from "../reference/reference"; import { Tag } from "../tag/tag"; import { User } from "../user/user"; @@ -21,8 +21,6 @@ export interface Description extends BaseEntity { dmp?: Dmp; } -export interface PublicDescription extends BaseEntity { -} export interface DescriptionPropertyDefinition { fieldSets: Map; @@ -118,4 +116,29 @@ export interface DescriptionStatusPersist { id: Guid; status: DescriptionStatus; hash: string; +} + +// +// Public +// + +export interface PublicDescription extends BaseEntity { + label?: string; + status?: DescriptionStatus; + description?: string; + finalizedAt?: Date; + descriptionTemplate?: PublicDescriptionTemplate; + dmpDescriptionTemplate?: PublicDmpDescriptionTemplate; + dmp?: PublicDmp; +} + +export interface PublicDmpDescriptionTemplate { + id: Guid; + dmp: PublicDmp; +} + +export interface PublicDescriptionTemplate { + id: Guid; + label: string; + description: string; } \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dmp/dmp.ts b/dmp-frontend/src/app/core/model/dmp/dmp.ts index f59d0ef25..b5cc56b86 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp.ts @@ -5,7 +5,7 @@ import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status'; import { BaseEntity, BaseEntityPersist } from '@common/base/base-entity.model'; import { Guid } from '@common/types/guid'; import { DescriptionTemplate } from '../description-template/description-template'; -import { Description } from '../description/description'; +import { Description, PublicDescription } from '../description/description'; import { DmpBlueprint } from '../dmp-blueprint/dmp-blueprint'; import { EntityDoi } from '../entity-doi/entity-doi'; import { ReferencePersist } from '../reference/reference'; @@ -146,3 +146,58 @@ export interface DmpUserRemovePersist { export interface DmpUserInvitePersist { users: DmpUserPersist[]; } + +// +// Public +// + +export interface PublicDmp extends BaseEntity { + label?: string; + version?: number; + description?: string; + finalizedAt?: Date; + publishedAt?: Date; + dmpReferences: PublicDmpReference[]; + users: PublicDmpUser[]; + descriptions: PublicDescription[]; +} + +export interface PublicDmpReference { + id: Guid; + dmp: PublicDmp; + reference: PublicReference; +} + +export interface PublicReference { + id: Guid; + label: string; + type: PublicReferenceType; + description?: string; + reference?: string; +} + +export interface PublicReferenceType { + id: Guid; + name: string; +} + +export interface PublicReference { + id: Guid; + label: string; + type: PublicUser; + role: DmpUserRole; +} + + +export interface PublicDmpUser { + id: Guid; + dmp: PublicDmp; + user: PublicUser; + role: DmpUserRole; +} + +export interface PublicUser { + id: Guid; + name: string; +} + diff --git a/dmp-frontend/src/app/core/services/description/description.service.ts b/dmp-frontend/src/app/core/services/description/description.service.ts index 8b352b54a..633394bc9 100644 --- a/dmp-frontend/src/app/core/services/description/description.service.ts +++ b/dmp-frontend/src/app/core/services/description/description.service.ts @@ -34,11 +34,7 @@ export class DescriptionService { publicQuery(q: DescriptionLookup): Observable> { const url = `${this.apiBase}/public/query`; - const params = new BaseHttpParams(); - params.interceptorContext = { - excludedInterceptors: [InterceptorType.AuthToken] - }; - return this.http.post>(url, q, { params: params }).pipe(catchError((error: any) => throwError(error))); + return this.http.post>(url, q).pipe(catchError((error: any) => throwError(error))); } getSingle(id: Guid, reqFields: string[] = []): Observable { @@ -52,18 +48,12 @@ export class DescriptionService { catchError((error: any) => throwError(error))); } - getPublicSingle(id: Guid, reqFields: string[] = []): Observable { + getPublicSingle(id: Guid, reqFields: string[] = []): Observable { const url = `${this.apiBase}/public/${id}`; - const options: HttpParamsOptions = { fromObject: { f: reqFields } }; - - let params: BaseHttpParams = new BaseHttpParams(options); - params.interceptorContext = { - excludedInterceptors: [InterceptorType.AuthToken] - }; - - + const options = { params: { f: reqFields } }; + return this.http - .get(url, { params: params }).pipe( + .get(url, options).pipe( catchError((error: any) => throwError(error))); } diff --git a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts index 42e68a55e..9b40743d7 100644 --- a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts +++ b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts @@ -15,7 +15,7 @@ import { catchError, map } from 'rxjs/operators'; import { nameof } from 'ts-simple-nameof'; import { BaseHttpParams } from '../../../../common/http/base-http-params'; import { InterceptorType } from '../../../../common/http/interceptors/interceptor-type'; -import { CloneDmpPersist, Dmp, DmpPersist, DmpUser, DmpUserInvitePersist, DmpUserPersist, DmpUserRemovePersist, NewVersionDmpPersist } from '../../model/dmp/dmp'; +import { CloneDmpPersist, Dmp, DmpPersist, DmpUser, DmpUserInvitePersist, DmpUserPersist, DmpUserRemovePersist, NewVersionDmpPersist, PublicDmp } from '../../model/dmp/dmp'; import { AuthService } from '../auth/auth.service'; import { ConfigurationService } from '../configuration/configuration.service'; import { BaseHttpV2Service } from '../http/base-http-v2.service'; @@ -41,6 +41,11 @@ export class DmpService { return this.http.post>(url, q).pipe(catchError((error: any) => throwError(error))); } + publicQuery(q: DmpLookup): Observable> { + const url = `${this.apiBase}/public/query`; + return this.http.post>(url, q).pipe(catchError((error: any) => throwError(error))); + } + getSingle(id: Guid, reqFields: string[] = []): Observable { const url = `${this.apiBase}/${id}`; const options = { params: { f: reqFields } }; @@ -50,17 +55,12 @@ export class DmpService { catchError((error: any) => throwError(error))); } - getPublicSingle(id: Guid, reqFields: string[] = []): Observable { //TODO: add this to backend. + getPublicSingle(id: Guid, reqFields: string[] = []): Observable { const url = `${this.apiBase}/public/${id}`; - const options: HttpParamsOptions = { fromObject: { f: reqFields } }; - - let params: BaseHttpParams = new BaseHttpParams(options); - params.interceptorContext = { - excludedInterceptors: [InterceptorType.AuthToken] - }; + const options = { params: { f: reqFields } }; return this.http - .get(url, { params: params }).pipe( + .get(url, options).pipe( catchError((error: any) => throwError(error))); } diff --git a/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.html b/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.html index a98a39ee9..5107e3b7a 100644 --- a/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.html +++ b/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.html @@ -5,13 +5,13 @@
- +
-
+
diff --git a/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.ts b/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.ts index 5aa32b4bc..f66faf66c 100644 --- a/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.ts +++ b/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.component.ts @@ -6,11 +6,17 @@ import { Observable } from "rxjs"; import { Inject } from "@angular/core"; import { TranslateService } from "@ngx-translate/core"; import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; -import { Dmp } from '@app/core/model/dmp/dmp'; +import { Dmp, DmpDescriptionTemplate } from '@app/core/model/dmp/dmp'; import { DmpService } from '@app/core/services/dmp/dmp.service'; import { DescriptionService } from '@app/core/services/description/description.service'; import { DmpDescriptionTemplateLookup } from '@app/core/query/dmp-description-template.lookup'; import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { DmpLookup } from '@app/core/query/dmp.lookup'; +import { Guid } from '@common/types/guid'; +import { DmpStatus } from '@app/core/common/enum/dmp-status'; +import { nameof } from 'ts-simple-nameof'; +import { FilterService } from '@common/modules/text-filter/filter-service'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; @Component({ selector: 'description-copy-dialog-component', @@ -22,12 +28,12 @@ export class DescriptionCopyDialogComponent { dmpModel: Dmp; descriptionDescriptionTemplateLabel: String; dmpAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { //TODO: add filter to only get DMPs that have connection with the same Description Template group. - initialItems: (data?: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup(null,null,null,null, this.dmpDescriptionTemplateLookup)).pipe(map(x => x.items)), - filterFn: (searchQuery: string, data?: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup(searchQuery, null, null, null, this.dmpDescriptionTemplateLookup)).pipe(map(x => x.items)), - getSelectedItem: (selectedItem: any) => this.dmpService.query(this.dmpService.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])), + initialItems: (data?: any) => this.dmpService.query(this.buildDmpLookup(null,null,null,null, this.dmpDescriptionTemplateLookup)).pipe(map(x => x.items)), + filterFn: (searchQuery: string, data?: any) => this.dmpService.query(this.buildDmpLookup(searchQuery, null, null, null, this.dmpDescriptionTemplateLookup)).pipe(map(x => x.items)), + getSelectedItem: (selectedItem: any) => this.dmpService.query(this.buildDmpLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])), displayFn: (item: Dmp) => item.label, titleFn: (item: Dmp) => item.label, - valueAssign: (item: Dmp) => item.id, + valueAssign: (item: Dmp) => this.findSection(item), }; dmpDescriptionTemplateLookup: DmpDescriptionTemplateLookup = { @@ -35,16 +41,48 @@ export class DescriptionCopyDialogComponent { isActive: [IsActive.Active] } as DmpDescriptionTemplateLookup; + private buildDmpLookup(like?: string, excludedIds?: Guid[], ids?: Guid[], statuses?: DmpStatus[], dmpDescriptionTemplateSubQuery?: DmpDescriptionTemplateLookup): DmpLookup { + const lookup: DmpLookup = new DmpLookup(); + lookup.page = { size: 100, offset: 0 }; + if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; } + if (ids && ids.length > 0) { lookup.ids = ids; } + lookup.isActive = [IsActive.Active]; + lookup.statuses = statuses; + lookup.project = { + fields: [ + nameof(x => x.id), + nameof(x => x.label), + [nameof(x => x.dmpDescriptionTemplates), nameof(x => x.sectionId)].join('.'), + [nameof(x => x.dmpDescriptionTemplates), nameof(x => x.descriptionTemplateGroupId)].join('.'), + + ] + }; + if (dmpDescriptionTemplateSubQuery != null) lookup.dmpDescriptionTemplateSubQuery = dmpDescriptionTemplateSubQuery; + lookup.order = { items: [nameof(x => x.label)] }; + if (like) { lookup.like = this.filterService.transformLike(like); } + return lookup; + } + constructor( public dialogRef: MatDialogRef, public dmpService: DmpService, public descriptionService: DescriptionService, public language: TranslateService, + private filterService: FilterService, @Inject(MAT_DIALOG_DATA) public data: any ) { } ngOnInit() { - + } + + findSection(dmp: Dmp){ + if(dmp.dmpDescriptionTemplates.length == 1){ + this.data.formGroup.get('sectionId').setValue(dmp.dmpDescriptionTemplates[0].sectionId); + }else if(dmp.dmpDescriptionTemplates.length > 1){ + //TODO + } + + return dmp.id } cancel() { @@ -52,9 +90,7 @@ export class DescriptionCopyDialogComponent { } confirm() { - // TODO: create a backend service to copy the description - const newDmpId = this.data.formControl.value; - this.dialogRef.close(newDmpId); + this.dialogRef.close(this.data.formGroup); } getErrorMessage() { diff --git a/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.module.ts b/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.module.ts index 776628c63..52087b9a1 100644 --- a/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.module.ts +++ b/dmp-frontend/src/app/ui/description/description-copy-dialog/description-copy-dialog.module.ts @@ -4,12 +4,14 @@ import { CommonUiModule } from '@common/ui/common-ui.module'; import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module'; import { CommonFormsModule } from '@common/forms/common-forms.module'; import { DescriptionCopyDialogComponent } from './description-copy-dialog.component'; +import { RouterModule } from '@angular/router'; @NgModule({ imports: [ CommonUiModule, CommonFormsModule, - AutoCompleteModule + AutoCompleteModule, + RouterModule ], declarations: [ DescriptionCopyDialogComponent diff --git a/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts b/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts index 03669b475..11a1e0aad 100644 --- a/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts +++ b/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts @@ -52,7 +52,7 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit status: Number; totalCount: number; dmpSearchEnabled = true; - listingItems: Description[] = []; + listingItems: any[] = []; hasListingItems = null; isPublic: boolean = false; @@ -216,7 +216,8 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit [nameof(x => x.dmpDescriptionTemplate), nameof(x => x.sectionId)].join('.'), ] }; - this.descriptionService.query(lookup).pipe(takeUntil(this._destroyed)) + if(this.isPublic){ + this.descriptionService.publicQuery(lookup).pipe(takeUntil(this._destroyed)) .subscribe(result => { if (!result) { return []; } this.totalCount = result.count; @@ -224,6 +225,17 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit this.listingItems.push(...result.items); this.hasListingItems = true; }); + }else{ + this.descriptionService.query(lookup).pipe(takeUntil(this._destroyed)) + .subscribe(result => { + if (!result) { return []; } + this.totalCount = result.count; + if (lookup?.page?.offset === 0) this.listingItems = []; + this.listingItems.push(...result.items); + this.hasListingItems = true; + }); + } + } openFiltersDialog(): void { diff --git a/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts b/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts index 241ed11db..b1f31a805 100644 --- a/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts +++ b/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts @@ -1,6 +1,6 @@ import { Location } from '@angular/common'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { UntypedFormControl } from '@angular/forms'; +import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { Router } from '@angular/router'; import { DmpAccessType } from '@app/core/common/enum/dmp-access-type'; @@ -61,7 +61,8 @@ export class DescriptionListingItemComponent extends BaseComponent implements On public dmpService: DmpService, public referenceService: ReferenceService, public referenceTypeService: ReferenceTypeService, - public fileTransformerService: FileTransformerService + public fileTransformerService: FileTransformerService, + private fb: UntypedFormBuilder, ) { super(); } @@ -155,12 +156,15 @@ export class DescriptionListingItemComponent extends BaseComponent implements On } copyToDmp(description: Description) { - const formControl = new UntypedFormControl(); + const formGroup = this.fb.group({ + dmpId: this.fb.control(null, Validators.required), + sectionId: this.fb.control(null, Validators.required), + }) const dialogRef = this.dialog.open(DescriptionCopyDialogComponent, { width: '500px', restoreFocus: false, data: { - formControl: formControl, + formGroup: formGroup, descriptionId: description.id, descriptionTemplate: description.descriptionTemplate, descriptionProfileExist: false, @@ -170,9 +174,9 @@ export class DescriptionListingItemComponent extends BaseComponent implements On }); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) - .subscribe(newDmpId => { - if (newDmpId) { - this.router.navigate(['/descriptions/copy/' + description.id], { queryParams: { newDmpId: newDmpId } }); + .subscribe(formGroup => { + if (formGroup) { + this.router.navigate(['descriptions/edit/copy/' + description.id + '/' + formGroup.get('dmpId').value + '/' + formGroup.get('sectionId').value]); } }); } diff --git a/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts b/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts index 4ab5c98a3..523f09e2f 100644 --- a/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts +++ b/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { BaseComponent } from '@common/base/base.component'; // import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; import { Location } from '@angular/common'; -import { UntypedFormControl } from '@angular/forms'; +import { UntypedFormBuilder, UntypedFormControl, Validators } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { DescriptionStatus } from '@app/core/common/enum/description-status'; @@ -42,7 +42,7 @@ import { ReferenceType } from '@app/core/model/reference-type/reference-type'; }) export class DescriptionOverviewComponent extends BaseComponent implements OnInit { - description: Description; + description: any; researchers: DmpReference[] = []; isNew = true; isFinalized = false; @@ -73,7 +73,8 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni private matomoService: MatomoService, private fileUtils: FileUtils, public fileTransformerService: FileTransformerService, - private referenceTypeService: ReferenceTypeService + private referenceTypeService: ReferenceTypeService, + private fb: UntypedFormBuilder, ) { super(); } @@ -325,12 +326,15 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni } openCopyToDmpDialog() { - const formControl = new UntypedFormControl(); + const formGroup = this.fb.group({ + dmpId: this.fb.control(null, Validators.required), + sectionId: this.fb.control(null, Validators.required), + }) const dialogRef = this.dialog.open(DescriptionCopyDialogComponent, { width: '500px', restoreFocus: false, data: { - formControl: formControl, + formGroup: formGroup, descriptionId: this.description.id, descriptionTemplate: this.description.descriptionTemplate, dmpDescriptionTemplate: this.description.dmpDescriptionTemplate, @@ -341,11 +345,9 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni }); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) - .subscribe(newDmpId => { - if (newDmpId) { - this.router.navigate(['/descriptions/copy/' + this.description.id], { queryParams: { newDmpId: newDmpId } }); - // let url = this.router.createUrlTree(['/descriptions/copy/', result.descriptionId, { newDmpId: newDmpId }]) - // window.open(url.toString(), '_blank') + .subscribe(formGroup => { + if (formGroup) { + this.router.navigate(['descriptions/edit/copy/' + this.description.id + '/' + formGroup.get('dmpId').value + '/' + formGroup.get('sectionId').value]); } }); } diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.model.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.model.ts index d5eac43b7..355a682f1 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.model.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.model.ts @@ -42,7 +42,7 @@ export class DmpEditorModel extends BaseEditorModel implements DmpPersist { this.language = item.language; this.blueprint = item.blueprint?.id; this.accessType = item.accessType; - if (item?.dmpUsers) { item.dmpUsers.map(x => this.users.push(new DmpUserEditorModel(this.validationErrorModel).fromModel(x))); } + if (item?.dmpUsers) { item.dmpUsers.filter(x => x.isActive === IsActive.Active).map(x => this.users.push(new DmpUserEditorModel(this.validationErrorModel).fromModel(x))); } item.blueprint.definition.sections.forEach(section => { if (section.hasTemplates) { diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.resolver.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.resolver.ts index 93d2d227e..dfa905242 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.resolver.ts @@ -60,6 +60,7 @@ export class DmpEditorResolver extends BaseEditorResolver { [nameof(x => x.dmpUsers), nameof(x => x.user.name)].join('.'), [nameof(x => x.dmpUsers), nameof(x => x.role)].join('.'), [nameof(x => x.dmpUsers), nameof(x => x.sectionId)].join('.'), + [nameof(x => x.dmpUsers), nameof(x => x.isActive)].join('.'), [nameof(x => x.dmpReferences), nameof(x => x.id)].join('.'), [nameof(x => x.dmpReferences), nameof(x => x.isActive)].join('.'), diff --git a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts index b86eb3f61..6b2c8d3bd 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts +++ b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts @@ -44,7 +44,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr lookup: DmpLookup = new DmpLookup(); groupId: string; totalCount: number; - listingItems: Dmp[] = []; + listingItems: any[] = []; isPublic: boolean = false; hasListingItems = null; pageSize: number = 5; @@ -188,6 +188,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr [nameof(x => x.descriptions), nameof(x => x.id)].join('.'), [nameof(x => x.descriptions), nameof(x => x.label)].join('.'), + [nameof(x => x.descriptions), nameof(x => x.isActive)].join('.'), [nameof(x => x.blueprint), nameof(x => x.id)].join('.'), [nameof(x => x.blueprint), nameof(x => x.label)].join('.'), @@ -201,6 +202,9 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr [nameof(x => x.dmpUsers), nameof(x => x.id)].join('.'), [nameof(x => x.dmpUsers), nameof(x => x.user.id)].join('.'), [nameof(x => x.dmpUsers), nameof(x => x.role)].join('.'), + [nameof(x => x.dmpUsers), nameof(x => x.dmp.id)].join('.'), + [nameof(x => x.dmpUsers), nameof(x => x.isActive)].join('.'), + [nameof(x => x.dmpReferences), nameof(x => x.id)].join('.'), [nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.id)].join('.'), [nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.label)].join('.'), @@ -208,7 +212,9 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr // [nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.reference)].join('.'), ] }; - this.dmpService.query(lookup).pipe(takeUntil(this._destroyed)) + + if(this.isPublic){ + this.dmpService.publicQuery(lookup).pipe(takeUntil(this._destroyed)) .subscribe(result => { if (!result) { return []; } this.totalCount = result.count; @@ -216,6 +222,22 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr this.listingItems.push(...result.items); this.hasListingItems = true; }); + }else{ + this.dmpService.query(lookup).pipe(takeUntil(this._destroyed)) + .subscribe(result => { + if (!result) { return []; } + this.totalCount = result.count; + if (lookup?.page?.offset === 0) this.listingItems = []; + result.items.forEach(x=> { + x.descriptions = x.descriptions?.filter(x=> x.isActive === IsActive.Active); + x.dmpUsers = x.dmpUsers.filter(x=> x.isActive === IsActive.Active); + this.listingItems.push(x); + }) + // this.listingItems.push(...result.items); + this.hasListingItems = true; + }); + } + } controlModified(): void { diff --git a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts index 01ca80ff2..e7a6b69e7 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts +++ b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts @@ -223,11 +223,11 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { } canCreateNewVersion(dmp: Dmp): boolean { - return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.CreateNewVersionDmp); + return (this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.CreateNewVersionDmp)) && this.isPublic == false; } canDeleteDmp(dmp: Dmp): boolean { - return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.DeleteDmp); + return (this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.DeleteDmp)) && this.isPublic == false; } canCloneDmp(dmp: Dmp): boolean { @@ -235,7 +235,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { } canFinalizeDmp(dmp: Dmp): boolean { - return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.FinalizeDmp); + return (this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.FinalizeDmp)) && this.isPublic == false; } canExportDmp(dmp: Dmp): boolean { @@ -243,10 +243,10 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { } canInviteDmpUsers(dmp: Dmp): boolean { - return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.InviteDmpUsers); + return (this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.InviteDmpUsers)) && this.isPublic == false; } canAssignDmpUsers(dmp: Dmp): boolean { - return this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.AssignDmpUsers); + return (this.isDmpOwner(dmp) || this.authentication.hasPermission(AppPermission.AssignDmpUsers)) && this.isPublic == false; } } diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html index 23554c911..7c90865c8 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html @@ -36,7 +36,7 @@ {{dmp.updatedAt | dateTimeCultureFormatter: "d MMMM y"}}
-
+
check {{'DMP-OVERVIEW.FINALISED' | translate}}
diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts index 9b3982e1e..09ffbfbfb 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts @@ -43,6 +43,7 @@ import { CloneDmpDialogComponent } from '../clone-dialog/dmp-clone-dialog.compon import { NewVersionDmpDialogComponent } from '../new-version-dialog/dmp-new-version-dialog.component'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { ReferenceType } from '@app/core/model/reference-type/reference-type'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; @Component({ selector: 'app-dmp-overview', @@ -51,7 +52,7 @@ import { ReferenceType } from '@app/core/model/reference-type/reference-type'; }) export class DmpOverviewComponent extends BaseComponent implements OnInit { - dmp: Dmp; + dmp: any; selectedBlueprint: DmpBlueprint; researchers: DmpReference[] = []; isNew = true; @@ -114,6 +115,8 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { .pipe(takeUntil(this._destroyed)) .subscribe(data => { this.dmp = data; + this.dmp.dmpUsers = data.dmpUsers.filter(x=> x.isActive === IsActive.Active); + if(this.dmp.descriptions) this.dmp.descriptions = data.descriptions.filter(x=> x.isActive === IsActive.Active); this.selectedBlueprint= data.blueprint; this.researchers = this.referenceService.getReferencesForTypes(this.dmp?.dmpReferences, [this.referenceTypeService.getResearcherReferenceType()]); if (!this.hasDoi()) { @@ -195,15 +198,15 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { } canEditDmp(): boolean{ - return (this.isDraftDmp()) && (this.isDmpOwner() || this.authentication.hasPermission(AppPermission.EditDmp)); + return (this.isDraftDmp()) && (this.isDmpOwner() || this.authentication.hasPermission(AppPermission.EditDmp)) && this.isPublicView == false; } canCreateNewVersion(): boolean { - return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.CreateNewVersionDmp); + return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.CreateNewVersionDmp) && this.isPublicView == false; } canDeleteDmp(): boolean { - return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.DeleteDmp); + return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.DeleteDmp) && this.isPublicView == false; } canCloneDmp(): boolean { @@ -211,7 +214,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { } canFinalizeDmp(): boolean { - return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.FinalizeDmp); + return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.FinalizeDmp) && this.isPublicView == false; } canExportDmp(): boolean { @@ -219,11 +222,11 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { } canInviteDmpUsers(): boolean { - return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.InviteDmpUsers); + return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.InviteDmpUsers) && this.isPublicView == false; } canAssignDmpUsers(): boolean { - return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.AssignDmpUsers); + return this.isDmpOwner() || this.authentication.hasPermission(AppPermission.AssignDmpUsers) && this.isPublicView == false; } editClicked() { @@ -769,10 +772,13 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { [nameof(x => x.descriptions), nameof(x => x.id)].join('.'), [nameof(x => x.descriptions), nameof(x => x.label)].join('.'), [nameof(x => x.descriptions), nameof(x => x.status)].join('.'), + [nameof(x => x.descriptions), nameof(x => x.isActive)].join('.'), [nameof(x => x.dmpUsers), nameof(x => x.id)].join('.'), [nameof(x => x.dmpUsers), nameof(x => x.user.id)].join('.'), [nameof(x => x.dmpUsers), nameof(x => x.user.name)].join('.'), [nameof(x => x.dmpUsers), nameof(x => x.role)].join('.'), + [nameof(x => x.dmpUsers), nameof(x => x.dmp.id)].join('.'), + [nameof(x => x.dmpUsers), nameof(x => x.isActive)].join('.'), [nameof(x => x.dmpReferences), nameof(x => x.id)].join('.'), [nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.id)].join('.'), [nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.label)].join('.'),