description template type and dmp blueprint frontend changes
This commit is contained in:
parent
0b3178177a
commit
4d3098860d
|
@ -20,4 +20,9 @@ public class AuditableAction {
|
|||
|
||||
public static final EventId EntityDoi_Delete = new EventId(2003, "EntityDoi_Delete");
|
||||
|
||||
public static final EventId User_Settings_Query = new EventId(3000, "User_Settings_Query");
|
||||
public static final EventId User_Settings_Lookup = new EventId(3001, "User_Settings_Lookup");
|
||||
public static final EventId User_Settings_Persist = new EventId(3002, "User_Settings_Persist");
|
||||
public static final EventId User_Settings_Delete = new EventId(3003, "User_Settings_Delete");
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,12 @@ public final class Permission {
|
|||
public static String EditEntityDoi = "EditEntityDoi";
|
||||
public static String DeleteEntityDoi = "DeleteEntityDoi";
|
||||
|
||||
//UserSettings
|
||||
public static String BrowseUserSettings = "BrowseUserSettings";
|
||||
public static String EditUserSettings = "EditUserSettings";
|
||||
public static String DeleteUserSettings = "DeleteUserSettings";
|
||||
|
||||
|
||||
// UI Pages
|
||||
public static String ViewDescriptionTemplateTypePage = "ViewDescriptionTemplateTypePage";
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package eu.eudat.commons.enums;
|
||||
|
||||
import eu.eudat.data.converters.enums.DatabaseEnum;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public enum UserSettingsType implements DatabaseEnum<Short> {
|
||||
|
||||
Settings((short) 0),
|
||||
Config((short) 1);
|
||||
|
||||
private final Short value;
|
||||
|
||||
UserSettingsType(Short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Short getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private static final Map<Short, UserSettingsType> map = EnumUtils.getEnumValueMap(UserSettingsType.class);
|
||||
|
||||
public static UserSettingsType of(Short i) {
|
||||
return map.get(i);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
package eu.eudat.data;
|
||||
|
||||
|
||||
import eu.eudat.commons.enums.UserSettingsType;
|
||||
import eu.eudat.data.converters.enums.UserSettingsTypeConverter;
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity
|
||||
@Table(name = "UserSettings")
|
||||
public class UserSettingsEntity {
|
||||
|
||||
@Id
|
||||
@Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false)
|
||||
private UUID id;
|
||||
public static final String _id = "id";
|
||||
|
||||
@Column(name = "key", length = 500, nullable = false)
|
||||
private String key;
|
||||
public static final String _key = "key";
|
||||
|
||||
@Column(name = "value", nullable = false)
|
||||
private String value;
|
||||
public static final String _value = "value";
|
||||
|
||||
@Column(name = "name", nullable = false)
|
||||
private String name;
|
||||
public static final String _name = "name";
|
||||
|
||||
@Column(name = "entity_id", columnDefinition = "uuid", nullable = true)
|
||||
private UUID entityId;
|
||||
public static final String _entityId = "entityId";
|
||||
|
||||
@Column(name = "created_at", nullable = false)
|
||||
private Instant createdAt;
|
||||
public static final String _createdAt = "createdAt";
|
||||
|
||||
@Column(name = "updated_at", nullable = false)
|
||||
private Instant updatedAt;
|
||||
public static final String _updatedAt = "updatedAt";
|
||||
|
||||
@Column(name = "type", nullable = false)
|
||||
@Convert(converter = UserSettingsTypeConverter.class)
|
||||
private UserSettingsType type;
|
||||
public static final String _type = "type";
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public UUID getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public void setEntityId(UUID entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public Instant getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(Instant updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public UserSettingsType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(UserSettingsType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package eu.eudat.data.converters.enums;
|
||||
|
||||
import eu.eudat.commons.enums.UserSettingsType;
|
||||
import jakarta.persistence.Converter;
|
||||
|
||||
@Converter
|
||||
public class UserSettingsTypeConverter extends DatabaseEnumConverter<UserSettingsType, Short> {
|
||||
public UserSettingsType of(Short i) {
|
||||
return UserSettingsType.of(i);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package eu.eudat.model;
|
||||
|
||||
import eu.eudat.commons.enums.UserSettingsType;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
public class UserSettings {
|
||||
|
||||
private UUID id;
|
||||
public static final String _id = "id";
|
||||
|
||||
private String key;
|
||||
public static final String _key = "key";
|
||||
|
||||
private String value;
|
||||
public static final String _value = "value";
|
||||
|
||||
private UUID entityId;
|
||||
public static final String _entityId = "entityId";
|
||||
|
||||
private Instant createdAt;
|
||||
public static final String _createdAt = "createdAt";
|
||||
|
||||
private Instant updatedAt;
|
||||
public static final String _updatedAt = "updatedAt";
|
||||
|
||||
private UserSettingsType type;
|
||||
public static final String _type = "type";
|
||||
|
||||
private String hash;
|
||||
public static final String _hash = "hash";
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public UUID getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public void setEntityId(UUID entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public Instant getUpdatedAt() {
|
||||
return updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(Instant updatedAt) {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public UserSettingsType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(UserSettingsType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public void setHash(String hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package eu.eudat.model.builder;
|
||||
|
||||
import eu.eudat.authorization.AuthorizationFlags;
|
||||
import eu.eudat.convention.ConventionService;
|
||||
import eu.eudat.data.UserSettingsEntity;
|
||||
import eu.eudat.model.UserSettings;
|
||||
import gr.cite.tools.data.builder.BuilderFactory;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import gr.cite.tools.logging.DataLogEntry;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class UserSettingsBuilder extends BaseBuilder<UserSettings, UserSettingsEntity> {
|
||||
|
||||
private final BuilderFactory builderFactory;
|
||||
private final QueryFactory queryFactory;
|
||||
|
||||
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
|
||||
|
||||
public UserSettingsBuilder(ConventionService conventionService, BuilderFactory builderFactory, QueryFactory queryFactory) {
|
||||
super(conventionService, new LoggerService(LoggerFactory.getLogger(UserSettingsBuilder.class)));
|
||||
this.builderFactory = builderFactory;
|
||||
this.queryFactory = queryFactory;
|
||||
}
|
||||
|
||||
public UserSettingsBuilder authorize(EnumSet<AuthorizationFlags> values) {
|
||||
this.authorize = values;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserSettings> build(FieldSet fields, List<UserSettingsEntity> data) throws MyApplicationException {
|
||||
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0));
|
||||
this.logger.trace(new DataLogEntry("requested fields", fields));
|
||||
if (fields == null || data == null || fields.isEmpty()) return new ArrayList<>();
|
||||
|
||||
List<UserSettings> models = new ArrayList<>();
|
||||
|
||||
for (UserSettingsEntity d : data) {
|
||||
UserSettings m = new UserSettings();
|
||||
if (fields.hasField(this.asIndexer(UserSettings._id))) m.setId(d.getId());
|
||||
if (fields.hasField(this.asIndexer(UserSettings._value))) m.setValue(d.getValue());
|
||||
if (fields.hasField(this.asIndexer(UserSettings._key))) m.setKey(d.getKey());
|
||||
if (fields.hasField(this.asIndexer(UserSettings._type))) m.setType(d.getType());
|
||||
if (fields.hasField(this.asIndexer(UserSettings._entityId))) m.setEntityId(d.getEntityId());
|
||||
if (fields.hasField(this.asIndexer(UserSettings._createdAt))) m.setCreatedAt(d.getCreatedAt());
|
||||
if (fields.hasField(this.asIndexer(UserSettings._updatedAt))) m.setUpdatedAt(d.getUpdatedAt());
|
||||
if (fields.hasField(this.asIndexer(UserSettings._hash))) m.setHash(this.hashValue(Instant.ofEpochMilli(d.getUpdatedAt().toEpochMilli())));
|
||||
models.add(m);
|
||||
}
|
||||
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
|
||||
return models;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package eu.eudat.model.censorship;
|
||||
|
||||
import eu.eudat.authorization.OwnedResource;
|
||||
import eu.eudat.authorization.Permission;
|
||||
import eu.eudat.convention.ConventionService;
|
||||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||
import gr.cite.tools.data.censor.CensorFactory;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import gr.cite.tools.logging.DataLogEntry;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class UserSettingsCensor extends BaseCensor {
|
||||
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserSettingsCensor.class));
|
||||
|
||||
protected final AuthorizationService authService;
|
||||
protected final CensorFactory censorFactory;
|
||||
|
||||
public UserSettingsCensor(ConventionService conventionService, AuthorizationService authService, CensorFactory censorFactory) {
|
||||
super(conventionService);
|
||||
this.authService = authService;
|
||||
this.censorFactory = censorFactory;
|
||||
}
|
||||
|
||||
public void censor(FieldSet fields, UUID userId) throws MyForbiddenException {
|
||||
logger.debug(new DataLogEntry("censoring fields", fields));
|
||||
if (this.isEmpty(fields)) return;
|
||||
this.authService.authorizeAtLeastOneForce(userId != null ? List.of(new OwnedResource(userId)) : null, Permission.BrowseUserSettings);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package eu.eudat.model.persist;
|
||||
|
||||
import eu.eudat.commons.enums.UserSettingsType;
|
||||
import eu.eudat.commons.validation.FieldNotNullIfOtherSet;
|
||||
import eu.eudat.commons.validation.ValidId;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@FieldNotNullIfOtherSet(message = "{validation.hashempty}")
|
||||
public class UserSettingsPersist {
|
||||
|
||||
@ValidId(message = "{validation.invalidid}")
|
||||
private UUID id;
|
||||
|
||||
@NotNull(message = "{validation.empty}")
|
||||
@NotEmpty(message = "{validation.empty}")
|
||||
private String key;
|
||||
|
||||
@NotNull(message = "{validation.empty}")
|
||||
@NotEmpty(message = "{validation.empty}")
|
||||
private String value;
|
||||
|
||||
@ValidId(message = "{validation.invalidid}")
|
||||
private UUID entityId;
|
||||
|
||||
@NotNull(message = "{validation.empty}")
|
||||
private UserSettingsType type;
|
||||
|
||||
private String hash;
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public UUID getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public void setEntityId(UUID entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
public UserSettingsType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(UserSettingsType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public void setHash(String hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,234 @@
|
|||
package eu.eudat.query;
|
||||
|
||||
import eu.eudat.authorization.AuthorizationFlags;
|
||||
import eu.eudat.authorization.Permission;
|
||||
import eu.eudat.commons.enums.UserSettingsType;
|
||||
import eu.eudat.commons.scope.user.UserScope;
|
||||
import eu.eudat.data.UserSettingsEntity;
|
||||
import eu.eudat.model.UserSettings;
|
||||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||
import gr.cite.tools.data.query.FieldResolver;
|
||||
import gr.cite.tools.data.query.QueryBase;
|
||||
import gr.cite.tools.data.query.QueryContext;
|
||||
import jakarta.persistence.Tuple;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class UserSettingsQuery extends QueryBase<UserSettingsEntity> {
|
||||
|
||||
private String like;
|
||||
private Collection<UUID> ids;
|
||||
private Collection<UserSettingsType> userSettingsTypes;
|
||||
private Collection<String> keys;
|
||||
private Collection<UserSettingsType> types;
|
||||
private Collection<UUID> entityIds;
|
||||
|
||||
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
|
||||
|
||||
private final UserScope userScope;
|
||||
private final AuthorizationService authService;
|
||||
|
||||
public UserSettingsQuery(
|
||||
UserScope userScope,
|
||||
AuthorizationService authService
|
||||
) {
|
||||
this.userScope = userScope;
|
||||
this.authService = authService;
|
||||
}
|
||||
|
||||
public UserSettingsQuery like(String like) {
|
||||
this.like = like;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery ids(UUID value) {
|
||||
this.ids = List.of(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery ids(UUID... value) {
|
||||
this.ids = Arrays.asList(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery ids(Collection<UUID> values) {
|
||||
this.ids = values;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery userSettingsTypes(UserSettingsType value) {
|
||||
this.userSettingsTypes = List.of(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery userSettingsTypes(UserSettingsType... value) {
|
||||
this.userSettingsTypes = Arrays.asList(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery userSettingsTypes(Collection<UserSettingsType> values) {
|
||||
this.userSettingsTypes = values;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery keys(String value) {
|
||||
this.keys = List.of(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery keys(String... value) {
|
||||
this.keys = Arrays.asList(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery keys(Collection<String> values) {
|
||||
this.keys = values;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public UserSettingsQuery types(UserSettingsType value) {
|
||||
this.types = List.of(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery types(UserSettingsType... value) {
|
||||
this.types = Arrays.asList(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery types(Collection<UserSettingsType> values) {
|
||||
this.types = values;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery entityIds(UUID value) {
|
||||
this.entityIds = List.of(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery entityIds(UUID... value) {
|
||||
this.entityIds = Arrays.asList(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery entityIds(Collection<UUID> values) {
|
||||
this.entityIds = values;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserSettingsQuery authorize(EnumSet<AuthorizationFlags> values) {
|
||||
this.authorize = values;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean isFalseQuery() {
|
||||
return this.isEmpty(this.ids) || this.isEmpty(this.keys) || this.isEmpty(this.types) || this.isEmpty(this.entityIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<UserSettingsEntity> entityClass() {
|
||||
return UserSettingsEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <X, Y> Predicate applyAuthZ(QueryContext<X, Y> queryContext) {
|
||||
if (this.authorize.contains(AuthorizationFlags.None)) return null;
|
||||
if (this.authorize.contains(AuthorizationFlags.Permission) && this.authService.authorize(Permission.BrowseUserSettings)) return null;
|
||||
UUID ownerId = null;
|
||||
if (this.authorize.contains(AuthorizationFlags.Owner)) ownerId = this.userScope.getUserIdSafe();
|
||||
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
if (ownerId != null) {
|
||||
predicates.add(queryContext.CriteriaBuilder.equal(queryContext.Root.get(UserSettingsEntity._entityId), ownerId));
|
||||
}
|
||||
if (predicates.size() > 0) {
|
||||
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
|
||||
return queryContext.CriteriaBuilder.and(predicatesArray);
|
||||
} else {
|
||||
return queryContext.CriteriaBuilder.or(); //Creates a false query
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) {
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
if (this.like != null && !this.like.isEmpty()) {
|
||||
predicates.add(queryContext.CriteriaBuilder.or(queryContext.CriteriaBuilder.like(queryContext.Root.get(UserSettingsEntity._key), this.like),
|
||||
queryContext.CriteriaBuilder.like(queryContext.Root.get(UserSettingsEntity._value), this.like)
|
||||
));
|
||||
}
|
||||
if (this.ids != null) {
|
||||
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserSettingsEntity._id));
|
||||
for (UUID item : this.ids) inClause.value(item);
|
||||
predicates.add(inClause);
|
||||
}
|
||||
|
||||
if (this.userSettingsTypes != null) {
|
||||
CriteriaBuilder.In<UserSettingsType> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserSettingsEntity._type));
|
||||
for (UserSettingsType item : this.userSettingsTypes) inClause.value(item);
|
||||
predicates.add(inClause);
|
||||
}
|
||||
|
||||
if (this.keys != null) {
|
||||
CriteriaBuilder.In<String> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserSettingsEntity._key));
|
||||
for (String item : this.keys) inClause.value(item);
|
||||
predicates.add(inClause);
|
||||
}
|
||||
|
||||
if (this.entityIds != null) {
|
||||
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserSettingsEntity._entityId));
|
||||
for (UUID item : this.entityIds) inClause.value(item);
|
||||
predicates.add(inClause);
|
||||
}
|
||||
|
||||
if (this.types != null) {
|
||||
CriteriaBuilder.In<UserSettingsType> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserSettingsEntity._type));
|
||||
for (UserSettingsType item : this.types) inClause.value(item);
|
||||
predicates.add(inClause);
|
||||
}
|
||||
|
||||
|
||||
if (predicates.size() > 0) {
|
||||
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
|
||||
return queryContext.CriteriaBuilder.and(predicatesArray);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String fieldNameOf(FieldResolver item) {
|
||||
if (item.match(UserSettings._id)) return UserSettingsEntity._id;
|
||||
else if (item.match(UserSettings._entityId)) return UserSettingsEntity._entityId;
|
||||
else if (item.match(UserSettings._value)) return UserSettingsEntity._value;
|
||||
else if (item.match(UserSettings._key)) return UserSettingsEntity._key;
|
||||
else if (item.match(UserSettings._type)) return UserSettingsEntity._type;
|
||||
else if (item.match(UserSettings._createdAt)) return UserSettingsEntity._createdAt;
|
||||
else if (item.match(UserSettings._updatedAt)) return UserSettingsEntity._updatedAt;
|
||||
else if (item.match(UserSettings._hash)) return UserSettingsEntity._updatedAt;
|
||||
else return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UserSettingsEntity convert(Tuple tuple, Set<String> columns) {
|
||||
UserSettingsEntity item = new UserSettingsEntity();
|
||||
item.setId(QueryBase.convertSafe(tuple, columns, UserSettingsEntity._id, UUID.class));
|
||||
item.setEntityId(QueryBase.convertSafe(tuple, columns, UserSettingsEntity._entityId, UUID.class));
|
||||
item.setKey(QueryBase.convertSafe(tuple, columns, UserSettingsEntity._key, String.class));
|
||||
item.setValue(QueryBase.convertSafe(tuple, columns, UserSettingsEntity._value, String.class));
|
||||
item.setType(QueryBase.convertSafe(tuple, columns, UserSettingsEntity._type, UserSettingsType.class));
|
||||
item.setCreatedAt(QueryBase.convertSafe(tuple, columns, UserSettingsEntity._createdAt, Instant.class));
|
||||
item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, UserSettingsEntity._updatedAt, Instant.class));
|
||||
return item;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package eu.eudat.query.lookup;
|
||||
|
||||
import eu.eudat.commons.enums.UserSettingsType;
|
||||
import eu.eudat.query.UserSettingsQuery;
|
||||
import gr.cite.tools.data.query.Lookup;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class UserSettingsLookup extends Lookup {
|
||||
|
||||
private String like;
|
||||
private List<UUID> ids;
|
||||
private List<UserSettingsType> userSettingsTypes;
|
||||
|
||||
public String getLike() {
|
||||
return like;
|
||||
}
|
||||
|
||||
public void setLike(String like) {
|
||||
this.like = like;
|
||||
}
|
||||
|
||||
public List<UUID> getIds() {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public void setIds(List<UUID> ids) {
|
||||
this.ids = ids;
|
||||
}
|
||||
|
||||
public List<UserSettingsType> getUserSettingsTypes() {
|
||||
return userSettingsTypes;
|
||||
}
|
||||
|
||||
public void setUserSettingsTypes(List<UserSettingsType> userSettingsTypes) {
|
||||
this.userSettingsTypes = userSettingsTypes;
|
||||
}
|
||||
|
||||
public UserSettingsQuery enrich(QueryFactory queryFactory) {
|
||||
UserSettingsQuery query = queryFactory.query(UserSettingsQuery.class);
|
||||
if (this.like != null) query.like(this.like);
|
||||
if (this.ids != null) query.ids(this.ids);
|
||||
if (this.userSettingsTypes != null) query.userSettingsTypes(this.userSettingsTypes);
|
||||
|
||||
this.enrichCommon(query);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
}
|
|
@ -39,7 +39,6 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
@RequestScope
|
||||
public class DescriptionTemplateTypeServiceImpl implements DescriptionTemplateTypeService {
|
||||
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionTemplateTypeServiceImpl.class));
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package eu.eudat.service.user.settings;
|
||||
|
||||
import eu.eudat.model.UserSettings;
|
||||
import eu.eudat.model.persist.UserSettingsPersist;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.exception.MyNotFoundException;
|
||||
import gr.cite.tools.exception.MyValidationException;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
|
||||
public interface UserSettingsService {
|
||||
UserSettings persist(UserSettingsPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException;
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package eu.eudat.service.user.settings;
|
||||
|
||||
import eu.eudat.authorization.AuthorizationFlags;
|
||||
import eu.eudat.authorization.Permission;
|
||||
import eu.eudat.commons.scope.user.UserScope;
|
||||
import eu.eudat.convention.ConventionService;
|
||||
import eu.eudat.data.UserSettingsEntity;
|
||||
import eu.eudat.errorcode.ErrorThesaurusProperties;
|
||||
import eu.eudat.model.UserSettings;
|
||||
import eu.eudat.model.builder.UserSettingsBuilder;
|
||||
import eu.eudat.model.persist.UserSettingsPersist;
|
||||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||
import gr.cite.tools.data.builder.BuilderFactory;
|
||||
import gr.cite.tools.data.deleter.DeleterFactory;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.exception.MyNotFoundException;
|
||||
import gr.cite.tools.exception.MyValidationException;
|
||||
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import gr.cite.tools.logging.MapLogEntry;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.context.annotation.RequestScope;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class UserSettingsServiceImpl implements UserSettingsService {
|
||||
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserSettingsServiceImpl.class));
|
||||
private final EntityManager entityManager;
|
||||
private final AuthorizationService authorizationService;
|
||||
private final DeleterFactory deleterFactory;
|
||||
private final BuilderFactory builderFactory;
|
||||
private final ConventionService conventionService;
|
||||
private final ErrorThesaurusProperties errors;
|
||||
private final MessageSource messageSource;
|
||||
|
||||
private final UserScope userScope;
|
||||
|
||||
@Autowired
|
||||
public UserSettingsServiceImpl(
|
||||
EntityManager entityManager,
|
||||
AuthorizationService authorizationService,
|
||||
DeleterFactory deleterFactory,
|
||||
BuilderFactory builderFactory,
|
||||
ConventionService conventionService,
|
||||
ErrorThesaurusProperties errors,
|
||||
MessageSource messageSource,
|
||||
UserScope userScope) {
|
||||
this.entityManager = entityManager;
|
||||
this.authorizationService = authorizationService;
|
||||
this.deleterFactory = deleterFactory;
|
||||
this.builderFactory = builderFactory;
|
||||
this.conventionService = conventionService;
|
||||
this.errors = errors;
|
||||
this.messageSource = messageSource;
|
||||
this.userScope = userScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserSettings persist(UserSettingsPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException {
|
||||
logger.debug(new MapLogEntry("persisting data access request").And("model", model).And("fields", fields));
|
||||
|
||||
this.authorizationService.authorizeForce(Permission.EditUserSettings);
|
||||
|
||||
boolean isUpdate = this.conventionService.isValidGuid(model.getId());
|
||||
|
||||
UserSettingsEntity data;
|
||||
if (isUpdate) {
|
||||
data = this.entityManager.find(UserSettingsEntity.class, model.getId());
|
||||
if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), UserSettings.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||
} else {
|
||||
data = new UserSettingsEntity();
|
||||
data.setCreatedAt(Instant.now());
|
||||
data.setId(UUID.randomUUID());
|
||||
|
||||
}
|
||||
|
||||
data.setName(model.getKey());
|
||||
data.setType(model.getType());
|
||||
data.setKey(model.getKey());
|
||||
data.setValue(model.getValue());
|
||||
data.setEntityId(model.getEntityId());
|
||||
data.setUpdatedAt(Instant.now());
|
||||
|
||||
if (isUpdate) this.entityManager.merge(data);
|
||||
else this.entityManager.persist(data);
|
||||
|
||||
this.entityManager.flush();
|
||||
|
||||
return this.builderFactory.builder(UserSettingsBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(BaseFieldSet.build(fields, UserSettings._id, UserSettings._key), data);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
package eu.eudat.controllers.v2;
|
||||
import eu.eudat.audit.AuditableAction;
|
||||
import eu.eudat.authorization.AuthorizationFlags;
|
||||
import eu.eudat.data.UserSettingsEntity;
|
||||
import eu.eudat.model.UserSettings;
|
||||
import eu.eudat.model.builder.UserSettingsBuilder;
|
||||
import eu.eudat.model.censorship.UserSettingsCensor;
|
||||
import eu.eudat.model.persist.UserSettingsPersist;
|
||||
import eu.eudat.model.result.QueryResult;
|
||||
import eu.eudat.query.UserSettingsQuery;
|
||||
import eu.eudat.query.lookup.UserSettingsLookup;
|
||||
import eu.eudat.service.user.settings.UserSettingsService;
|
||||
import gr.cite.tools.auditing.AuditService;
|
||||
import gr.cite.tools.data.builder.BuilderFactory;
|
||||
import gr.cite.tools.data.censor.CensorFactory;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.exception.MyNotFoundException;
|
||||
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||
import gr.cite.tools.fieldset.FieldSet;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
import gr.cite.tools.logging.MapLogEntry;
|
||||
import gr.cite.tools.validation.MyValidate;
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.management.InvalidApplicationException;
|
||||
import java.util.*;
|
||||
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
@RequestMapping(path = "api/user-settings")
|
||||
public class UserSettingsController {
|
||||
|
||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserSettingsController.class));
|
||||
|
||||
private final BuilderFactory builderFactory;
|
||||
private final AuditService auditService;
|
||||
private final UserSettingsService settingsService;
|
||||
private final CensorFactory censorFactory;
|
||||
private final QueryFactory queryFactory;
|
||||
private final MessageSource messageSource;
|
||||
|
||||
@Autowired
|
||||
public UserSettingsController(
|
||||
BuilderFactory builderFactory,
|
||||
AuditService auditService,
|
||||
UserSettingsService settingsService,
|
||||
CensorFactory censorFactory,
|
||||
QueryFactory queryFactory,
|
||||
MessageSource messageSource) {
|
||||
this.builderFactory = builderFactory;
|
||||
this.auditService = auditService;
|
||||
this.settingsService = settingsService;
|
||||
this.censorFactory = censorFactory;
|
||||
this.queryFactory = queryFactory;
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
@PostMapping("query")
|
||||
public QueryResult<UserSettings> Query(@RequestBody UserSettingsLookup lookup) throws MyApplicationException, MyForbiddenException {
|
||||
logger.debug("querying {}", UserSettings.class.getSimpleName());
|
||||
this.censorFactory.censor(UserSettingsCensor.class).censor(lookup.getProject(), null);
|
||||
UserSettingsQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrPermission);
|
||||
List<UserSettingsEntity> data = query.collectAs(lookup.getProject());
|
||||
List<UserSettings> models = this.builderFactory.builder(UserSettingsBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(lookup.getProject(), data);
|
||||
long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size();
|
||||
|
||||
this.auditService.track(AuditableAction.User_Settings_Query, "lookup", lookup);
|
||||
//this.auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
|
||||
|
||||
return new QueryResult<>(models, count);
|
||||
}
|
||||
|
||||
@GetMapping("{key}")
|
||||
@Transactional
|
||||
public UserSettings Get(@PathVariable("key") String key) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
|
||||
logger.debug(new MapLogEntry("retrieving" + UserSettings.class.getSimpleName()).And("key", key));
|
||||
|
||||
BaseFieldSet fieldSet = new BaseFieldSet();
|
||||
fieldSet.setFields(Set.of(
|
||||
UserSettings._id,
|
||||
UserSettings._key,
|
||||
UserSettings._value,
|
||||
UserSettings._entityId,
|
||||
UserSettings._createdAt,
|
||||
UserSettings._updatedAt,
|
||||
UserSettings._type
|
||||
));
|
||||
UserSettingsQuery query = this.queryFactory.query(UserSettingsQuery.class).authorize(AuthorizationFlags.OwnerOrPermission).keys(key);
|
||||
UserSettings model = this.builderFactory.builder(UserSettingsBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(fieldSet, query.firstAs(fieldSet));
|
||||
|
||||
this.auditService.track(AuditableAction.User_Settings_Lookup, Map.ofEntries(
|
||||
new AbstractMap.SimpleEntry<String, Object>("key", key)
|
||||
));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
@PostMapping("persist")
|
||||
@Transactional
|
||||
public UserSettings Persist(@MyValidate @RequestBody UserSettingsPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException {
|
||||
logger.debug(new MapLogEntry("persisting" + UserSettings.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
|
||||
|
||||
UserSettings persisted = this.settingsService.persist(model, fieldSet);
|
||||
|
||||
this.auditService.track(AuditableAction.User_Settings_Persist, Map.ofEntries(
|
||||
new AbstractMap.SimpleEntry<String, Object>("model", model),
|
||||
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
|
||||
));
|
||||
//this.auditService.trackIdentity(AuditableAction.IdentityTracking_Action);
|
||||
return persisted;
|
||||
}
|
||||
|
||||
}
|
|
@ -13,7 +13,7 @@ ADD COLUMN "Type" uuid;
|
|||
INSERT INTO public."DescriptionTemplateType" ("ID", "Name", "Status")
|
||||
VALUES ('709a8400-10ca-11ee-be56-0242ac120002', 'Dataset', 1);
|
||||
|
||||
UPDATE public."DescriptionTemplate" SET ("Type") = '709a8400-10ca-11ee-be56-0242ac120002';
|
||||
UPDATE public."DescriptionTemplate" SET "Type" = '709a8400-10ca-11ee-be56-0242ac120002';
|
||||
|
||||
ALTER TABLE public."DescriptionTemplate"
|
||||
ALTER COLUMN "Type" SET NOT NULL;
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
DO $$DECLARE
|
||||
this_version CONSTANT varchar := '00.01.001';
|
||||
BEGIN
|
||||
PERFORM * FROM "DBVersion" WHERE version = this_version;
|
||||
IF FOUND THEN RETURN; END IF;
|
||||
|
||||
ALTER TABLE public."DescriptionTemplateType"
|
||||
RENAME "ID" TO id;
|
||||
|
||||
|
@ -32,3 +38,8 @@ UPDATE public."DescriptionTemplateType" SET status = 0 where is_active = 0;
|
|||
|
||||
ALTER TABLE public."DescriptionTemplateType"
|
||||
ALTER COLUMN is_active SET NOT NULL;
|
||||
|
||||
|
||||
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.001', '2023-10-19 12:00:00.000000+02', now(), 'Align Description Template Type.');
|
||||
|
||||
END$$;
|
|
@ -1,3 +1,9 @@
|
|||
DO $$DECLARE
|
||||
this_version CONSTANT varchar := '00.01.002';
|
||||
BEGIN
|
||||
PERFORM * FROM "DBVersion" WHERE version = this_version;
|
||||
IF FOUND THEN RETURN; END IF;
|
||||
|
||||
ALTER TABLE public."EntityDoi"
|
||||
RENAME "ID" TO id;
|
||||
|
||||
|
@ -21,3 +27,8 @@ ALTER TABLE public."EntityDoi"
|
|||
|
||||
ALTER TABLE public."EntityDoi"
|
||||
ADD COLUMN is_active smallint NOT NULL DEFAULT 1
|
||||
|
||||
|
||||
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.002', '2023-10-19 12:00:00.000000+02', now(), 'Align Entity Doi table.');
|
||||
|
||||
END$$;
|
|
@ -0,0 +1,23 @@
|
|||
DO $$DECLARE
|
||||
this_version CONSTANT varchar := '00.01.003';
|
||||
BEGIN
|
||||
PERFORM * FROM "DBVersion" WHERE version = this_version;
|
||||
IF FOUND THEN RETURN; END IF;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.UserSettings
|
||||
(
|
||||
id uuid NOT NULL,
|
||||
key character varying(500) COLLATE pg_catalog."default" NOT NULL,
|
||||
entity_id uuid,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
type character varying(200) COLLATE pg_catalog."default" NOT NULL,
|
||||
value text COLLATE pg_catalog."default" NOT NULL,
|
||||
name character varying(500) COLLATE pg_catalog."default" NOT NULL,
|
||||
CONSTRAINT user_settings_pkey PRIMARY KEY (id)
|
||||
)
|
||||
|
||||
|
||||
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.003', '2023-10-19 12:00:00.000000+02', now(), 'Add UserSettings table.');
|
||||
|
||||
END$$;
|
|
@ -4,6 +4,7 @@ import { ReloadHelperComponent } from '@app/ui/misc/reload-helper/reload-helper.
|
|||
import { Oauth2DialogComponent } from './ui/misc/oauth2-dialog/oauth2-dialog.component';
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppPermission } from './core/common/enum/permission.enum';
|
||||
import { BreadcrumbService } from './ui/misc/breadcrumb/breadcrumb.service';
|
||||
|
||||
const appRoutes: Routes = [
|
||||
{
|
||||
|
@ -11,7 +12,10 @@ const appRoutes: Routes = [
|
|||
component: AppComponent,
|
||||
data: {
|
||||
breadcrumbs: false,
|
||||
title: 'GENERAL.TITLES.GENERAL'
|
||||
title: 'GENERAL.TITLES.GENERAL',
|
||||
...BreadcrumbService.generateRouteDataConfiguration({
|
||||
title: 'BREADCRUMBS.HOME'
|
||||
})
|
||||
},
|
||||
pathMatch: 'full'
|
||||
},
|
||||
|
@ -75,8 +79,8 @@ const appRoutes: Routes = [
|
|||
}
|
||||
},
|
||||
{
|
||||
path: 'dmp-profiles',
|
||||
loadChildren: () => import('./ui/admin/dmp-profile/dmp-profile.module').then(m => m.DmpProfileModule),
|
||||
path: 'dmp-blueprints',
|
||||
loadChildren: () => import('./ui/admin/dmp-blueprint/dmp-blueprint.module').then(m => m.DmpBlueprintModule),
|
||||
data: {
|
||||
breadcrumb: true,
|
||||
title: 'GENERAL.TITLES.DMP-BLUEPRINTS'
|
||||
|
@ -99,14 +103,17 @@ const appRoutes: Routes = [
|
|||
}
|
||||
},
|
||||
{
|
||||
path: 'description-types',
|
||||
loadChildren: () => import('./ui/admin/description-types/description-types.module').then(m => m.DescriptionTypesModule),
|
||||
path: 'description-template-type',
|
||||
loadChildren: () => import('./ui/admin/description-types/description-template-type.module').then(m => m.DescriptionTemplateTypesModule),
|
||||
data: {
|
||||
breadcrumb: true,
|
||||
title: 'GENERAL.TITLES.DESCRIPTION-TYPES',
|
||||
title: 'GENERAL.TITLES.DESCRIPTION-TEMPLATE-TYPES',
|
||||
authContext: {
|
||||
permissions: [AppPermission.ViewDescriptionTemplateTypePage]
|
||||
}
|
||||
},
|
||||
...BreadcrumbService.generateRouteDataConfiguration({
|
||||
title: 'BREADCRUMBS.DESCRIPTION-TEMPLATE-TYPES'
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@ import { TranslateService } from '@ngx-translate/core';
|
|||
import { environment } from '../environments/environment';
|
||||
import { AuthService } from './core/services/auth/auth.service';
|
||||
import { CultureService } from './core/services/culture/culture-service';
|
||||
import { BreadCrumbResolverService } from './ui/misc/breadcrumb/service/breadcrumb.service';
|
||||
// import { BreadCrumbResolverService } from './ui/misc/breadcrumb/service/breadcrumb.service';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { NgcCookieConsentService, NgcStatusChangeEvent } from "ngx-cookieconsent";
|
||||
import { CookieService } from "ngx-cookie-service";
|
||||
|
@ -19,6 +19,7 @@ import { Location } from '@angular/common';
|
|||
import { MatomoService } from './core/services/matomo/matomo-service';
|
||||
import { SideNavService } from './core/services/sidenav/side-nav.sevice';
|
||||
import { MatSidenav } from '@angular/material/sidenav';
|
||||
import { TimezoneService } from './core/services/timezone/timezone-service';
|
||||
|
||||
|
||||
declare const gapi: any;
|
||||
|
@ -45,9 +46,10 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||
private route: ActivatedRoute,
|
||||
private authentication: AuthService,
|
||||
private translate: TranslateService,
|
||||
private breadCrumbResolverService: BreadCrumbResolverService,
|
||||
// private breadCrumbResolverService: BreadCrumbResolverService,
|
||||
private titleService: Title,
|
||||
private cultureService: CultureService,
|
||||
private timezoneService: TimezoneService,
|
||||
private cookieService: CookieService,
|
||||
private ccService: NgcCookieConsentService,
|
||||
private language: LanguageService,
|
||||
|
@ -96,7 +98,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||
}
|
||||
|
||||
onActivate(event: any) {
|
||||
this.breadCrumbResolverService.push(event);
|
||||
// this.breadCrumbResolverService.push(event);
|
||||
}
|
||||
|
||||
onDeactivate(event: any) {
|
||||
|
@ -225,6 +227,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||
initializeServices() {
|
||||
this.translate.setDefaultLang(this.configurationService.defaultLanguage || 'en');
|
||||
this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileCulture() ? this.cultureService.cultureSelected(this.authentication.getUserProfileCulture()) : this.cultureService.cultureSelected(this.configurationService.defaultCulture);
|
||||
this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileTimezone() ? this.timezoneService.timezoneSelected(this.authentication.getUserProfileTimezone()) : this.timezoneService.timezoneSelected(this.configurationService.defaultTimezone);
|
||||
this.authentication.currentAccountIsAuthenticated() && this.authentication.getUserProfileLanguage() ? this.language.changeLanguage(this.authentication.getUserProfileLanguage()) : (this.configurationService.defaultLanguage || 'en');
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import { CoreServiceModule } from '@app/core/core-service.module';
|
|||
import { NotificationModule } from '@app/library/notification/notification.module';
|
||||
import { LoginModule } from '@app/ui/auth/login/login.module';
|
||||
import { DatasetCreateWizardModule } from '@app/ui/dataset-create-wizard/dataset-create-wizard.module';
|
||||
import { BreadcrumbModule } from '@app/ui/misc/breadcrumb/breadcrumb.module';
|
||||
// import { BreadcrumbModule } from '@app/ui/misc/breadcrumb/breadcrumb.module';
|
||||
import { HelpContentModule } from '@app/ui/misc/help-content/help-content.module';
|
||||
import { NavigationModule } from '@app/ui/misc/navigation/navigation.module';
|
||||
import { ReloadHelperComponent } from '@app/ui/misc/reload-helper/reload-helper.component';
|
||||
|
@ -137,7 +137,7 @@ export function InstallationConfigurationFactory(appConfig: ConfigurationService
|
|||
//Ui
|
||||
NotificationModule,
|
||||
NavigationModule,
|
||||
BreadcrumbModule,
|
||||
// BreadcrumbModule,
|
||||
HelpContentModule,
|
||||
ReactiveFormsModule,
|
||||
FormsModule,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
export enum DescriptionTemplateTypeStatus {
|
||||
Draft = 0,
|
||||
Finalized = 1,
|
||||
Deleted = 99
|
||||
Draft = 'Draft',
|
||||
Finalized = 'Finalized'
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
export enum DmpProfileFieldDataType {
|
||||
export enum DmpBlueprintFieldDataType {
|
||||
Date = 0,
|
||||
Number = 1,
|
||||
Text = 2,
|
|
@ -0,0 +1,4 @@
|
|||
export enum DmpBlueprintStatus {
|
||||
Draft = 'Draft',
|
||||
Finalized = 'Finalized'
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export enum DmpBlueprintType {
|
||||
Input = 0
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
export enum DmpProfileStatus {
|
||||
Draft = 0,
|
||||
Finalized = 1,
|
||||
Deleted = 99
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
export enum DmpProfileType {
|
||||
Input = 0
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export enum IsActive {
|
||||
Inactive = 0,
|
||||
Active = 1
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
import { HttpClient } from '@angular/common/http';
|
||||
import { APP_INITIALIZER, ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
|
||||
import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
|
||||
import { PrefillingService } from "@app/core/services/prefilling.service";
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
import { AdminAuthGuard } from './admin-auth-guard.service';
|
||||
import { AuthGuard } from './auth-guard.service';
|
||||
import { AuthService } from './services/auth/auth.service';
|
||||
import { ConfigurationService } from './services/configuration/configuration.service';
|
||||
import { ContactSupportService } from './services/contact-support/contact-support.service';
|
||||
import { CultureService } from './services/culture/culture-service';
|
||||
import { LanguageInfoService } from './services/culture/language-info-service';
|
||||
|
@ -14,8 +13,10 @@ import { DatasetProfileService } from './services/dataset-profile/dataset-profil
|
|||
import { DatasetWizardService } from './services/dataset-wizard/dataset-wizard.service';
|
||||
import { DatasetExternalAutocompleteService } from './services/dataset/dataset-external-autocomplete.service';
|
||||
import { DatasetService } from './services/dataset/dataset.service';
|
||||
import { DepositRepositoriesService } from './services/deposit-repositories/deposit-repositories.service';
|
||||
import { DescriptionTemplateTypeService } from './services/description-template-type/description-template-type.service';
|
||||
import { DmpBlueprintService } from './services/dmp/dmp-blueprint.service';
|
||||
import { DmpInvitationService } from './services/dmp/dmp-invitation.service';
|
||||
import { DmpProfileService } from './services/dmp/dmp-profile.service';
|
||||
import { DmpService } from './services/dmp/dmp.service';
|
||||
import { EmailConfirmationService } from './services/email-confirmation/email-confirmation.service';
|
||||
import { ExternalDataRepositoryService } from './services/external-sources/data-repository/extternal-data-repository.service';
|
||||
|
@ -28,6 +29,7 @@ import { ExternalServiceService } from './services/external-sources/service/exte
|
|||
import { FunderService } from './services/funder/funder.service';
|
||||
import { GrantFileUploadService } from './services/grant/grant-file-upload.service';
|
||||
import { GrantService } from './services/grant/grant.service';
|
||||
import { BaseHttpV2Service } from './services/http/base-http-v2.service';
|
||||
import { BaseHttpService } from './services/http/base-http.service';
|
||||
import { LanguageService } from './services/language/language.service';
|
||||
import { LockService } from './services/lock/lock.service';
|
||||
|
@ -40,21 +42,19 @@ import { ProjectService } from './services/project/project.service';
|
|||
import { QuickWizardService } from './services/quick-wizard/quick-wizard.service';
|
||||
import { SearchBarService } from './services/search-bar/search-bar.service';
|
||||
import { TimezoneService } from './services/timezone/timezone-service';
|
||||
import { UnlinkAccountEmailConfirmationService } from './services/unlink-account-email-confirmation/unlink-account-email-confirmation.service';
|
||||
import { UserService } from './services/user/user.service';
|
||||
import { CollectionUtils } from './services/utilities/collection-utils.service';
|
||||
import { TypeUtils } from './services/utilities/type-utils.service';
|
||||
import { SpecialAuthGuard } from './special-auth-guard.service';
|
||||
import {PrefillingService} from "@app/core/services/prefilling.service";
|
||||
import { DepositRepositoriesService } from './services/deposit-repositories/deposit-repositories.service';
|
||||
import { UnlinkAccountEmailConfirmationService } from './services/unlink-account-email-confirmation/unlink-account-email-confirmation.service';
|
||||
import { DescriptionTemplateTypeService } from './services/description-template-type/description-template-type.service';
|
||||
import { BaseHttpV2Service } from './services/http/base-http-v2.service';
|
||||
//import { KeycloakService } from 'keycloak-angular';
|
||||
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||
import { FilterService } from '@common/modules/text-filter/filter-service';
|
||||
import { PrincipalService } from './services/http/principal.service';
|
||||
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
||||
import { BaseHttpParams } from '@common/http/base-http-params';
|
||||
import { from } from 'rxjs';
|
||||
import { SupportiveMaterialService } from './services/supportive-material/supportive-material.service';
|
||||
import { UserSettingsHttpService } from './services/user-settings/user-settings-http.service';
|
||||
import { UserSettingsService } from './services/user-settings/user-settings.service';
|
||||
import { QueryParamsService } from './services/utilities/query-params.service';
|
||||
//
|
||||
//
|
||||
// This is shared module that provides all the services. Its imported only once on the AppModule.
|
||||
|
@ -96,7 +96,7 @@ export class CoreServiceModule {
|
|||
GrantFileUploadService,
|
||||
DmpService,
|
||||
DepositRepositoriesService,
|
||||
DmpProfileService,
|
||||
DmpBlueprintService,
|
||||
ExternalSourcesService,
|
||||
ExternalSourcesConfigurationService,
|
||||
DatasetService,
|
||||
|
@ -123,7 +123,12 @@ export class CoreServiceModule {
|
|||
UnlinkAccountEmailConfirmationService,
|
||||
LanguageInfoService,
|
||||
PrefillingService,
|
||||
DescriptionTemplateTypeService
|
||||
DescriptionTemplateTypeService,
|
||||
HttpErrorHandlingService,
|
||||
QueryParamsService,
|
||||
UserSettingsService,
|
||||
UserSettingsHttpService,
|
||||
FilterService
|
||||
],
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { DateTimeCultureFormatPipe } from './pipes/date-time-culture-format.pipe
|
|||
import {FieldValuePipe} from "@app/core/pipes/field-value.pipe";
|
||||
import {ColumnClassPipe} from "@app/core/pipes/column-class.pipe";
|
||||
import { DatasetInSectioPipe } from './pipes/dataset-in-section.pipe';
|
||||
import { PipeService } from '@common/formatting/pipe.service';
|
||||
|
||||
//
|
||||
//
|
||||
|
@ -27,7 +28,7 @@ import { DatasetInSectioPipe } from './pipes/dataset-in-section.pipe';
|
|||
JsonParserPipe,
|
||||
FieldValuePipe,
|
||||
ColumnClassPipe,
|
||||
DatasetInSectioPipe
|
||||
DatasetInSectioPipe,
|
||||
],
|
||||
exports: [
|
||||
NgForLimitPipe,
|
||||
|
@ -43,6 +44,7 @@ import { DatasetInSectioPipe } from './pipes/dataset-in-section.pipe';
|
|||
providers: [
|
||||
EnumUtils,
|
||||
DatePipe,
|
||||
PipeService,
|
||||
NgForLimitPipe,
|
||||
TimezoneInfoDisplayPipe,
|
||||
DateFormatPipe,
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
export interface DescriptionTemplateType {
|
||||
id: string;
|
||||
import { DescriptionTemplateTypeStatus } from "@app/core/common/enum/description-template-type-status";
|
||||
import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model";
|
||||
|
||||
export interface DescriptionTemplateType extends BaseEntity {
|
||||
name: string;
|
||||
status: number;
|
||||
status: DescriptionTemplateTypeStatus;
|
||||
}
|
||||
|
||||
export interface DescriptionTemplateTypePersist extends BaseEntityPersist {
|
||||
name: string;
|
||||
status: DescriptionTemplateTypeStatus;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
export interface DmpProfileExternalAutoCompleteField {
|
||||
export interface DmpBlueprintExternalAutoCompleteField {
|
||||
url: string;
|
||||
optionsRoot: string;
|
||||
multiAutoComplete: boolean;
|
|
@ -0,0 +1,13 @@
|
|||
import { DmpBlueprintFieldDataType } from '../../common/enum/dmp-blueprint-field-type';
|
||||
import { DmpBlueprintType } from '../../common/enum/dmp-blueprint-type';
|
||||
import { DmpBlueprintExternalAutoCompleteFieldDataEditorModel } from '../../../ui/admin/dmp-blueprint/editor/external-autocomplete/dmp-blueprint-external-autocomplete-field-editor.model';
|
||||
|
||||
export interface DmpBlueprintField {
|
||||
id: string;
|
||||
type: DmpBlueprintType;
|
||||
dataType: DmpBlueprintFieldDataType;
|
||||
required: boolean;
|
||||
label: string;
|
||||
value: any;
|
||||
externalAutocomplete?: DmpBlueprintExternalAutoCompleteFieldDataEditorModel;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
import { DmpBlueprintDefinition } from "../dmp/dmp-blueprint/dmp-blueprint";
|
||||
|
||||
export interface DmpBlueprintListing {
|
||||
id: string;
|
||||
label: string;
|
||||
definition: DmpBlueprintDefinition;
|
||||
status: number;
|
||||
created: Date;
|
||||
modified: Date;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import { DmpBlueprintStatus } from "@app/core/common/enum/dmp-blueprint-status";
|
||||
import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model";
|
||||
import { DmpBlueprintDefinition } from "../dmp/dmp-blueprint/dmp-blueprint";
|
||||
|
||||
|
||||
export interface DmpBlueprint extends BaseEntity {
|
||||
label: string;
|
||||
definition: DmpBlueprintDefinition;
|
||||
status: DmpBlueprintStatus;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface DmpBlueprintPersist extends BaseEntityPersist {
|
||||
label: string;
|
||||
definition: DmpBlueprintDefinition;
|
||||
status: number;
|
||||
description: string;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
import { DmpProfileFieldDataType } from '../../common/enum/dmp-profile-field-type';
|
||||
import { DmpProfileType } from '../../common/enum/dmp-profile-type';
|
||||
import { DmpProfileExternalAutoCompleteFieldDataEditorModel } from '../../../ui/admin/dmp-profile/editor/external-autocomplete/dmp-profile-external-autocomplete-field-editor.model';
|
||||
|
||||
export interface DmpProfileField {
|
||||
id: string;
|
||||
type: DmpProfileType;
|
||||
dataType: DmpProfileFieldDataType;
|
||||
required: boolean;
|
||||
label: string;
|
||||
value: any;
|
||||
externalAutocomplete?: DmpProfileExternalAutoCompleteFieldDataEditorModel;
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import { DmpProfileDefinition } from "./dmp-profile";
|
||||
|
||||
export interface DmpProfileListing {
|
||||
id: string;
|
||||
label: string;
|
||||
definition: DmpProfileDefinition;
|
||||
status: number;
|
||||
created: Date;
|
||||
modified: Date;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import { DmpProfileField } from "./dmp-profile-field";
|
||||
|
||||
|
||||
export interface DmpProfile {
|
||||
id: string;
|
||||
label: string;
|
||||
definition: DmpProfileDefinition;
|
||||
status: number;
|
||||
created: Date;
|
||||
modified: Date;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface DmpProfileDefinition {
|
||||
fields: DmpProfileField[];
|
||||
}
|
|
@ -1,68 +1,72 @@
|
|||
import { DmpBlueprintStatus } from "@app/core/common/enum/dmp-blueprint-status";
|
||||
import { DmpBlueprintField } from "../../dmp-blueprint/dmp-blueprint-field";
|
||||
|
||||
export interface DmpBlueprint {
|
||||
id: string;
|
||||
label: string;
|
||||
definition: DmpBlueprintDefinition;
|
||||
status: number;
|
||||
status: DmpBlueprintStatus;
|
||||
created: Date;
|
||||
modified: Date;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface DmpBlueprintDefinition {
|
||||
sections: SectionDmpBlueprint[];
|
||||
sections: SectionDmpBlueprint[];
|
||||
fields: DmpBlueprintField[];
|
||||
}
|
||||
|
||||
export interface SectionDmpBlueprint {
|
||||
id: string;
|
||||
label: string;
|
||||
description: string;
|
||||
ordinal: number;
|
||||
fields: FieldInSection[];
|
||||
hasTemplates: boolean;
|
||||
descriptionTemplates?: DescriptionTemplatesInSection[];
|
||||
id: string;
|
||||
label: string;
|
||||
description: string;
|
||||
ordinal: number;
|
||||
fields: FieldInSection[];
|
||||
hasTemplates: boolean;
|
||||
descriptionTemplates?: DescriptionTemplatesInSection[];
|
||||
}
|
||||
|
||||
export interface FieldInSection {
|
||||
id: string;
|
||||
category: FieldCategory;
|
||||
type: number;
|
||||
label: string;
|
||||
placeholder: string;
|
||||
description: string;
|
||||
required: boolean;
|
||||
ordinal: number;
|
||||
id: string;
|
||||
category: FieldCategory;
|
||||
type: number;
|
||||
label: string;
|
||||
placeholder: string;
|
||||
description: string;
|
||||
required: boolean;
|
||||
ordinal: number;
|
||||
}
|
||||
|
||||
export enum FieldCategory {
|
||||
SYSTEM = 0,
|
||||
EXTRA = 1
|
||||
SYSTEM = 0,
|
||||
EXTRA = 1
|
||||
}
|
||||
|
||||
export enum SystemFieldType {
|
||||
TEXT = 0,
|
||||
HTML_TEXT = 1,
|
||||
RESEARCHERS= 2,
|
||||
ORGANIZATIONS = 3,
|
||||
LANGUAGE = 4,
|
||||
CONTACT = 5,
|
||||
FUNDER = 6,
|
||||
GRANT = 7,
|
||||
PROJECT = 8,
|
||||
LICENSE = 9,
|
||||
ACCESS_RIGHTS = 10
|
||||
TEXT = 0,
|
||||
HTML_TEXT = 1,
|
||||
RESEARCHERS = 2,
|
||||
ORGANIZATIONS = 3,
|
||||
LANGUAGE = 4,
|
||||
CONTACT = 5,
|
||||
FUNDER = 6,
|
||||
GRANT = 7,
|
||||
PROJECT = 8,
|
||||
LICENSE = 9,
|
||||
ACCESS_RIGHTS = 10
|
||||
}
|
||||
|
||||
export interface DescriptionTemplatesInSection {
|
||||
id: string;
|
||||
descriptionTemplateId: string;
|
||||
label: string;
|
||||
minMultiplicity: number;
|
||||
maxMultiplicity: number;
|
||||
id: string;
|
||||
descriptionTemplateId: string;
|
||||
label: string;
|
||||
minMultiplicity: number;
|
||||
maxMultiplicity: number;
|
||||
}
|
||||
|
||||
export enum ExtraFieldType {
|
||||
TEXT = 0,
|
||||
RICH_TEXT = 1,
|
||||
DATE = 2,
|
||||
NUMBER = 3
|
||||
TEXT = 0,
|
||||
RICH_TEXT = 1,
|
||||
DATE = 2,
|
||||
NUMBER = 3
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { DmpStatus } from "../../common/enum/dmp-status";
|
||||
import { DmpAssociatedProfileModel } from '../dmp-profile/dmp-associated-profile';
|
||||
import { DmpAssociatedProfileModel } from '../dmp-blueprint/dmp-associated-profile';
|
||||
|
||||
export interface DmpListingModel {
|
||||
id: string;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { OrganizationModel } from "../organisation/organization";
|
||||
import { UserInfoListingModel } from "../user/user-info-listing";
|
||||
import { DmpAssociatedProfileModel } from "../dmp-profile/dmp-associated-profile";
|
||||
import { DmpAssociatedProfileModel } from "../dmp-blueprint/dmp-associated-profile";
|
||||
import { ResearcherModel } from "../researcher/researcher";
|
||||
import { GrantOverviewModel } from "../grant/grant-overview";
|
||||
import { DatasetOverviewModel } from "../dataset/dataset-overview";
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
import { DmpProfileDefinition } from "../dmp-profile/dmp-profile";
|
||||
import { OrganizationModel } from "../organisation/organization";
|
||||
import { GrantListingModel } from "../grant/grant-listing";
|
||||
import { ResearcherModel } from "../researcher/researcher";
|
||||
import { UserModel } from "../user/user";
|
||||
import { DmpDynamicField } from "./dmp-dynamic-field";
|
||||
import { UserInfoListingModel } from "../user/user-info-listing";
|
||||
import { ProjectModel } from "../project/project";
|
||||
import { FunderModel } from "../funder/funder";
|
||||
import { DmpStatus } from '@app/core/common/enum/dmp-status';
|
||||
import { DatasetWizardModel } from '../dataset/dataset-wizard';
|
||||
import { FunderModel } from "../funder/funder";
|
||||
import { GrantListingModel } from "../grant/grant-listing";
|
||||
import { OrganizationModel } from "../organisation/organization";
|
||||
import { ProjectModel } from "../project/project";
|
||||
import { ResearcherModel } from "../researcher/researcher";
|
||||
import { UserModel } from "../user/user";
|
||||
import { UserInfoListingModel } from "../user/user-info-listing";
|
||||
import { DmpDatasetProfile } from "./dmp-dataset-profile/dmp-dataset-profile";
|
||||
import { DmpDynamicField } from "./dmp-dynamic-field";
|
||||
import { DmpExtraField } from "./dmp-extra-field";
|
||||
|
||||
export interface DmpModel {
|
||||
id: string;
|
||||
label: string;
|
||||
groupId: String;
|
||||
profile: DmpProfile;
|
||||
profile: DmpBlueprint;
|
||||
version: number;
|
||||
status: DmpStatus;
|
||||
lockable: boolean;
|
||||
|
@ -40,7 +39,7 @@ export interface DmpModel {
|
|||
}
|
||||
|
||||
|
||||
export interface DmpProfile {
|
||||
export interface DmpBlueprint {
|
||||
id: string;
|
||||
label: string;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { RecentActivityModel } from './recent-activity.model';
|
||||
import { RecentDatasetModel } from './recent-dataset-activity.model';
|
||||
import { DmpAssociatedProfileModel } from '../dmp-profile/dmp-associated-profile';
|
||||
import { DmpAssociatedProfileModel } from '../dmp-blueprint/dmp-associated-profile';
|
||||
import { UserInfoListingModel } from '../user/user-info-listing';
|
||||
import { DatasetUrlListing } from '../dataset/dataset-url-listing';
|
||||
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import { UserSettingsType } from '@app/core/services/user-settings/user-settings.service';
|
||||
import { Guid } from '@common/types/guid';
|
||||
|
||||
export interface UserSetting {
|
||||
id: Guid;
|
||||
name: string;
|
||||
type: UserSettingsType;
|
||||
value: any;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
hash: string;
|
||||
userId: Guid;
|
||||
isDefault?: boolean;
|
||||
}
|
||||
|
||||
export interface UserSettings {
|
||||
key: string;
|
||||
settings: UserSetting[];
|
||||
defaultSetting: UserSetting;
|
||||
}
|
||||
|
||||
export interface UserSettingPersist {
|
||||
id: Guid;
|
||||
name: string;
|
||||
key: string;
|
||||
type: UserSettingsType;
|
||||
value: string;
|
||||
hash: string;
|
||||
isDefault: boolean;
|
||||
}
|
||||
|
||||
export interface UserSettingsKey {
|
||||
key: string;
|
||||
}
|
||||
|
||||
//TODO possible move these
|
||||
export interface UserSettingsInformation<T> {
|
||||
key: string;
|
||||
type: UserSettingsBuilder<T>;
|
||||
}
|
||||
|
||||
export type UserSettingsBuilder<T> = new () => T;
|
||||
|
||||
export interface UserSettingsLookupBuilder<T> {
|
||||
update(lookup: T);
|
||||
apply(lookup: T): T;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import { Lookup } from "@common/model/lookup";
|
||||
import { Guid } from "@common/types/guid";
|
||||
import { IsActive } from "../common/enum/is-active.enum";
|
||||
|
||||
export class DescriptionTemplateTypeLookup extends Lookup implements DescriptionTemplateTypeFilter {
|
||||
ids: Guid[];
|
||||
excludedIds: Guid[];
|
||||
like: string;
|
||||
isActive: IsActive[];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export interface DescriptionTemplateTypeFilter {
|
||||
ids: Guid[];
|
||||
excludedIds: Guid[];
|
||||
like: string;
|
||||
isActive: IsActive[];
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
import { Status } from "@app/core/common/enum/status";
|
||||
import { Lookup } from "@common/model/lookup";
|
||||
import { Guid } from "@common/types/guid";
|
||||
|
||||
export class DescriptionTemplateTypeLookup extends Lookup {
|
||||
ids: Guid[];
|
||||
excludedIds: Guid[];
|
||||
like: string;
|
||||
isActive: Status[];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import { Lookup } from '@common/model/lookup';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { IsActive } from '../common/enum/is-active.enum';
|
||||
|
||||
export class DmpBlueprintLookup extends Lookup implements DmpBlueprintFilter {
|
||||
ids: Guid[];
|
||||
excludedIds: Guid[];
|
||||
like: string;
|
||||
isActive: IsActive[];
|
||||
typeIds: Guid[];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
export interface DmpBlueprintFilter {
|
||||
ids: Guid[];
|
||||
excludedIds: Guid[];
|
||||
like: string;
|
||||
isActive: IsActive[];
|
||||
typeIds: Guid[];
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import { DmpBlueprintStatus } from "@app/core/common/enum/dmp-blueprint-status";
|
||||
import { BaseCriteria } from "../base-criteria";
|
||||
|
||||
export class DmpBlueprintCriteria extends BaseCriteria {
|
||||
public status?: number;
|
||||
public status?: DmpBlueprintStatus;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { BaseCriteria } from "../base-criteria";
|
||||
|
||||
export class DmpProfileCriteria extends BaseCriteria {
|
||||
export class DmpBlueprintCriteria extends BaseCriteria {
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { BaseCriteria } from "../base-criteria";
|
||||
|
||||
export class DmpProfileExternalAutocompleteCriteria extends BaseCriteria {
|
||||
export class DmpBlueprintExternalAutocompleteCriteria extends BaseCriteria {
|
||||
public profileID: String;
|
||||
public fieldID: String;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ export enum LoginStatus {
|
|||
@Injectable()
|
||||
export class AuthService extends BaseService {
|
||||
|
||||
public permissionEnum = AppPermission;
|
||||
public authenticationStateSubject: Subject<AuthenticationState>;
|
||||
private accessToken: string;
|
||||
private appAccount: AppAccount;
|
||||
|
|
|
@ -36,6 +36,11 @@ export class ConfigurationService extends BaseComponent {
|
|||
return this._defaultCulture;
|
||||
}
|
||||
|
||||
private _defaultTimezone: string;
|
||||
get defaultTimezone(): string {
|
||||
return this._defaultTimezone || 'UTC';
|
||||
}
|
||||
|
||||
private _defaultLanguage: string;
|
||||
get defaultLanguage(): string {
|
||||
return this._defaultLanguage;
|
||||
|
@ -102,6 +107,11 @@ export class ConfigurationService extends BaseComponent {
|
|||
return this._keycloak;
|
||||
}
|
||||
|
||||
private _userSettingsVersion: string;
|
||||
get userSettingsVersion(): string {
|
||||
return this._userSettingsVersion;
|
||||
}
|
||||
|
||||
|
||||
public loadConfiguration(): Promise<any> {
|
||||
return new Promise((r, e) => {
|
||||
|
@ -143,6 +153,7 @@ export class ConfigurationService extends BaseComponent {
|
|||
this._app = config.App;
|
||||
this._helpService = HelpService.parseValue(config.HelpService);
|
||||
this._defaultCulture = config.defaultCulture;
|
||||
this._defaultTimezone = config.defaultTimezone;
|
||||
this._defaultLanguage = config.defaultLanguage;
|
||||
this._availableLanguages = config.availableLanguages;
|
||||
this._keycloak = KeycloakConfiguration.parseValue(config.keycloak);
|
||||
|
@ -158,6 +169,7 @@ export class ConfigurationService extends BaseComponent {
|
|||
this._matomoSiteId = config.matomo.siteId;
|
||||
}
|
||||
this._maxFileSizeInMB = config.maxFileSizeInMB;
|
||||
this._userSettingsVersion = config.userSettingsVersion;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,42 +1,49 @@
|
|||
import { HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ConfigurationService } from '../configuration/configuration.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type';
|
||||
import { DescriptionTemplateType, DescriptionTemplateTypePersist } from '@app/core/model/description-template-type/description-template-type';
|
||||
import { DescriptionTemplateTypeLookup } from '@app/core/query/description-template-type.lookup';
|
||||
import { QueryResult } from '@common/model/query-result';
|
||||
import { DescriptionTemplateTypeLookup } from '@app/core/query/description-template/description-template-type.lookup';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { ConfigurationService } from '../configuration/configuration.service';
|
||||
import { BaseHttpV2Service } from '../http/base-http-v2.service';
|
||||
|
||||
@Injectable()
|
||||
export class DescriptionTemplateTypeService {
|
||||
|
||||
private get apiBase(): string { return `${this.configurationService.server}description-template-type`; }
|
||||
private headers = new HttpHeaders();
|
||||
constructor(private http: BaseHttpV2Service, private installationConfiguration: ConfigurationService) { }
|
||||
|
||||
constructor(private http: BaseHttpV2Service, private configurationService: ConfigurationService) {}
|
||||
private get apiBase(): string { return `${this.installationConfiguration.server}description-template-type`; }
|
||||
|
||||
query(lookup: DescriptionTemplateTypeLookup): Observable<QueryResult<DescriptionTemplateType>> {
|
||||
const url = `${this.apiBase}/query`;
|
||||
return this.http.post<QueryResult<DescriptionTemplateType>>(url, lookup, { headers: this.headers });
|
||||
}
|
||||
query(q: DescriptionTemplateTypeLookup): Observable<QueryResult<DescriptionTemplateType>> {
|
||||
const url = `${this.apiBase}/query`;
|
||||
return this.http
|
||||
.post<QueryResult<DescriptionTemplateType>>(url, q).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
get(id: string): Observable<QueryResult<DescriptionTemplateType>> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
return this.http.get<QueryResult<DescriptionTemplateType>>(url , { headers: this.headers });
|
||||
}
|
||||
getSingle(id: Guid, reqFields: string[] = []): Observable<DescriptionTemplateType> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
const options = { params: { f: reqFields } };
|
||||
|
||||
persist(payload: DescriptionTemplateType): Observable<QueryResult<DescriptionTemplateType>> {
|
||||
const url = `${this.apiBase}/persist`;
|
||||
return this.http.post<QueryResult<DescriptionTemplateType>>(url, payload, { headers: this.headers });
|
||||
}
|
||||
return this.http
|
||||
.get<DescriptionTemplateType>(url, options).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
update(payload: DescriptionTemplateType): Observable<QueryResult<DescriptionTemplateType>> {
|
||||
const url = `${this.apiBase}/update`;
|
||||
return this.http.post<QueryResult<DescriptionTemplateType>>(url, payload, { headers: this.headers });
|
||||
}
|
||||
persist(item: DescriptionTemplateTypePersist): Observable<DescriptionTemplateType> {
|
||||
const url = `${this.apiBase}/persist`;
|
||||
|
||||
delete(id: string): Observable<void> {
|
||||
const url = `${this.apiBase}/delete/${id}`;
|
||||
return this.http.delete<void>(url, { headers: this.headers });
|
||||
}
|
||||
return this.http
|
||||
.post<DescriptionTemplateType>(url, item).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
delete(id: Guid): Observable<DescriptionTemplateType> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
|
||||
return this.http
|
||||
.delete<DescriptionTemplateType>(url).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { DataTableData } from '@app/core/model/data-table/data-table-data';
|
||||
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
|
||||
import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing';
|
||||
import { DmpBlueprint, DmpBlueprintPersist } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||
import { DmpBlueprintListing } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing';
|
||||
import { DmpBlueprintLookup } from '@app/core/query/dmp-blueprint.lookup';
|
||||
import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria';
|
||||
import { DmpBlueprintExternalAutocompleteCriteria } from '@app/core/query/dmp/dmp-profile-external-autocomplete-criteria';
|
||||
import { RequestItem } from '@app/core/query/request-item';
|
||||
import { BaseHttpParams } from '@common/http/base-http-params';
|
||||
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
|
||||
import { QueryResult } from '@common/model/query-result';
|
||||
import { Observable, throwError } from 'rxjs';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { ConfigurationService } from '../configuration/configuration.service';
|
||||
import { BaseHttpV2Service } from '../http/base-http-v2.service';
|
||||
import { Guid } from '@common/types/guid';
|
||||
|
||||
@Injectable()
|
||||
export class DmpBlueprintService {
|
||||
|
||||
private actionUrl: string;
|
||||
private headers = new HttpHeaders();
|
||||
|
||||
constructor(private http: BaseHttpV2Service, private httpClient: HttpClient, private configurationService: ConfigurationService) {
|
||||
this.actionUrl = configurationService.server + 'dmpprofile/';
|
||||
}
|
||||
|
||||
private get apiBase(): string { return `${this.configurationService.server}dmpprofile`; }
|
||||
|
||||
query(q: DmpBlueprintLookup): Observable<QueryResult<DmpBlueprint>> {
|
||||
const url = `${this.apiBase}/query`;
|
||||
return this.http.post<QueryResult<DmpBlueprint>>(url, q).pipe(catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
getSingle(id: Guid, reqFields: string[] = []): Observable<DmpBlueprint> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
const options = { params: { f: reqFields } };
|
||||
|
||||
return this.http
|
||||
.get<DmpBlueprint>(url, options).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
persist(item: DmpBlueprintPersist): Observable<DmpBlueprint> {
|
||||
const url = `${this.apiBase}/persist`;
|
||||
|
||||
return this.http
|
||||
.post<DmpBlueprint>(url, item).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
delete(id: Guid): Observable<DmpBlueprint> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
|
||||
return this.http
|
||||
.delete<DmpBlueprint>(url).pipe(
|
||||
catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
getPaged(dataTableRequest: DataTableRequest<DmpBlueprintCriteria>): Observable<DataTableData<DmpBlueprintListing>> {
|
||||
return this.http.post<DataTableData<DmpBlueprintListing>>(this.actionUrl + 'getPaged', dataTableRequest, { headers: this.headers });
|
||||
}
|
||||
|
||||
getPagedBlueprint(dataTableRequest: DataTableRequest<DmpBlueprintCriteria>): Observable<DataTableData<DmpBlueprintListing>> {
|
||||
return this.http.post<DataTableData<DmpBlueprintListing>>(this.actionUrl + 'getPagedBlueprint', dataTableRequest, { headers: this.headers });
|
||||
}
|
||||
|
||||
getSingleBlueprint(id: String): Observable<DmpBlueprintListing> {
|
||||
return this.http.get<DmpBlueprintListing>(this.actionUrl + 'getSingleBlueprint/' + id, { headers: this.headers });
|
||||
}
|
||||
|
||||
createDmp(dataManagementPlanModel: DmpBlueprint): Observable<DmpBlueprint> {
|
||||
return this.http.post<DmpBlueprint>(this.actionUrl, dataManagementPlanModel, { headers: this.headers });
|
||||
}
|
||||
|
||||
createBlueprint(dmpBlueprint: DmpBlueprint): Observable<DmpBlueprint> {
|
||||
return this.http.post<DmpBlueprint>(this.actionUrl + 'blueprint', dmpBlueprint, { headers: this.headers });
|
||||
}
|
||||
|
||||
public downloadXML(id: string): Observable<HttpResponse<Blob>> {
|
||||
let headerXml: HttpHeaders = this.headers.set('Content-Type', 'application/xml')
|
||||
return this.httpClient.get(this.actionUrl + 'getXml/' + id, { responseType: 'blob', observe: 'response', headers: headerXml });
|
||||
}
|
||||
|
||||
uploadFile(file: FileList, labelSent: string): Observable<DataTableData<DatasetListingModel>> {
|
||||
const params = new BaseHttpParams();
|
||||
params.interceptorContext = {
|
||||
excludedInterceptors: [InterceptorType.JSONContentType]
|
||||
};
|
||||
const formData = new FormData();
|
||||
formData.append('file', file[0], labelSent);
|
||||
return this.http.post(this.actionUrl + "upload", formData, { params: params });
|
||||
}
|
||||
|
||||
clone(id: string): Observable<DmpBlueprint> {
|
||||
return this.http.post<DmpBlueprint>(this.actionUrl + 'clone/' + id, { headers: this.headers });
|
||||
}
|
||||
|
||||
externalAutocomplete(lookUpItem: RequestItem<DmpBlueprintExternalAutocompleteCriteria>): Observable<any> {
|
||||
return this.httpClient.post(this.actionUrl + 'search/autocomplete', lookUpItem);
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { environment } from '../../../../environments/environment';
|
||||
import { DataTableRequest } from '../../model/data-table/data-table-request';
|
||||
import { DmpProfile } from '../../model/dmp-profile/dmp-profile';
|
||||
import { BaseHttpService } from '../http/base-http.service';
|
||||
import { DmpProfileListing } from '../../model/dmp-profile/dmp-profile-listing';
|
||||
import { RequestItem } from '../../query/request-item';
|
||||
import { DataTableData } from '../../model/data-table/data-table-data';
|
||||
import { DmpProfileCriteria } from '../../query/dmp/dmp-profile-criteria';
|
||||
import { DatasetListingModel } from '../../model/dataset/dataset-listing';
|
||||
import { BaseHttpParams } from '../../../../common/http/base-http-params';
|
||||
import { InterceptorType } from '../../../../common/http/interceptors/interceptor-type';
|
||||
import { DmpProfileExternalAutocompleteCriteria } from '../../query/dmp/dmp-profile-external-autocomplete-criteria';
|
||||
import { ConfigurationService } from '../configuration/configuration.service';
|
||||
import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria';
|
||||
import { DmpBlueprintListing } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing';
|
||||
import { DmpBlueprint } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint';
|
||||
|
||||
@Injectable()
|
||||
export class DmpProfileService {
|
||||
|
||||
private actionUrl: string;
|
||||
private headers = new HttpHeaders();
|
||||
|
||||
constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) {
|
||||
this.actionUrl = configurationService.server + 'dmpprofile/';
|
||||
}
|
||||
|
||||
getPaged(dataTableRequest: DataTableRequest<DmpProfileCriteria>): Observable<DataTableData<DmpProfileListing>> {
|
||||
return this.http.post<DataTableData<DmpProfileListing>>(this.actionUrl + 'getPaged', dataTableRequest, { headers: this.headers });
|
||||
}
|
||||
|
||||
getPagedBlueprint(dataTableRequest: DataTableRequest<DmpBlueprintCriteria>): Observable<DataTableData<DmpBlueprintListing>> {
|
||||
return this.http.post<DataTableData<DmpBlueprintListing>>(this.actionUrl + 'getPagedBlueprint', dataTableRequest, { headers: this.headers });
|
||||
}
|
||||
|
||||
getSingle(id: String): Observable<DmpProfile> {
|
||||
return this.http.get<DmpProfile>(this.actionUrl + 'getSingle/' + id, { headers: this.headers });
|
||||
}
|
||||
|
||||
getSingleBlueprint(id: String): Observable<DmpBlueprintListing> {
|
||||
return this.http.get<DmpBlueprintListing>(this.actionUrl + 'getSingleBlueprint/' + id, { headers: this.headers });
|
||||
}
|
||||
|
||||
createDmp(dataManagementPlanModel: DmpProfile): Observable<DmpProfile> {
|
||||
return this.http.post<DmpProfile>(this.actionUrl, dataManagementPlanModel, { headers: this.headers });
|
||||
}
|
||||
|
||||
createBlueprint(dmpBlueprint: DmpBlueprint): Observable<DmpProfile> {
|
||||
return this.http.post<DmpProfile>(this.actionUrl + 'blueprint', dmpBlueprint, { headers: this.headers });
|
||||
}
|
||||
|
||||
public downloadXML(id: string): Observable<HttpResponse<Blob>> {
|
||||
let headerXml: HttpHeaders = this.headers.set('Content-Type', 'application/xml')
|
||||
return this.httpClient.get(this.actionUrl + 'getXml/' + id, { responseType: 'blob', observe: 'response', headers: headerXml });
|
||||
}
|
||||
|
||||
uploadFile(file: FileList, labelSent: string): Observable<DataTableData<DatasetListingModel>> {
|
||||
const params = new BaseHttpParams();
|
||||
params.interceptorContext = {
|
||||
excludedInterceptors: [InterceptorType.JSONContentType]
|
||||
};
|
||||
const formData = new FormData();
|
||||
formData.append('file', file[0], labelSent);
|
||||
return this.http.post(this.actionUrl + "upload", formData, { params: params });
|
||||
}
|
||||
|
||||
clone(id: string): Observable<DmpBlueprint> {
|
||||
return this.http.post<DmpBlueprint>(this.actionUrl + 'clone/' + id, { headers: this.headers });
|
||||
}
|
||||
|
||||
delete(id: string): Observable<any> {
|
||||
return this.http.delete<any>(this.actionUrl + id, { headers: this.headers });
|
||||
}
|
||||
|
||||
externalAutocomplete(lookUpItem: RequestItem<DmpProfileExternalAutocompleteCriteria>): Observable<any> {
|
||||
return this.httpClient.post(this.actionUrl + 'search/autocomplete', lookUpItem);
|
||||
}
|
||||
}
|
|
@ -82,7 +82,7 @@ export class DmpService {
|
|||
return this.http.delete<DmpModel>(this.actionUrl + 'inactivate/' + id, { headers: this.headers });
|
||||
}
|
||||
|
||||
searchDMPProfiles(dataSetProfileRequest: RequestItem<DatasetProfileCriteria>): Observable<DatasetProfileModel[]> {
|
||||
searchDmpBlueprints(dataSetProfileRequest: RequestItem<DatasetProfileCriteria>): Observable<DatasetProfileModel[]> {
|
||||
return this.http.post<DatasetProfileModel[]>(this.actionUrl + 'datasetprofiles/get', dataSetProfileRequest, { headers: this.headers });
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ export class DmpService {
|
|||
return this.httpClient.get(this.actionUrl + 'rda/' + id, { responseType: 'blob', observe: 'response' });
|
||||
}
|
||||
|
||||
public uploadXml(fileList: FileList, dmpTitle: string, dmpProfiles: any[]): Observable<any> {
|
||||
public uploadXml(fileList: FileList, dmpTitle: string, dmpBlueprints: any[]): Observable<any> {
|
||||
const formData: FormData = new FormData();
|
||||
if (fileList instanceof FileList) {
|
||||
for (let i = 0; i < fileList.length; i++) {
|
||||
|
@ -148,8 +148,8 @@ export class DmpService {
|
|||
} else {
|
||||
formData.append('file', fileList, dmpTitle);
|
||||
}
|
||||
for (let j = 0; j < dmpProfiles.length; j++) {
|
||||
formData.append('profiles', dmpProfiles[j].id);
|
||||
for (let j = 0; j < dmpBlueprints.length; j++) {
|
||||
formData.append('profiles', dmpBlueprints[j].id);
|
||||
}
|
||||
const params = new BaseHttpParams();
|
||||
params.interceptorContext = {
|
||||
|
|
|
@ -91,7 +91,7 @@ export class ExternalSourcesService {
|
|||
}
|
||||
|
||||
// TODO: currently not used.
|
||||
public searchDMPProfiles(like: string): Observable<ExternalSourceItemModel[]> {
|
||||
public searchDmpBlueprints(like: string): Observable<ExternalSourceItemModel[]> {
|
||||
return this.http.get<ExternalSourceItemModel[]>(this.actionUrl + 'datasetprofiles/get' + '?query=' + like, { headers: this.headers });
|
||||
}
|
||||
|
||||
|
|
|
@ -35,4 +35,61 @@ export class TimezoneService {
|
|||
getCurrentTimezone(): string {
|
||||
return this.currentTimezone;
|
||||
}
|
||||
|
||||
public buildDateTime(params: {
|
||||
time: string,
|
||||
date: moment.Moment
|
||||
}): moment.Moment {
|
||||
|
||||
const { time, date } = params;
|
||||
|
||||
if (!time || !date) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const momentTime = moment.duration(time);
|
||||
const momentDate = moment(date.toString());
|
||||
|
||||
const toReturn = moment.utc({
|
||||
year: momentDate.year(),
|
||||
month: momentDate.month(),
|
||||
date: momentDate.date(),
|
||||
hour: momentTime.hours(),
|
||||
minute: momentTime.minutes()
|
||||
})
|
||||
|
||||
return toReturn.tz(this.getCurrentTimezone(), true);
|
||||
}
|
||||
|
||||
|
||||
public splitDateTime(params: {
|
||||
dateTime: moment.Moment,
|
||||
}): { date: moment.Moment, time: string } | null {
|
||||
|
||||
const { dateTime } = params
|
||||
|
||||
if (!dateTime) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const dateTimeMoment = moment(dateTime.toString()).tz(this.getCurrentTimezone());
|
||||
|
||||
const date =
|
||||
moment.utc({
|
||||
year: dateTimeMoment.year(),
|
||||
month: dateTimeMoment.month(),
|
||||
date: dateTimeMoment.date(),
|
||||
});
|
||||
|
||||
const hours = dateTimeMoment.hour();
|
||||
const minutes = dateTimeMoment.minute();
|
||||
|
||||
const hoursString = hours > 10 ? hours.toString() : `0${hours}`
|
||||
const minutesString = hours > 10 ? minutes.toString() : `0${minutes}`
|
||||
|
||||
return {
|
||||
date,
|
||||
time: `${hoursString}:${minutesString}:00`
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { Observable } from 'rxjs';
|
||||
import { UserSettingPersist, UserSettings } from '@app/core/model/user-settings/user-settings.model';
|
||||
import { BaseHttpV2Service } from '../http/base-http-v2.service';
|
||||
import { ConfigurationService } from '../configuration/configuration.service';
|
||||
|
||||
@Injectable()
|
||||
export class UserSettingsHttpService {
|
||||
constructor(
|
||||
private installationConfiguration: ConfigurationService,
|
||||
private http: BaseHttpV2Service) { }
|
||||
|
||||
private get apiBase(): string { return `${this.installationConfiguration.server}user-settings`; }
|
||||
|
||||
getSingle(key: string): Observable<UserSettings> {
|
||||
const url = `${this.apiBase}/${key}`;
|
||||
|
||||
return this.http.get<UserSettings>(url);
|
||||
}
|
||||
|
||||
persist(item: UserSettingPersist): Observable<UserSettings> {
|
||||
const url = `${this.apiBase}/persist`;
|
||||
|
||||
return this.http.post<UserSettings>(url, item);
|
||||
}
|
||||
|
||||
persistAll(items: UserSettingPersist[]): Observable<UserSettings[]> {
|
||||
const url = `${this.apiBase}/persist-all-default`;
|
||||
|
||||
return this.http.post<UserSettings[]>(url, items);
|
||||
}
|
||||
|
||||
delete(id: Guid): Observable<UserSettings> {
|
||||
const url = `${this.apiBase}/${id}`;
|
||||
return this.http
|
||||
.delete<UserSettings>(url);
|
||||
}
|
||||
|
||||
share(item: UserSettingPersist, targetId: Guid): Observable<UserSettings>{
|
||||
const url = `${this.apiBase}/share/${targetId}`;
|
||||
|
||||
return this.http.post<UserSettings>(url, item);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,332 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { UserSettingPersist, UserSettingsInformation, UserSettings as UserSettingsObject } from '@app/core/model/user-settings/user-settings.model';
|
||||
import { BaseService } from '@common/base/base.service';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import * as moment from 'moment';
|
||||
import { Moment } from 'moment';
|
||||
import { Observable, Subject, of as observableOf } from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { AuthService, LoginStatus } from '../auth/auth.service';
|
||||
import { ConfigurationService } from '../configuration/configuration.service';
|
||||
import { UserSettingsHttpService } from './user-settings-http.service';
|
||||
|
||||
export enum UserSettingsType {
|
||||
Setting = 0,
|
||||
Config = 1
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class UserSettingsService extends BaseService {
|
||||
static CACHE_SETTINGS_LIFETIME = 7200; // (value is in seconds) 2 hours
|
||||
|
||||
public userSettingUpdated: Subject<string>;
|
||||
private userSettingsMap: Map<String, any> = new Map<String, any>();
|
||||
private userSettingsLastAccessMap: Map<String, Moment> = new Map<String, Moment>();
|
||||
|
||||
constructor(
|
||||
private userSettingsHttpService: UserSettingsHttpService,
|
||||
private authService: AuthService,
|
||||
private installationConfigurationService: ConfigurationService
|
||||
) {
|
||||
super();
|
||||
this.userSettingUpdated = new Subject<string>();
|
||||
|
||||
this.authService.getAuthenticationStateObservable().pipe(takeUntil(this._destroyed)).subscribe(authenticationState => {
|
||||
if (authenticationState.loginStatus === LoginStatus.LoggedOut) {
|
||||
localStorage.clear();
|
||||
this.userSettingsMap = new Map<String, any>();
|
||||
this.userSettingsLastAccessMap = new Map<String, Moment>();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public getUserSettingUpdatedObservable(): Observable<string> {
|
||||
return this.userSettingUpdated.asObservable();
|
||||
}
|
||||
|
||||
get<T>(userSettingsInformation: UserSettingsInformation<T>): Observable<UserSettings<T>> {
|
||||
if (this.userSettingsLastAccessMap.has(userSettingsInformation.key)) {
|
||||
const lastAccess = this.userSettingsLastAccessMap.get(userSettingsInformation.key);
|
||||
const difference = moment.utc().diff(lastAccess, 'seconds');
|
||||
|
||||
if (difference > UserSettingsService.CACHE_SETTINGS_LIFETIME) {
|
||||
this.clearSetting(userSettingsInformation.key);
|
||||
}
|
||||
}
|
||||
|
||||
this.userSettingsLastAccessMap.set(userSettingsInformation.key, moment.utc());
|
||||
|
||||
if (this.userSettingsMap.has(userSettingsInformation.key)) { return observableOf(this.userSettingsMap.get(userSettingsInformation.key)); }
|
||||
|
||||
return this.loadUserSettings<T>(userSettingsInformation);
|
||||
}
|
||||
|
||||
set<T>(setting: UserSetting<T>, isDefault: boolean = false, userSettingsInformation: UserSettingsInformation<T> = null) {
|
||||
const userSetting = this.buildUserSetting(setting, userSettingsInformation.key, isDefault);
|
||||
let userSettings: UserSettings<T> = this.buildUserSettings(userSetting, userSettingsInformation.key);
|
||||
|
||||
if (this.userSettingsMap.has(userSettingsInformation.key)) {
|
||||
userSettings = this.userSettingsMap.get(userSettingsInformation.key);
|
||||
if (userSettings == null) { userSettings = this.buildUserSettings(userSetting, userSettingsInformation.key); }
|
||||
const itemIndex = userSettings.settings.findIndex(item => item.id === userSetting.id);
|
||||
if (itemIndex < 0) {
|
||||
userSettings.settings.push(userSetting);
|
||||
} else {
|
||||
userSettings.settings[itemIndex] = userSetting;
|
||||
}
|
||||
if (isDefault) {
|
||||
userSettings.defaultSetting = userSetting;
|
||||
}
|
||||
} else {
|
||||
userSetting.isDefault = isDefault;
|
||||
if (isDefault) { userSettings.defaultSetting = userSetting; }
|
||||
}
|
||||
|
||||
userSettings.settings.forEach((element) => {
|
||||
if (!(element.id === userSettings.defaultSetting.id)) {
|
||||
element.isDefault = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.persistUserSettings(userSettingsInformation.key, userSettings, userSettingsInformation, true);
|
||||
this.userSettingsLastAccessMap.set(userSettingsInformation.key, moment.utc());
|
||||
}
|
||||
|
||||
remove<T>(id: Guid, userSettingsInformation: UserSettingsInformation<T> = null) {
|
||||
this.deleteFromWebServer(id, userSettingsInformation);
|
||||
}
|
||||
|
||||
share(userSettings: UserSetting<any>, targetId: Guid, newName: string): Observable<UserSettingsObject> {
|
||||
const userSettingsToPersist: UserSettingPersist = {
|
||||
id: null,
|
||||
key: userSettings.key,
|
||||
isDefault: false,
|
||||
name: newName,
|
||||
type: userSettings.type,
|
||||
value: JSON.stringify(userSettings.value),
|
||||
hash: null
|
||||
};
|
||||
return this.userSettingsHttpService.share(userSettingsToPersist, targetId);
|
||||
}
|
||||
|
||||
private deleteFromWebServer<T>(id: Guid, userSettingsInformation: UserSettingsInformation<T>) {
|
||||
this.userSettingsHttpService.delete(id).pipe(takeUntil(this._destroyed)).subscribe(item => {
|
||||
const result: UserSettings<T> = (item ? this.toTypedUserSettings<T>(item as UserSettingsObject) : null);
|
||||
this.persistUserSettings(userSettingsInformation.key, result, userSettingsInformation, false);
|
||||
this.userSettingUpdated.next(userSettingsInformation.key);
|
||||
});
|
||||
}
|
||||
|
||||
private buildUserSettings<T>(setting: UserSetting<T>, key: string): UserSettings<T> {
|
||||
const userSettings: UserSettings<T> = {
|
||||
key: key,
|
||||
settings: [setting],
|
||||
defaultSetting: setting
|
||||
};
|
||||
return userSettings;
|
||||
}
|
||||
|
||||
private buildUserSetting<T>(setting: UserSetting<T>, key: string, isDefault: boolean): UserSetting<T> {
|
||||
const userSettings: UserSetting<T> = {
|
||||
id: setting.id,
|
||||
key: key,
|
||||
name: setting.name,
|
||||
value: setting.value,
|
||||
type: UserSettingsType.Setting,
|
||||
isDefault: isDefault,
|
||||
hash: setting.hash
|
||||
};
|
||||
return userSettings;
|
||||
}
|
||||
|
||||
private loadUserSettings<T>(userSettingsInformation: UserSettingsInformation<T>): Observable<UserSettings<T>> {
|
||||
const localStorageItem = this.loadFromLocalStorage(userSettingsInformation.key);
|
||||
if (localStorageItem) {
|
||||
const jsonLocalStorageItem = JSON.parse(localStorageItem);
|
||||
if (jsonLocalStorageItem) { return observableOf((jsonLocalStorageItem as UserSettings<T>)); }
|
||||
}
|
||||
|
||||
return this.userSettingsHttpService.getSingle(userSettingsInformation.key).pipe(
|
||||
// catchError(() => {
|
||||
// const result: UserSettings<T> = this.defaultValue(userSettingsInformation);
|
||||
// this.persistUserSettings(userSettingsInformation.key, result, userSettingsInformation, false);
|
||||
// return observableOf(result);
|
||||
// }),
|
||||
map(x => {
|
||||
const result: UserSettings<T> = (x ? this.toTypedUserSettings<T>(x as UserSettingsObject) : null);
|
||||
this.persistUserSettings(userSettingsInformation.key, result, userSettingsInformation, false);
|
||||
return result;
|
||||
}));
|
||||
}
|
||||
|
||||
private persistUserSettings<T>(key: string, userSettings: UserSettings<T>, userSettingsInformation: UserSettingsInformation<T>, pushChangeToServer: boolean = true) {
|
||||
this.userSettingsMap.set(key, userSettings);
|
||||
this.storeToLocalStorage(key, userSettings);
|
||||
|
||||
if (pushChangeToServer) {
|
||||
this.persistSettingsChanges(key, userSettings, userSettingsInformation);
|
||||
}
|
||||
}
|
||||
|
||||
private persistSettingsChanges<T>(key: string, userSettings: UserSettings<T>, userSettingsInformation: UserSettingsInformation<T>, updateLocalAfterPush: boolean = true) {
|
||||
const changesToPush: UserSettingPersist[] = [];
|
||||
const userSettingsPersist = this.prepareSettingsToPushToWebServer(userSettings);
|
||||
userSettingsPersist.forEach(element => {
|
||||
changesToPush.push(element);
|
||||
});
|
||||
this.pushToWebServer(changesToPush, userSettingsInformation, updateLocalAfterPush);
|
||||
}
|
||||
|
||||
private buildPersistModel(element: any): UserSettingPersist {
|
||||
const userSettingsToPersist: UserSettingPersist = {
|
||||
id: element.id,
|
||||
key: element.key,
|
||||
isDefault: element.isDefault,
|
||||
name: element.name,
|
||||
type: element.type,
|
||||
value: JSON.stringify(element.value),
|
||||
hash: element.hash
|
||||
};
|
||||
|
||||
return userSettingsToPersist;
|
||||
}
|
||||
|
||||
private prepareSettingsToPushToWebServer(userSettings: UserSettings<any>): UserSettingPersist[] {
|
||||
|
||||
const userSettingsArray: UserSettingPersist[] = [];
|
||||
if (userSettings && userSettings.settings && userSettings.settings.length !== 0) {
|
||||
userSettings.settings.forEach(element => {
|
||||
userSettingsArray.push(this.buildPersistModel(element));
|
||||
});
|
||||
}
|
||||
return userSettingsArray;
|
||||
}
|
||||
|
||||
private toTypedUserSettings<T>(userSettings: UserSettingsObject): UserSettings<T> {
|
||||
const settingsArray: UserSetting<T>[] = [];
|
||||
if (userSettings && userSettings.settings && userSettings.settings.length !== 0) {
|
||||
userSettings.settings.forEach(element => {
|
||||
const settingElement: UserSetting<T> = {
|
||||
id: element.id,
|
||||
key: userSettings.key,
|
||||
name: element.name,
|
||||
value: JSON.parse(element.value),
|
||||
userId: element.userId,
|
||||
updatedAt: element.updatedAt,
|
||||
createdAt: element.createdAt,
|
||||
hash: element.hash,
|
||||
type: element.type,
|
||||
isDefault: element.isDefault
|
||||
};
|
||||
settingsArray.push(settingElement);
|
||||
});
|
||||
}
|
||||
let defaultSetting: UserSetting<T> = null;
|
||||
if (userSettings.defaultSetting) {
|
||||
const defaultSettingValue = userSettings.defaultSetting;
|
||||
defaultSetting = {
|
||||
id: defaultSettingValue.id,
|
||||
key: userSettings.key,
|
||||
name: defaultSettingValue.name,
|
||||
value: userSettings.defaultSetting ? JSON.parse(defaultSettingValue.value) : defaultSettingValue.value,
|
||||
userId: defaultSettingValue.userId,
|
||||
updatedAt: defaultSettingValue.updatedAt,
|
||||
createdAt: defaultSettingValue.createdAt,
|
||||
hash: defaultSettingValue.hash,
|
||||
type: defaultSettingValue.type,
|
||||
isDefault: defaultSettingValue.isDefault
|
||||
};
|
||||
}
|
||||
const result: UserSettings<T> = {
|
||||
key: userSettings.key,
|
||||
settings: settingsArray,
|
||||
defaultSetting: defaultSetting
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
private pushToWebServer<T>(userSettingsToPersist: UserSettingPersist[], userSettingsInformation: UserSettingsInformation<T>, updateLocalAfterPush: boolean) {
|
||||
if (!userSettingsToPersist || userSettingsToPersist.length === 0) { return; }
|
||||
this.userSettingsHttpService.persistAll(userSettingsToPersist).pipe(takeUntil(this._destroyed)).subscribe(items => {
|
||||
if (updateLocalAfterPush) {
|
||||
const result: UserSettings<any>[] = items ? items.map(x => this.toTypedUserSettings<any>(x as UserSettingsObject)) : [];
|
||||
result.forEach(item => {
|
||||
if (item.defaultSetting != null) {
|
||||
this.userSettingsMap.set(item.key, item);
|
||||
this.storeToLocalStorage(item.key, item);
|
||||
} else {
|
||||
this.clearSetting(item.key);
|
||||
}
|
||||
this.userSettingUpdated.next(item.key);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private clearSetting(key: string) {
|
||||
this.userSettingsMap.delete(key);
|
||||
this.userSettingsLastAccessMap.delete(key);
|
||||
this.deleteFromLocalStorage(key);
|
||||
}
|
||||
|
||||
private loadFromLocalStorage(key: string) {
|
||||
return localStorage.getItem(this.generateLocalStorageKey(key));
|
||||
}
|
||||
|
||||
private storeToLocalStorage(key: string, value: any) {
|
||||
return localStorage.setItem(this.generateLocalStorageKey(key), JSON.stringify(value));
|
||||
}
|
||||
|
||||
private deleteFromLocalStorage(key: string) {
|
||||
return localStorage.removeItem(this.generateLocalStorageKey(key));
|
||||
}
|
||||
|
||||
private generateLocalStorageKey(key: string): string {
|
||||
return `${this.getUserSettingsVersion()}_${this.getUserId()}_${key}`;
|
||||
}
|
||||
|
||||
// private defaultValue<T>(userSettingsInformation: UserSettingsInformation<T>): UserSettings<T> {
|
||||
// const defaultSetting: UserSetting<T> = {
|
||||
// id: null,
|
||||
// name: null,
|
||||
// userId: this.getUserId(),
|
||||
// key: userSettingsInformation.key,
|
||||
// type: UserSettingsType.Config,
|
||||
// isDefault: true,
|
||||
// value: new userSettingsInformation.type()
|
||||
// };
|
||||
// const userSettings: UserSettings<T> = {
|
||||
// defaultSetting: defaultSetting,
|
||||
// key: userSettingsInformation.key,
|
||||
// settings: [defaultSetting]
|
||||
// };
|
||||
// return userSettings;
|
||||
// }
|
||||
|
||||
private getUserId(): Guid {
|
||||
return this.authService.userId();
|
||||
}
|
||||
|
||||
private getUserSettingsVersion(): string {
|
||||
return this.installationConfigurationService.userSettingsVersion;
|
||||
}
|
||||
}
|
||||
|
||||
export interface UserSettings<T> {
|
||||
key: string;
|
||||
settings: UserSetting<T>[];
|
||||
defaultSetting: UserSetting<T>;
|
||||
}
|
||||
|
||||
export interface UserSetting<T> {
|
||||
id: Guid;
|
||||
name: string;
|
||||
key: string;
|
||||
type: UserSettingsType;
|
||||
value: T;
|
||||
createdAt?: Date;
|
||||
updatedAt?: Date;
|
||||
hash?: string;
|
||||
userId?: Guid;
|
||||
isDefault?: boolean;
|
||||
}
|
|
@ -4,8 +4,8 @@ import { AppRole } from '../../common/enum/app-role';
|
|||
import { DatasetProfileComboBoxType } from '../../common/enum/dataset-profile-combo-box-type';
|
||||
import { DatasetProfileFieldViewStyle } from '../../common/enum/dataset-profile-field-view-style';
|
||||
import { DatasetStatus } from '../../common/enum/dataset-status';
|
||||
import { DmpProfileFieldDataType } from '../../common/enum/dmp-profile-field-type';
|
||||
import { DmpProfileType } from '../../common/enum/dmp-profile-type';
|
||||
import { DmpBlueprintFieldDataType } from '../../common/enum/dmp-blueprint-field-type';
|
||||
import { DmpBlueprintType } from '../../common/enum/dmp-blueprint-type';
|
||||
import { DmpStatus } from '../../common/enum/dmp-status';
|
||||
import { ValidationType } from '../../common/enum/validation-type';
|
||||
import { DatasetProfileInternalDmpEntitiesType } from '../../common/enum/dataset-profile-internal-dmp-entities-type';
|
||||
|
@ -13,6 +13,7 @@ import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order
|
|||
import { Role } from '@app/core/common/enum/role';
|
||||
import { RoleOrganizationType } from '@app/core/common/enum/role-organization-type';
|
||||
import { ViewStyleType } from '@app/ui/admin/dataset-profile/editor/components/field/view-style-enum';
|
||||
import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status';
|
||||
|
||||
@Injectable()
|
||||
export class EnumUtils {
|
||||
|
@ -34,18 +35,18 @@ export class EnumUtils {
|
|||
}
|
||||
}
|
||||
|
||||
toDmpProfileFieldDataTypeString(type: DmpProfileFieldDataType): string {
|
||||
toDmpBlueprintFieldDataTypeString(type: DmpBlueprintFieldDataType): string {
|
||||
switch (type) {
|
||||
case DmpProfileFieldDataType.Date: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.DATE');
|
||||
case DmpProfileFieldDataType.Number: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.NUMBER');
|
||||
case DmpProfileFieldDataType.Text: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.TEXT');
|
||||
case DmpProfileFieldDataType.ExternalAutocomplete: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.EXTERNAL-AUTOCOMPLETE');
|
||||
case DmpBlueprintFieldDataType.Date: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.DATE');
|
||||
case DmpBlueprintFieldDataType.Number: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.NUMBER');
|
||||
case DmpBlueprintFieldDataType.Text: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.TEXT');
|
||||
case DmpBlueprintFieldDataType.ExternalAutocomplete: return this.language.instant('TYPES.DMP-PROFILE-FIELD.DATA-TYPE.EXTERNAL-AUTOCOMPLETE');
|
||||
}
|
||||
}
|
||||
|
||||
toDmpProfileTypeString(type: DmpProfileType): string {
|
||||
toDmpBlueprintTypeString(type: DmpBlueprintType): string {
|
||||
switch (type) {
|
||||
case DmpProfileType.Input: return this.language.instant('TYPES.DMP-PROFILE-FIELD.TYPE.INPUT');
|
||||
case DmpBlueprintType.Input: return this.language.instant('TYPES.DMP-PROFILE-FIELD.TYPE.INPUT');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,4 +186,11 @@ export class EnumUtils {
|
|||
case RoleOrganizationType.Other: return this.language.instant('USER-PROFILE.ROLE-ORGANIZATION.OTHER');
|
||||
}
|
||||
}
|
||||
|
||||
toDescriptionTemplateTypeStatusString(status: DescriptionTemplateTypeStatus): string {
|
||||
switch (status) {
|
||||
case DescriptionTemplateTypeStatus.Draft: return this.language.instant('TYPES.DESCRIPTION-TEMPLATE-TYPE-STATUS.DRAFT');
|
||||
case DescriptionTemplateTypeStatus.Finalized: return this.language.instant('TYPES.DESCRIPTION-TEMPLATE-TYPE-STATUS.FINALIZED');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Lookup } from '@common/model/lookup';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
|
||||
@Injectable()
|
||||
export class QueryParamsService {
|
||||
|
||||
constructor() { }
|
||||
|
||||
|
||||
serializeLookup(lookup: Lookup): string {
|
||||
return JSON.stringify(lookup, (key: string, value: any) => {
|
||||
switch (key) {
|
||||
// case nameof<Lookup>(x => x.page):
|
||||
// case nameof<Lookup>(x => x.order):
|
||||
case nameof<Lookup>(x => x.metadata):
|
||||
case nameof<Lookup>(x => x.project):
|
||||
return undefined;
|
||||
default:
|
||||
return value == null ? undefined : value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
deSerializeLookup(serializedLookup: string): any {
|
||||
const json = JSON.parse(serializedLookup);
|
||||
// delete json[nameof<Lookup>(x => x.page)];
|
||||
// delete json[nameof<Lookup>(x => x.order)];
|
||||
delete json[nameof<Lookup>(x => x.metadata)];
|
||||
delete json[nameof<Lookup>(x => x.project)];
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
serializeObject(object: Record<string,any>): string | null{
|
||||
if(!object){
|
||||
return null
|
||||
}
|
||||
return JSON.stringify(object);
|
||||
}
|
||||
|
||||
deserializeObject<T>(object: string):T | null {
|
||||
if(!object){
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(object);
|
||||
}
|
||||
|
||||
|
||||
deSerializeAndApplyLookup(serializedLookup: string, targetLookup: Lookup) {
|
||||
this.applyLookup(targetLookup, this.deSerializeLookup(serializedLookup));
|
||||
}
|
||||
|
||||
private applyLookup(target: Lookup, source: Lookup) {
|
||||
Object.keys(source).forEach(key => {
|
||||
target[key] = source[key];
|
||||
});
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ import * as FileSaver from 'file-saver';
|
|||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { DatasetProfileEditorModel } from '@app/ui/admin/dataset-profile/editor/dataset-profile-editor-model';
|
||||
import { DatasetWizardModel } from '@app/core/model/dataset/dataset-wizard';
|
||||
import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
||||
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
||||
import { DatasetProfileService } from '@app/core/services/dataset-profile/dataset-profile.service';
|
||||
import { LoggingService } from '@app/core/services/logging/logging-service';
|
||||
import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service';
|
||||
|
@ -48,7 +48,7 @@ import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate
|
|||
import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service';
|
||||
import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type';
|
||||
import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status';
|
||||
import { DescriptionTemplateTypeLookup } from '@app/core/query/description-template/description-template-type.lookup';
|
||||
import { DescriptionTemplateTypeLookup } from '@app/core/query/description-template-type.lookup';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
|
||||
const skipDisable: any[] = require('../../../../../assets/resources/skipDisable.json');
|
||||
|
@ -76,7 +76,7 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent
|
|||
private datasetProfileId: string;
|
||||
newVersionId: string;
|
||||
dataWizardModel: DatasetWizardModel;
|
||||
breadCrumbs: Observable<BreadcrumbItem[]>;
|
||||
// breadCrumbs: Observable<BreadcrumbItem[]>;
|
||||
@ViewChild('stepper') stepper: MatStepper;
|
||||
viewOnly = false;
|
||||
nestedCount: number[] = [];
|
||||
|
@ -166,11 +166,11 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent
|
|||
},
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
this.breadCrumbs = observableOf([{
|
||||
parentComponentName: 'DatasetProfileListingComponent',
|
||||
label: this.language.instant('NAV-BAR.TEMPLATE'),
|
||||
url: '/dataset-profiles/' + this.datasetProfileId
|
||||
}]);
|
||||
// this.breadCrumbs = observableOf([{
|
||||
// parentComponentName: 'DatasetProfileListingComponent',
|
||||
// label: this.language.instant('NAV-BAR.TEMPLATE'),
|
||||
// url: '/dataset-profiles/' + this.datasetProfileId
|
||||
// }]);
|
||||
} else if (cloneId != null) {
|
||||
this.isClone = true;
|
||||
this.datasetProfileService.clone(cloneId)
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
</button>
|
||||
<button mat-menu-item (click)="downloadXML(row.id)" *ngIf="row.status === datasetStatusEnum.Finalized">
|
||||
<mat-icon>download</mat-icon>
|
||||
{{'DMP-PROFILE-EDITOR.ACTIONS.DOWNLOAD-XML' | translate}}
|
||||
{{'DMP-BLUEPRINT-EDITOR.ACTIONS.DOWNLOAD-XML' | translate}}
|
||||
</button>
|
||||
<button mat-menu-item (click)="deleteTemplate(row.id)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
|
|
|
@ -15,7 +15,7 @@ import { DmpService } from '@app/core/services/dmp/dmp.service';
|
|||
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { DatasetProfileCriteriaComponent } from '@app/ui/admin/dataset-profile/listing/criteria/dataset-profile.component';
|
||||
import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
||||
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
@ -35,7 +35,7 @@ export class DatasetProfileListingComponent extends BaseComponent implements OnI
|
|||
@ViewChild(MatSort, { static: true }) sort: MatSort;
|
||||
@ViewChild(DatasetProfileCriteriaComponent, { static: true }) criteria: DatasetProfileCriteriaComponent;
|
||||
|
||||
breadCrumbs: Observable<BreadcrumbItem[]>;
|
||||
// breadCrumbs: Observable<BreadcrumbItem[]>;
|
||||
dataSource: DatasetDataSource | null;
|
||||
displayedColumns: String[] = ['label', 'description', 'created', 'status', 'actions'];
|
||||
pageEvent: PageEvent;
|
||||
|
@ -83,11 +83,11 @@ export class DatasetProfileListingComponent extends BaseComponent implements OnI
|
|||
this.criteria.setCriteria(this.getDefaultCriteria());
|
||||
this.refresh();
|
||||
this.criteria.setRefreshCallback(() => this.refresh());
|
||||
this.breadCrumbs = observableOf([{
|
||||
parentComponentName: null,
|
||||
label: this.language.instant('NAV-BAR.DATASET-TEMPLATES'),
|
||||
url: '/dataset-profiles'
|
||||
}]);
|
||||
// this.breadCrumbs = observableOf([{
|
||||
// parentComponentName: null,
|
||||
// label: this.language.instant('NAV-BAR.DATASET-TEMPLATES'),
|
||||
// url: '/dataset-profiles'
|
||||
// }]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||
import { HybridListingModule } from '@common/modules/hybrid-listing/hybrid-listing.module';
|
||||
import { TextFilterModule } from '@common/modules/text-filter/text-filter.module';
|
||||
import { UserSettingsModule } from '@common/modules/user-settings/user-settings.module';
|
||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||
import { DescriptionTemplateTypesRoutingModule } from './description-template-type.routing';
|
||||
import { DescriptionTemplateTypeEditorComponent } from './editor/description-template-type-editor.component';
|
||||
import { DescriptionTemplateTypeListingComponent } from './listing/description-template-type-listing.component';
|
||||
import { DescriptionTemplateTypeListingFiltersComponent } from './listing/filters/description-template-type-listing-filters.component';
|
||||
import { FormattingModule } from '@app/core/formatting.module';
|
||||
import { CommonFormattingModule } from '@common/formatting/common-formatting.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
DescriptionTemplateTypeListingComponent,
|
||||
DescriptionTemplateTypeEditorComponent,
|
||||
DescriptionTemplateTypeListingFiltersComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
CommonUiModule,
|
||||
CommonFormsModule,
|
||||
CommonFormattingModule,
|
||||
DescriptionTemplateTypesRoutingModule,
|
||||
HybridListingModule,
|
||||
TextFilterModule,
|
||||
UserSettingsModule
|
||||
]
|
||||
})
|
||||
export class DescriptionTemplateTypesModule { }
|
|
@ -0,0 +1,57 @@
|
|||
import { NgModule } from "@angular/core";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
import { AuthGuard } from "@app/core/auth-guard.service";
|
||||
import { AppPermission } from "@app/core/common/enum/permission.enum";
|
||||
import { BreadcrumbService } from "@app/ui/misc/breadcrumb/breadcrumb.service";
|
||||
import { PendingChangesGuard } from "@common/forms/pending-form-changes/pending-form-changes-guard.service";
|
||||
import { DescriptionTemplateTypeEditorComponent } from './editor/description-template-type-editor.component';
|
||||
import { DescriptionTemplateTypeEditorResolver } from "./editor/description-template-type-editor.resolver";
|
||||
import { DescriptionTemplateTypeListingComponent } from "./listing/description-template-type-listing.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: DescriptionTemplateTypeListingComponent,
|
||||
canActivate: [AuthGuard]
|
||||
},
|
||||
{
|
||||
path: 'new',
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
authContext: {
|
||||
permissions: [AppPermission.EditDescriptionTemplateType]
|
||||
},
|
||||
...BreadcrumbService.generateRouteDataConfiguration({
|
||||
title: 'BREADCRUMBS.NEW-DESCRIPTION-TEMPLATE-TYPE'
|
||||
})
|
||||
},
|
||||
component: DescriptionTemplateTypeEditorComponent,
|
||||
canDeactivate: [PendingChangesGuard],
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
canActivate: [AuthGuard],
|
||||
component: DescriptionTemplateTypeEditorComponent,
|
||||
canDeactivate: [PendingChangesGuard],
|
||||
resolve: {
|
||||
'entity': DescriptionTemplateTypeEditorResolver
|
||||
},
|
||||
data: {
|
||||
...BreadcrumbService.generateRouteDataConfiguration({
|
||||
title: 'BREADCRUMBS.EDIT-DESCRIPTION-TEMPLATE-TYPE'
|
||||
}),
|
||||
authContext: {
|
||||
permissions: [AppPermission.EditDescriptionTemplateType]
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
{ path: '**', loadChildren: () => import('@common/modules/page-not-found/page-not-found.module').then(m => m.PageNotFoundModule) },
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
providers: [DescriptionTemplateTypeEditorResolver]
|
||||
})
|
||||
export class DescriptionTemplateTypesRoutingModule { }
|
|
@ -1,21 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { DescriptionTypesRoutingModule } from './description-types.routing';
|
||||
import { DescriptionTypesComponent } from './listing/description-types.component';
|
||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||
import { DescriptionTypeEditorComponent } from './editor/description-type-editor.component';
|
||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
DescriptionTypesComponent,
|
||||
DescriptionTypeEditorComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
CommonUiModule,
|
||||
CommonFormsModule,
|
||||
DescriptionTypesRoutingModule
|
||||
]
|
||||
})
|
||||
export class DescriptionTypesModule { }
|
|
@ -1,45 +0,0 @@
|
|||
import { NgModule } from "@angular/core";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
import { AdminAuthGuard } from "@app/core/admin-auth-guard.service";
|
||||
import { DescriptionTypeEditorComponent } from './editor/description-type-editor.component';
|
||||
import { DescriptionTypesComponent } from "./listing/description-types.component";
|
||||
import { AuthGuard } from "@app/core/auth-guard.service";
|
||||
import { AppPermission } from "@app/core/common/enum/permission.enum";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: DescriptionTypesComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
authContext: {
|
||||
permissions: [AppPermission.ViewDescriptionTemplateTypePage]
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'new',
|
||||
component: DescriptionTypeEditorComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
title: 'GENERAL.TITLES.DESCRIPTION-TYPE-NEW',
|
||||
authContext: {
|
||||
permissions: [AppPermission.EditDescriptionTemplateType]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
component: DescriptionTypeEditorComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
title: 'GENERAL.TITLES.DESCRIPTION-TYPE-EDIT'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class DescriptionTypesRoutingModule { }
|
|
@ -0,0 +1,99 @@
|
|||
<div class="row description-template-type-editor">
|
||||
<div class="col-md-8 offset-md-2 colums-gapped">
|
||||
|
||||
<div class="row justify-content-between align-items-center">
|
||||
<div class="col">
|
||||
<!-- <h3 *ngIf="isNew">{{'DESCRIPTION-TEMPLATE-TYPE-EDITOR.NEW' | translate}}</h3> -->
|
||||
<app-navigation-breadcrumb />
|
||||
</div>
|
||||
|
||||
<div class="col-auto">
|
||||
<button mat-button class="action-btn" (click)="cancel()" type="button">{{'DESCRIPTION-TEMPLATE-TYPE-EDITOR.ACTIONS.CANCEL' | translate}}</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="canDelete">
|
||||
<button mat-button (click)="delete()" class="action-btn" type="button">
|
||||
<mat-icon>delete</mat-icon>
|
||||
{{'DESCRIPTION-TEMPLATE-TYPE-EDITOR.ACTIONS.DELETE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="canFinalize">
|
||||
<button mat-button class="action-btn" (click)="finalize(); formSubmit()">
|
||||
<mat-icon>save</mat-icon>
|
||||
{{'DESCRIPTION-TEMPLATE-TYPE-EDITOR.ACTIONS.FINALIZE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="canSave">
|
||||
<button mat-button class="action-btn" (click)="save(); formSubmit()">
|
||||
<mat-icon>save</mat-icon>
|
||||
{{'DESCRIPTION-TEMPLATE-TYPE-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-card appearance="outlined">
|
||||
<mat-card-header>
|
||||
<mat-card-title *ngIf="isNew">{{'DESCRIPTION-TEMPLATE-TYPE-EDITOR.NEW' | translate}}</mat-card-title>
|
||||
<!-- <mat-card-title *ngIf="!isNew">{{formGroup.get('name').value}}</mat-card-title> -->
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<form (ngSubmit)="formSubmit()" [formGroup]="formGroup" *ngIf="formGroup">
|
||||
<div class="info-grid">
|
||||
<div class="info-grid-label">
|
||||
<span>
|
||||
{{'DESCRIPTION-TEMPLATE-TYPE-EDITOR.FIELDS.NAME' | translate}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="info-grid-value">
|
||||
<mat-form-field class="col-lg-6">
|
||||
<input matInput placeholder="{{'DESCRIPTION-TEMPLATE-TYPE-EDITOR.FIELDS.NAME' | translate}}" type="text" name="name" [formControl]="formGroup.get('name')" required>
|
||||
<mat-error *ngIf="formGroup.get('name').hasError('backendError')">
|
||||
{{formGroup.get('name').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.get('name').hasError('required')">
|
||||
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="main-content">
|
||||
<div class="container-fluid description-type-editor">
|
||||
<div class="row align-items-center mb-4" *ngIf="formGroup">
|
||||
<div class="col-auto">
|
||||
<h3>{{'DESCRIPTION-TYPE-EDITOR.NEW' | translate}}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<form *ngIf="formGroup" (ngSubmit)="formSubmit()" [formGroup]="formGroup">
|
||||
<mat-card style="padding: 2em;">
|
||||
<mat-card-content>
|
||||
<div class="row" style="gap:1em">
|
||||
<mat-form-field class="col-lg-6">
|
||||
<input matInput placeholder="{{'DESCRIPTION-TYPE-EDITOR.FIELDS.LABEL' | translate}}" type="text" name="name" formControlName="name"
|
||||
required>
|
||||
<mat-error *ngIf="formGroup.get('name').hasError('backendError')">
|
||||
{{formGroup.get('name').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.get('name').hasError('required')">
|
||||
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="row mt-4">
|
||||
<div class="col-auto">
|
||||
<button mat-button class="action-btn" (click)="cancel()" type="button">{{'DESCRIPTION-TYPE-EDITOR.ACTIONS.CANCEL' | translate}}</button>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto">
|
||||
<button mat-button *ngIf="formGroup.get('status').value!=1" class="action-btn" (click)="finalize()"
|
||||
[disabled]="!this.isFormValid()" type="button">{{'DESCRIPTION-TYPE-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
|
||||
<button mat-button class="action-btn ml-3" type="submit" [disabled]="!this.isFormValid() || viewOnly">
|
||||
{{'DESCRIPTION-TYPE-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</form>
|
||||
</div>
|
||||
</div> -->
|
|
@ -1,7 +1,9 @@
|
|||
.description-type-editor {
|
||||
margin-top: 1.3rem;
|
||||
margin-left: 1em;
|
||||
margin-right: 3em;
|
||||
.description-template-type-editor {
|
||||
padding-top: 1em;
|
||||
|
||||
.editor-actions {
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn {
|
|
@ -0,0 +1,173 @@
|
|||
import { DatePipe } from '@angular/common';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { DescriptionTemplateType, DescriptionTemplateTypePersist } from '@app/core/model/description-template-type/description-template-type';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service';
|
||||
import { LoggingService } from '@app/core/services/logging/logging-service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
||||
import { BaseEditor } from '@common/base/base-editor';
|
||||
import { FormService } from '@common/forms/form-service';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||
import { FilterService } from '@common/modules/text-filter/filter-service';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { DescriptionTemplateTypeEditorModel } from './description-template-type-editor.model';
|
||||
import { DescriptionTemplateTypeEditorResolver } from './description-template-type-editor.resolver';
|
||||
import { DescriptionTemplateTypeEditorService } from './description-template-type-editor.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: './description-template-type-editor.component.html',
|
||||
styleUrls: ['./description-template-type-editor.component.scss'],
|
||||
providers: [DescriptionTemplateTypeEditorService]
|
||||
})
|
||||
export class DescriptionTemplateTypeEditorComponent extends BaseEditor<DescriptionTemplateTypeEditorModel, DescriptionTemplateType> implements OnInit {
|
||||
|
||||
isNew = true;
|
||||
isDeleted = false;
|
||||
formGroup: UntypedFormGroup = null;
|
||||
showInactiveDetails = false;
|
||||
|
||||
|
||||
protected get canDelete(): boolean {
|
||||
return !this.isDeleted && !this.isNew && this.hasPermission(this.authService.permissionEnum.DeleteDescriptionTemplateType);
|
||||
}
|
||||
|
||||
protected get canSave(): boolean {
|
||||
return !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditDescriptionTemplateType);
|
||||
}
|
||||
|
||||
protected get canFinalize(): boolean {
|
||||
return !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditDescriptionTemplateType);
|
||||
}
|
||||
|
||||
|
||||
private hasPermission(permission: AppPermission): boolean {
|
||||
return this.authService.hasPermission(permission) || this.editorModel?.permissions?.includes(permission);
|
||||
}
|
||||
|
||||
constructor(
|
||||
// BaseFormEditor injected dependencies
|
||||
protected dialog: MatDialog,
|
||||
protected language: TranslateService,
|
||||
protected formService: FormService,
|
||||
protected router: Router,
|
||||
protected uiNotificationService: UiNotificationService,
|
||||
protected httpErrorHandlingService: HttpErrorHandlingService,
|
||||
protected filterService: FilterService,
|
||||
protected datePipe: DatePipe,
|
||||
protected route: ActivatedRoute,
|
||||
protected queryParamsService: QueryParamsService,
|
||||
// Rest dependencies. Inject any other needed deps here:
|
||||
public authService: AuthService,
|
||||
public enumUtils: EnumUtils,
|
||||
private descriptionTemplateTypeService: DescriptionTemplateTypeService,
|
||||
private logger: LoggingService,
|
||||
private descriptionTemplateTypeEditorService: DescriptionTemplateTypeEditorService
|
||||
) {
|
||||
super(dialog, language, formService, router, uiNotificationService, httpErrorHandlingService, filterService, datePipe, route, queryParamsService);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
super.ngOnInit();
|
||||
}
|
||||
|
||||
getItem(itemId: Guid, successFunction: (item: DescriptionTemplateType) => void) {
|
||||
this.descriptionTemplateTypeService.getSingle(itemId, DescriptionTemplateTypeEditorResolver.lookupFields())
|
||||
.pipe(map(data => data as DescriptionTemplateType), takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
data => successFunction(data),
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
}
|
||||
|
||||
prepareForm(data: DescriptionTemplateType) {
|
||||
try {
|
||||
this.editorModel = data ? new DescriptionTemplateTypeEditorModel().fromModel(data) : new DescriptionTemplateTypeEditorModel();
|
||||
this.isDeleted = data ? data.isActive === IsActive.Inactive : false;
|
||||
this.buildForm();
|
||||
} catch (error) {
|
||||
this.logger.error('Could not parse descriptionTemplateType item: ' + data + error);
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
buildForm() {
|
||||
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.authService.hasPermission(AppPermission.EditDescriptionTemplateType));
|
||||
this.descriptionTemplateTypeEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
|
||||
}
|
||||
|
||||
refreshData(): void {
|
||||
this.getItem(this.editorModel.id, (data: DescriptionTemplateType) => this.prepareForm(data));
|
||||
}
|
||||
|
||||
refreshOnNavigateToData(id?: Guid): void {
|
||||
this.formGroup.markAsPristine();
|
||||
let route = [];
|
||||
|
||||
if (id === null) {
|
||||
route.push('../..');
|
||||
} else if (this.isNew) {
|
||||
route.push('../' + id);
|
||||
} else {
|
||||
route.push('..');
|
||||
}
|
||||
|
||||
this.router.navigate(route, { queryParams: { 'lookup': this.queryParamsService.serializeLookup(this.lookupParams), 'lv': ++this.lv }, replaceUrl: true, relativeTo: this.route });
|
||||
}
|
||||
|
||||
persistEntity(onSuccess?: (response) => void): void {
|
||||
const formData = this.formService.getValue(this.formGroup.value) as DescriptionTemplateTypePersist;
|
||||
|
||||
this.descriptionTemplateTypeService.persist(formData)
|
||||
.pipe(takeUntil(this._destroyed)).subscribe(
|
||||
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
}
|
||||
|
||||
formSubmit(): void {
|
||||
this.formService.touchAllFormFields(this.formGroup);
|
||||
if (!this.isFormValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.persistEntity();
|
||||
}
|
||||
|
||||
public delete() {
|
||||
const value = this.formGroup.value;
|
||||
if (value.id) {
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
maxWidth: '300px',
|
||||
data: {
|
||||
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
||||
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
||||
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL')
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
this.descriptionTemplateTypeService.delete(value.id).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onCallbackSuccess(),
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
clearErrorModel() {
|
||||
this.editorModel.validationErrorModel.clear();
|
||||
this.formService.validateAllFormFields(this.formGroup);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status';
|
||||
import { DescriptionTemplateType, DescriptionTemplateTypePersist } from '@app/core/model/description-template-type/description-template-type';
|
||||
import { BaseEditorModel } from '@common/base/base-form-editor-model';
|
||||
import { BackendErrorValidator } from '@common/forms/validation/custom-validator';
|
||||
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
|
||||
import { Validation, ValidationContext } from '@common/forms/validation/validation-context';
|
||||
|
||||
export class DescriptionTemplateTypeEditorModel extends BaseEditorModel implements DescriptionTemplateTypePersist {
|
||||
name: string;
|
||||
status: DescriptionTemplateTypeStatus = DescriptionTemplateTypeStatus.Draft;
|
||||
permissions: string[];
|
||||
|
||||
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
|
||||
protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder();
|
||||
|
||||
constructor() { super(); }
|
||||
|
||||
public fromModel(item: DescriptionTemplateType): DescriptionTemplateTypeEditorModel {
|
||||
if (item) {
|
||||
this.id = item.id;
|
||||
this.name = item.name;
|
||||
this.status = item.status;
|
||||
this.isActive = item.isActive;
|
||||
this.hash = item.hash;
|
||||
if (item.createdAt) { this.createdAt = item.createdAt; }
|
||||
if (item.updatedAt) { this.updatedAt = item.updatedAt; }
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup {
|
||||
if (context == null) { context = this.createValidationContext(); }
|
||||
|
||||
return this.formBuilder.group({
|
||||
id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators],
|
||||
name: [{ value: this.name, disabled: disabled }, context.getValidation('name').validators],
|
||||
status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators],
|
||||
hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators]
|
||||
});
|
||||
}
|
||||
|
||||
createValidationContext(): ValidationContext {
|
||||
const baseContext: ValidationContext = new ValidationContext();
|
||||
const baseValidationArray: Validation[] = new Array<Validation>();
|
||||
baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] });
|
||||
baseValidationArray.push({ key: 'name', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'RenameourceId')] });
|
||||
baseValidationArray.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] });
|
||||
baseValidationArray.push({ key: 'hash', validators: [] });
|
||||
|
||||
baseContext.validation = baseValidationArray;
|
||||
return baseContext;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type';
|
||||
import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service';
|
||||
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
|
||||
import { BaseEditorResolver } from '@common/base/base-editor.resolver';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { takeUntil, tap } from 'rxjs/operators';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
|
||||
@Injectable()
|
||||
export class DescriptionTemplateTypeEditorResolver extends BaseEditorResolver {
|
||||
|
||||
constructor(private descriptionTemplateTypeService: DescriptionTemplateTypeService, private breadcrumbService: BreadcrumbService) {
|
||||
super();
|
||||
}
|
||||
|
||||
public static lookupFields(): string[] {
|
||||
return [
|
||||
...BaseEditorResolver.lookupFields(),
|
||||
nameof<DescriptionTemplateType>(x => x.id),
|
||||
nameof<DescriptionTemplateType>(x => x.name),
|
||||
nameof<DescriptionTemplateType>(x => x.status),
|
||||
nameof<DescriptionTemplateType>(x => x.createdAt),
|
||||
nameof<DescriptionTemplateType>(x => x.hash),
|
||||
nameof<DescriptionTemplateType>(x => x.isActive)
|
||||
]
|
||||
}
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
|
||||
const fields = [
|
||||
...DescriptionTemplateTypeEditorResolver.lookupFields()
|
||||
];
|
||||
return this.descriptionTemplateTypeService.getSingle(Guid.parse(route.paramMap.get('id')), fields).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.name)), takeUntil(this._destroyed));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import { Injectable } from "@angular/core";
|
||||
import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model";
|
||||
|
||||
@Injectable()
|
||||
export class DescriptionTemplateTypeEditorService {
|
||||
private validationErrorModel: ValidationErrorModel;
|
||||
|
||||
public setValidationErrorModel(validationErrorModel: ValidationErrorModel): void {
|
||||
this.validationErrorModel = validationErrorModel;
|
||||
}
|
||||
|
||||
public getValidationErrorModel(): ValidationErrorModel {
|
||||
return this.validationErrorModel;
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
<div class="main-content">
|
||||
<div class="container-fluid description-type-editor">
|
||||
<div class="row align-items-center mb-4" *ngIf="formGroup">
|
||||
<div class="col-auto">
|
||||
<h3>{{'DESCRIPTION-TYPE-EDITOR.NEW' | translate}}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<form *ngIf="formGroup" (ngSubmit)="formSubmit()" [formGroup]="formGroup">
|
||||
<mat-card style="padding: 2em;">
|
||||
<mat-card-content>
|
||||
<div class="row" style="gap:1em">
|
||||
<mat-form-field class="col-lg-6">
|
||||
<input matInput placeholder="{{'DESCRIPTION-TYPE-EDITOR.FIELDS.LABEL' | translate}}" type="text" name="name" formControlName="name"
|
||||
required>
|
||||
<mat-error *ngIf="formGroup.get('name').hasError('backendError')">
|
||||
{{formGroup.get('name').getError('backendError').message}}</mat-error>
|
||||
<mat-error *ngIf="formGroup.get('name').hasError('required')">
|
||||
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="row mt-4">
|
||||
<div class="col-auto">
|
||||
<button mat-button class="action-btn" (click)="cancel()" type="button">{{'DESCRIPTION-TYPE-EDITOR.ACTIONS.CANCEL' | translate}}</button>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto">
|
||||
<button mat-button *ngIf="formGroup.get('status').value!=1" class="action-btn" (click)="finalize()"
|
||||
[disabled]="!this.isFormValid()" type="button">{{'DESCRIPTION-TYPE-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
|
||||
<button mat-button class="action-btn ml-3" type="submit" [disabled]="!this.isFormValid() || viewOnly">
|
||||
{{'DESCRIPTION-TYPE-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -1,161 +0,0 @@
|
|||
import { AfterViewInit, Component, OnInit } from '@angular/core';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
||||
import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status';
|
||||
import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type';
|
||||
import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { FormService } from '@common/forms/form-service';
|
||||
import { BackendErrorValidator } from '@common/forms/validation/custom-validator';
|
||||
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
|
||||
import { ValidationContext } from '@common/forms/validation/validation-context';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-type-editor',
|
||||
templateUrl: './description-type-editor.component.html',
|
||||
styleUrls: ['./description-type-editor.component.scss']
|
||||
})
|
||||
export class DescriptionTypeEditorComponent extends BaseComponent implements OnInit {
|
||||
|
||||
formGroup: UntypedFormGroup = null;
|
||||
descriptionTypeModel: DescriptionTypeEditorModel;
|
||||
|
||||
isNew = true;
|
||||
viewOnly = false;
|
||||
descriptionTemplateTypeId: string;
|
||||
|
||||
constructor(
|
||||
private descriptionTemplateTypeService: DescriptionTemplateTypeService,
|
||||
private formService: FormService,
|
||||
private uiNotificationService: UiNotificationService,
|
||||
private language: TranslateService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.route.paramMap.pipe(takeUntil(this._destroyed)).subscribe((paramMap: ParamMap) => {
|
||||
this.descriptionTemplateTypeId = paramMap.get('id');
|
||||
|
||||
if (this.descriptionTemplateTypeId != null) {
|
||||
this.isNew = false;
|
||||
this.descriptionTemplateTypeService.get(this.descriptionTemplateTypeId)
|
||||
.pipe(takeUntil(this._destroyed)).subscribe(
|
||||
type => {
|
||||
this.descriptionTypeModel = new DescriptionTypeEditorModel().fromModel(type.items[0]);
|
||||
if (this.descriptionTypeModel.status === DescriptionTemplateTypeStatus.Finalized) {
|
||||
this.formGroup = this.descriptionTypeModel.buildForm(null, true);
|
||||
this.viewOnly = true;
|
||||
}
|
||||
else {
|
||||
this.formGroup = this.descriptionTypeModel.buildForm();
|
||||
}
|
||||
},
|
||||
error => this.uiNotificationService.snackBarNotification(error.message, SnackBarNotificationLevel.Error)
|
||||
);
|
||||
}
|
||||
else {
|
||||
this.descriptionTypeModel = new DescriptionTypeEditorModel();
|
||||
this.descriptionTypeModel.status = DescriptionTemplateTypeStatus.Draft;
|
||||
this.formGroup = this.descriptionTypeModel.buildForm();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
formSubmit(): void {
|
||||
this.formService.touchAllFormFields(this.formGroup);
|
||||
if (!this.isFormValid()) { return; }
|
||||
this.onSubmit();
|
||||
}
|
||||
|
||||
public isFormValid() {
|
||||
return this.formGroup.valid;
|
||||
}
|
||||
|
||||
finalize() {
|
||||
this.formGroup.get('status').setValue(DescriptionTemplateTypeStatus.Finalized);
|
||||
this.onSubmit();
|
||||
}
|
||||
|
||||
onSubmit(): void {
|
||||
if (this.isNew) {
|
||||
this.descriptionTemplateTypeService.persist(this.formGroup.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onCallbackSuccess(true),
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
}
|
||||
else {
|
||||
this.descriptionTemplateTypeService.update(this.formGroup.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onCallbackSuccess(false),
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
onCallbackSuccess(creation: boolean): void {
|
||||
if (creation) {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION'), SnackBarNotificationLevel.Success);
|
||||
}
|
||||
else {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
|
||||
}
|
||||
this.router.navigate(['/description-types']);
|
||||
}
|
||||
|
||||
onCallbackError(errorResponse: any) {
|
||||
this.setErrorModel(errorResponse.error);
|
||||
this.formService.validateAllFormFields(this.formGroup);
|
||||
this.uiNotificationService.snackBarNotification(errorResponse.error.message, SnackBarNotificationLevel.Error);
|
||||
}
|
||||
|
||||
public setErrorModel(validationErrorModel: ValidationErrorModel) {
|
||||
Object.keys(validationErrorModel).forEach(item => {
|
||||
(<any>this.descriptionTypeModel.validationErrorModel)[item] = (<any>validationErrorModel)[item];
|
||||
});
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
this.router.navigate(['/description-types']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class DescriptionTypeEditorModel {
|
||||
public id: string;
|
||||
public name: string;
|
||||
public status: DescriptionTemplateTypeStatus;
|
||||
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
|
||||
|
||||
fromModel(item: DescriptionTemplateType): DescriptionTypeEditorModel {
|
||||
this.id = item.id;
|
||||
this.name = item.name;
|
||||
this.status = item.status;
|
||||
return this;
|
||||
}
|
||||
|
||||
buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup {
|
||||
if (context == null) { context = this.createValidationContext(); }
|
||||
const formGroup = new UntypedFormBuilder().group({
|
||||
id: [this.id],
|
||||
name: [{ value: this.name, disabled: disabled }, context.getValidation('name').validators],
|
||||
status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators]
|
||||
});
|
||||
return formGroup;
|
||||
}
|
||||
|
||||
createValidationContext(): ValidationContext {
|
||||
const baseContext: ValidationContext = new ValidationContext();
|
||||
baseContext.validation.push({ key: 'name', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'name')] });
|
||||
baseContext.validation.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] });
|
||||
return baseContext;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
<div class="row description-template-type-listing-listing">
|
||||
<div class="col-md-8 offset-md-2">
|
||||
|
||||
<div class="row mb-4 mt-3">
|
||||
<div class="col">
|
||||
<h4>{{'DESCRIPTION-TEMPLATE-TYPE-LISTING.TITLE' | translate}}</h4>
|
||||
<app-navigation-breadcrumb />
|
||||
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button mat-raised-button class="create-btn"
|
||||
*ngIf="authService.hasPermission(authService.permissionEnum.EditDescriptionTemplateType)"
|
||||
[routerLink]="['/description-template-type/new']">
|
||||
<mat-icon>add</mat-icon>
|
||||
{{'DESCRIPTION-TEMPLATE-TYPE-LISTING.CREATE-TYPE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-hybrid-listing [rows]="gridRows" [columns]="gridColumns" [visibleColumns]="visibleColumns"
|
||||
[count]="totalElements" [offset]="currentPageNumber" [limit]="lookup.page.size"
|
||||
[defaultSort]="lookup.order?.items" [externalSorting]="true" (rowActivated)="onRowActivated($event)"
|
||||
(pageLoad)="alterPage($event)" (columnSort)="onColumnSort($event)"
|
||||
(columnsChanged)="onColumnsChanged($event)" [listItemTemplate]="listItemTemplate">
|
||||
|
||||
<app-description-template-type-listing-filters hybrid-listing-filters [(filter)]="lookup"
|
||||
(filterChange)="filterChanged($event)" />
|
||||
|
||||
<app-user-settings-picker [key]="userSettingsKey" [userPreference]="lookup"
|
||||
(onSettingSelected)="changeSetting($event)" [autoSelectUserSettings]="autoSelectUserSettings"
|
||||
user-preference-settings />
|
||||
<button mat-icon-button download-listing-report>
|
||||
<mat-icon>download</mat-icon>
|
||||
</button>
|
||||
</app-hybrid-listing>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #listItemTemplate let-item="item" let-isColumnSelected="isColumnSelected">
|
||||
|
||||
|
||||
<div class="d-flex align-items-center p-3 gap-1-rem">
|
||||
<div class="row">
|
||||
<ng-container *ngIf="isColumnSelected('name')">
|
||||
<a class="buttonLinkClass" [routerLink]="'./' + item?.id" class="col-12"
|
||||
(click)="$event.stopPropagation()">{{item?.name | nullifyValue}}</a>
|
||||
<br />
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="isColumnSelected('status')">
|
||||
<div class="col-auto">
|
||||
<div class="status-chip"
|
||||
[ngClass]="{'status-chip-finalized': item.status === descriptionTemplateTypeStatuses.Finalized, 'status-chip-draft' : item.status === descriptionTemplateTypeStatuses.Draft}">
|
||||
{{enumUtils.toDescriptionTemplateTypeStatusString(item.status) | nullifyValue}}
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="isColumnSelected('createdAt')">
|
||||
<span class="col-12">
|
||||
{{'DESCRIPTION-TEMPLATE-TYPE-LISTING.FIELDS.CREATED-AT' | translate}}:
|
||||
<small>
|
||||
{{item?.createdAt | dateTimeFormatter : 'short' | nullifyValue}}
|
||||
</small>
|
||||
</span>
|
||||
<br>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="isColumnSelected('updatedAt')">
|
||||
<span class="col-12">
|
||||
{{'DESCRIPTION-TEMPLATE-TYPE-LISTING.FIELDS.UPDATED-AT' | translate}}:
|
||||
<small>
|
||||
{{item?.updatedAt | dateTimeFormatter : 'short' | nullifyValue}}
|
||||
</small>
|
||||
</span>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #descriptionTemplateTypeStatus let-row="row" let-item>
|
||||
<div class="row">
|
||||
<div class="col-auto status-chip"
|
||||
[ngClass]="{'status-chip-finalized': row.status === descriptionTemplateTypeStatuses.Finalized, 'status-chip-draft' : row.status === descriptionTemplateTypeStatuses.Draft}">
|
||||
{{enumUtils.toDescriptionTemplateTypeStatusString(row.status) | nullifyValue}}
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #actions let-row="row" let-item>
|
||||
<div class="row" (click)="$event.stopPropagation()">
|
||||
<div class="col-auto">
|
||||
<button mat-icon-button [matMenuTriggerFor]="actionsMenu">
|
||||
<mat-icon>more_horiz</mat-icon>
|
||||
</button>
|
||||
<mat-menu #actionsMenu="matMenu">
|
||||
<button mat-menu-item [routerLink]="['/description-template-type/' + row.id]">
|
||||
<mat-icon>edit</mat-icon>{{'DESCRIPTION-TEMPLATE-TYPE-LISTING.ACTIONS.EDIT' | translate}}
|
||||
</button>
|
||||
<button mat-menu-item (click)="deleteType(row.id)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
{{'DESCRIPTION-TEMPLATE-TYPE-LISTING.ACTIONS.DELETE' | translate}}
|
||||
</button>
|
||||
<!--<button *ngIf="row.status==1" mat-menu-item (click)="makeItPublic(row.id)"><mat-icon>people_outline</mat-icon>{{'DATASET-LISTING.ACTIONS.MAKE-IT-PUBLIC' | translate}}</button> -->
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
|
@ -1,8 +1,4 @@
|
|||
.mat-table {
|
||||
margin-top: 47px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.description-types-listing {
|
||||
.description-template-type-listing {
|
||||
margin-top: 1.3rem;
|
||||
margin-left: 1rem;
|
||||
margin-right: 2rem;
|
||||
|
@ -28,13 +24,6 @@
|
|||
z-index: 5;
|
||||
}
|
||||
}
|
||||
// PAGINATOR
|
||||
:host ::ng-deep .mat-paginator-container {
|
||||
flex-direction: row-reverse !important;
|
||||
justify-content: space-between !important;
|
||||
background-color: #f6f6f6;
|
||||
align-items: center;
|
||||
}
|
||||
.create-btn {
|
||||
border-radius: 30px;
|
||||
background-color: var(--secondary-color);
|
|
@ -0,0 +1,177 @@
|
|||
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type';
|
||||
import { DescriptionTemplateTypeLookup } from '@app/core/query/description-template-type.lookup';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
||||
import { BaseListingComponent } from '@common/base/base-listing-component';
|
||||
import { PipeService } from '@common/formatting/pipe.service';
|
||||
import { DataTableDateTimeFormatPipe } from '@common/formatting/pipes/date-time-format.pipe';
|
||||
import { QueryResult } from '@common/model/query-result';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||
import { ColumnDefinition, ColumnsChangedEvent, HybridListingComponent, PageLoadEvent } from '@common/modules/hybrid-listing/hybrid-listing.component';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
|
||||
@Component({
|
||||
templateUrl: './description-template-type-listing.component.html',
|
||||
styleUrls: ['./description-template-type-listing.component.scss']
|
||||
})
|
||||
export class DescriptionTemplateTypeListingComponent extends BaseListingComponent<DescriptionTemplateType, DescriptionTemplateTypeLookup> implements OnInit {
|
||||
publish = false;
|
||||
userSettingsKey = { key: 'DescriptionTemplateTypeListingUserSettings' };
|
||||
propertiesAvailableForOrder: ColumnDefinition[];
|
||||
descriptionTemplateTypeStatuses = DescriptionTemplateTypeStatus;
|
||||
|
||||
@ViewChild('descriptionTemplateTypeStatus', { static: true }) descriptionTemplateTypeStatus?: TemplateRef<any>;
|
||||
@ViewChild('actions', { static: true }) actions?: TemplateRef<any>;
|
||||
@ViewChild(HybridListingComponent, { static: true }) hybridListingComponent: HybridListingComponent;
|
||||
|
||||
private readonly lookupFields: string[] = [
|
||||
nameof<DescriptionTemplateType>(x => x.id),
|
||||
nameof<DescriptionTemplateType>(x => x.name),
|
||||
nameof<DescriptionTemplateType>(x => x.status),
|
||||
nameof<DescriptionTemplateType>(x => x.updatedAt),
|
||||
nameof<DescriptionTemplateType>(x => x.createdAt),
|
||||
nameof<DescriptionTemplateType>(x => x.hash),
|
||||
nameof<DescriptionTemplateType>(x => x.isActive)
|
||||
];
|
||||
|
||||
rowIdentity = x => x.id;
|
||||
|
||||
constructor(
|
||||
protected router: Router,
|
||||
protected route: ActivatedRoute,
|
||||
protected uiNotificationService: UiNotificationService,
|
||||
protected httpErrorHandlingService: HttpErrorHandlingService,
|
||||
protected queryParamsService: QueryParamsService,
|
||||
private descriptionTemplateTypeService: DescriptionTemplateTypeService,
|
||||
public authService: AuthService,
|
||||
private pipeService: PipeService,
|
||||
public enumUtils: EnumUtils,
|
||||
private language: TranslateService,
|
||||
private dialog: MatDialog
|
||||
) {
|
||||
super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService);
|
||||
// Lookup setup
|
||||
// Default lookup values are defined in the user settings class.
|
||||
this.lookup = this.initializeLookup();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
super.ngOnInit();
|
||||
}
|
||||
|
||||
protected initializeLookup(): DescriptionTemplateTypeLookup {
|
||||
const lookup = new DescriptionTemplateTypeLookup();
|
||||
lookup.metadata = { countAll: true };
|
||||
lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE };
|
||||
lookup.isActive = [IsActive.Active];
|
||||
lookup.order = { items: [this.toDescSortField(nameof<DescriptionTemplateType>(x => x.createdAt))] };
|
||||
this.updateOrderUiFields(lookup.order);
|
||||
|
||||
lookup.project = {
|
||||
fields: this.lookupFields
|
||||
};
|
||||
|
||||
return lookup;
|
||||
}
|
||||
|
||||
protected setupColumns() {
|
||||
this.gridColumns.push(...[{
|
||||
prop: nameof<DescriptionTemplateType>(x => x.name),
|
||||
sortable: true,
|
||||
languageName: 'DESCRIPTION-TEMPLATE-TYPE-LISTING.FIELDS.NAME'
|
||||
}, {
|
||||
prop: nameof<DescriptionTemplateType>(x => x.status),
|
||||
sortable: true,
|
||||
languageName: 'DESCRIPTION-TEMPLATE-TYPE-LISTING.FIELDS.STATUS',
|
||||
cellTemplate: this.descriptionTemplateTypeStatus
|
||||
},
|
||||
// {
|
||||
// prop: nameof<DescriptionTemplateType>(x => x.isExclude),
|
||||
// languageName: 'DESCRIPTION-TEMPLATE-TYPE-LISTING.FIELDS.IS-EXCLUDE',
|
||||
// pipe: this.pipeService.getPipe<IsExcludeTypePipe>(IsExcludeTypePipe)
|
||||
// },
|
||||
{
|
||||
prop: nameof<DescriptionTemplateType>(x => x.createdAt),
|
||||
sortable: true,
|
||||
languageName: 'DESCRIPTION-TEMPLATE-TYPE-LISTING.FIELDS.CREATED-AT',
|
||||
pipe: this.pipeService.getPipe<DataTableDateTimeFormatPipe>(DataTableDateTimeFormatPipe).withFormat('short')
|
||||
},
|
||||
{
|
||||
prop: nameof<DescriptionTemplateType>(x => x.updatedAt),
|
||||
sortable: true,
|
||||
languageName: 'DESCRIPTION-TEMPLATE-TYPE-LISTING.FIELDS.UPDATED-AT',
|
||||
pipe: this.pipeService.getPipe<DataTableDateTimeFormatPipe>(DataTableDateTimeFormatPipe).withFormat('short')
|
||||
},
|
||||
{
|
||||
alwaysShown: true,
|
||||
cellTemplate: this.actions,
|
||||
maxWidth: 120
|
||||
}
|
||||
]);
|
||||
this.propertiesAvailableForOrder = this.gridColumns.filter(x => x.sortable);
|
||||
}
|
||||
|
||||
//
|
||||
// Listing Component functions
|
||||
//
|
||||
onColumnsChanged(event: ColumnsChangedEvent) {
|
||||
super.onColumnsChanged(event);
|
||||
this.onColumnsChangedInternal(event.properties.map(x => x.toString()));
|
||||
}
|
||||
|
||||
private onColumnsChangedInternal(columns: string[]) {
|
||||
// Here are defined the projection fields that always requested from the api.
|
||||
const fields = new Set(this.lookupFields);
|
||||
this.gridColumns.map(x => x.prop)
|
||||
.filter(x => !columns?.includes(x as string))
|
||||
.forEach(item => {
|
||||
fields.delete(item as string)
|
||||
});
|
||||
this.lookup.project = { fields: [...fields] };
|
||||
this.onPageLoad({ offset: 0 } as PageLoadEvent);
|
||||
}
|
||||
|
||||
protected loadListing(): Observable<QueryResult<DescriptionTemplateType>> {
|
||||
return this.descriptionTemplateTypeService.query(this.lookup);
|
||||
}
|
||||
|
||||
public deleteType(id: Guid) {
|
||||
if (id) {
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
maxWidth: '300px',
|
||||
data: {
|
||||
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
||||
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
||||
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL')
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
this.descriptionTemplateTypeService.delete(id).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onCallbackSuccess(),
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onCallbackSuccess(): void {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success);
|
||||
this.ngOnInit();
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
<div class="main-content">
|
||||
<div class="container-fluid description-types-listing">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-auto">
|
||||
<h3>{{'DESCRIPTION-TYPES-LISTING.TITLE' | translate}}</h3>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto">
|
||||
<button mat-raised-button class="create-btn ml-md-3" [routerLink]="['/description-types/new']">
|
||||
<span class="button-text">
|
||||
{{'DESCRIPTION-TYPES-LISTING.CREATE-TYPE' | translate}}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <app-dmp-profile-criteria-component></app-dmp-profile-criteria-component> -->
|
||||
<div class="mat-elevation-z6">
|
||||
<mat-table [dataSource]="dataSource" matSort (matSortChange)="refresh()">
|
||||
|
||||
<!-- Column Definition: Name -->
|
||||
<ng-container cdkColumnDef="label">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header="label">
|
||||
{{'DESCRIPTION-TYPES-LISTING.COLUMNS.NAME' | translate}}</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{row.name}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container cdkColumnDef="status">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header="status">{{'DESCRIPTION-TYPES-LISTING.COLUMNS.STATUS' |
|
||||
translate}}</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">
|
||||
<div [ngClass]="['status-chip',getStatusClass(row.status)]">{{parseStatus(row.status) | translate}}</div>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container cdkColumnDef="delete">
|
||||
<mat-header-cell *matHeaderCellDef></mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" (click)="$event.stopPropagation()">
|
||||
<button mat-icon-button (click)="deleteTemplate(row.id)">
|
||||
<mat-icon [matTooltip]="('DESCRIPTION-TYPES-LISTING.ACTIONS.DELETE' | translate)"
|
||||
matTooltipPosition="right" class="dlt-btn">delete</mat-icon>
|
||||
</button>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns" (click)="rowClick(row.id)"></mat-row>
|
||||
|
||||
</mat-table>
|
||||
<mat-paginator #paginator [pageSizeOptions]="[10, 25, 100]">
|
||||
</mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,173 +0,0 @@
|
|||
import { DataSource } from '@angular/cdk/table';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { Component, EventEmitter, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { Router } from '@angular/router';
|
||||
import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type';
|
||||
import { DescriptionTemplateTypeLookup } from '@app/core/query/description-template/description-template-type.lookup';
|
||||
import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Observable, merge } from 'rxjs';
|
||||
import { map, startWith, switchMap, takeUntil } from 'rxjs/operators';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-types',
|
||||
templateUrl: './description-types.component.html',
|
||||
styleUrls: ['./description-types.component.scss']
|
||||
})
|
||||
export class DescriptionTypesComponent extends BaseComponent implements OnInit {
|
||||
|
||||
@ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator;
|
||||
@ViewChild(MatSort, { static: true }) _sort: MatSort;
|
||||
|
||||
dataSource: DescriptionTypesDataSource | null;
|
||||
displayedColumns: String[] = ['label', 'status', 'delete'];
|
||||
|
||||
statuses = [
|
||||
{ value: '0', viewValue: 'DESCRIPTION-TYPES-LISTING.STATUS.DRAFT' },
|
||||
{ value: '1', viewValue: 'DESCRIPTION-TYPES-LISTING.STATUS.FINALIZED' }
|
||||
];
|
||||
|
||||
constructor(
|
||||
private descriptionTemplateTypeService: DescriptionTemplateTypeService,
|
||||
private dialog: MatDialog,
|
||||
private language: TranslateService,
|
||||
private uiNotificationService: UiNotificationService,
|
||||
private router: Router
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.dataSource = new DescriptionTypesDataSource(this.descriptionTemplateTypeService, this._paginator, this._sort);
|
||||
}
|
||||
|
||||
rowClick(rowId: String) {
|
||||
this.router.navigate(['description-types/' + rowId]);
|
||||
}
|
||||
|
||||
parseStatus(value: number): string {
|
||||
const stringVal = value.toString()
|
||||
try {
|
||||
return this.statuses.find(status => status.value === stringVal).viewValue;
|
||||
} catch {
|
||||
return stringVal;
|
||||
}
|
||||
}
|
||||
|
||||
deleteTemplate(id: string) {
|
||||
if (id) {
|
||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||
restoreFocus: false,
|
||||
data: {
|
||||
message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'),
|
||||
confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'),
|
||||
cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'),
|
||||
isDeleteConfirmation: true
|
||||
}
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
this.descriptionTemplateTypeService.delete(id)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Success);
|
||||
this.refresh();
|
||||
},
|
||||
error => {
|
||||
this.onCallbackError(error);
|
||||
if (error.error.statusCode == 674) {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Error);
|
||||
} else {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
onCallbackError(errorResponse: HttpErrorResponse) {
|
||||
this.uiNotificationService.snackBarNotification(errorResponse.message, SnackBarNotificationLevel.Warning);
|
||||
}
|
||||
|
||||
getStatusClass(status: number): string {
|
||||
|
||||
if (status == 1) {
|
||||
return 'status-chip-finalized'
|
||||
}
|
||||
|
||||
return 'status-chip-draft';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class DescriptionTypesDataSource extends DataSource<DescriptionTemplateType> {
|
||||
|
||||
data: DescriptionTemplateType[] = [];
|
||||
loadData: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||
|
||||
constructor(
|
||||
private _service: DescriptionTemplateTypeService,
|
||||
private _paginator: MatPaginator,
|
||||
private _sort: MatSort
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
connect(): Observable<DescriptionTemplateType[]> {
|
||||
const dataChanges = [
|
||||
this._paginator.page,
|
||||
this._sort.sortChange
|
||||
];
|
||||
|
||||
return merge(...dataChanges).pipe(
|
||||
startWith(<string>null),
|
||||
switchMap(() => {
|
||||
let lookup: DescriptionTemplateTypeLookup = new DescriptionTemplateTypeLookup();
|
||||
lookup.page = {
|
||||
offset: this._paginator.pageIndex * this._paginator.pageSize,
|
||||
size: this._paginator.pageSize
|
||||
},
|
||||
lookup.project = {
|
||||
fields: [
|
||||
nameof<DescriptionTemplateType>(x => x.id),
|
||||
nameof<DescriptionTemplateType>(x => x.name),
|
||||
nameof<DescriptionTemplateType>(x => x.status)
|
||||
]
|
||||
};
|
||||
lookup.order = {
|
||||
items: ['name']
|
||||
};
|
||||
return this._service.query(lookup)
|
||||
}),
|
||||
map(result => {
|
||||
return result;
|
||||
}),
|
||||
map(result => {
|
||||
if (!result) { return []; }
|
||||
|
||||
this.data = result.items;
|
||||
this._paginator.length = result.count;
|
||||
return result.items;
|
||||
}));
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
// No-op
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<div class="d-flex align-items-center gap-1-rem">
|
||||
|
||||
<button mat-flat-button [matMenuTriggerFor]="filterMenu" #filterMenuTrigger="matMenuTrigger" (click)="updateFilters()" class="filter-button">
|
||||
<mat-icon aria-hidden="false" [matBadgeHidden]="!appliedFilterCount" [matBadge]="appliedFilterCount" matBadgeColor="warn" matBadgeSize="small">filter_alt</mat-icon>
|
||||
{{'COMMONS.LISTING-COMPONENT.SEARCH-FILTER-BTN' | translate}}
|
||||
</button>
|
||||
|
||||
|
||||
<mat-menu #filterMenu>
|
||||
<div class="p-3" (click)="$event?.stopPropagation?.()">
|
||||
<div class="search-listing-filters-container">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<h4>{{'DESCRIPTION-TEMPLATE-TYPE-LISTING.FILTER.TITLE' | translate}}</h4>
|
||||
<button color="accent" mat-button (click)="clearFilters()">
|
||||
{{'COMMONS.LISTING-COMPONENT.CLEAR-ALL-FILTERS' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<mat-slide-toggle labelPosition="before" [(ngModel)]="internalFilters.isActive">
|
||||
{{'DESCRIPTION-TEMPLATE-TYPE-LISTING.FILTER.IS-ACTIVE' | translate}}
|
||||
</mat-slide-toggle>
|
||||
|
||||
<div class="d-flex justify-content-end align-items-center mt-4 gap-1-rem">
|
||||
<button mat-stroked-button color="primary" (click)="filterMenuTrigger?.closeMenu()">
|
||||
{{'DESCRIPTION-TEMPLATE-TYPE-LISTING.FILTER.CANCEL' | translate}}
|
||||
</button>
|
||||
<button mat-raised-button color="primary" (click)="filterMenuTrigger.closeMenu(); applyFilters();">
|
||||
{{'DESCRIPTION-TEMPLATE-TYPE-LISTING.FILTER.APPLY-FILTERS' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-menu>
|
||||
|
||||
<app-expandable-search-field [(value)]=internalFilters.like (valueChange)="onSearchTermChange($event)" />
|
||||
</div>
|
|
@ -0,0 +1,25 @@
|
|||
.description-template-type-listing-filters {
|
||||
|
||||
}
|
||||
|
||||
::ng-deep.mat-mdc-menu-panel {
|
||||
max-width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
:host::ng-deep.mat-mdc-menu-content:not(:empty) {
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
.filter-button{
|
||||
padding-top: .6rem;
|
||||
padding-bottom: .6rem;
|
||||
// .mat-icon{
|
||||
// font-size: 1.5em;
|
||||
// width: 1.2em;
|
||||
// height: 1.2em;
|
||||
// }
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { DescriptionTemplateTypeFilter } from '@app/core/query/description-template-type.lookup';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
|
||||
@Component({
|
||||
selector: 'app-description-template-type-listing-filters',
|
||||
templateUrl: './description-template-type-listing-filters.component.html',
|
||||
styleUrls: ['./description-template-type-listing-filters.component.scss']
|
||||
})
|
||||
export class DescriptionTemplateTypeListingFiltersComponent extends BaseComponent implements OnInit, OnChanges {
|
||||
|
||||
@Input() readonly filter: DescriptionTemplateTypeFilter;
|
||||
@Output() filterChange = new EventEmitter<DescriptionTemplateTypeFilter>();
|
||||
|
||||
// * State
|
||||
internalFilters: DescriptionTemplateTypeListingFilters = this._getEmptyFilters();
|
||||
|
||||
protected appliedFilterCount: number = 0;
|
||||
constructor(
|
||||
public enumUtils: EnumUtils,
|
||||
) { super(); }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
const filterChange = changes[nameof<DescriptionTemplateTypeListingFiltersComponent>(x => x.filter)]?.currentValue as DescriptionTemplateTypeFilter;
|
||||
if (filterChange) {
|
||||
this.updateFilters()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onSearchTermChange(searchTerm: string): void {
|
||||
this.applyFilters()
|
||||
}
|
||||
|
||||
|
||||
protected updateFilters(): void {
|
||||
this.internalFilters = this._parseToInternalFilters(this.filter);
|
||||
this.appliedFilterCount = this._computeAppliedFilters(this.internalFilters);
|
||||
}
|
||||
|
||||
protected applyFilters(): void {
|
||||
const { isActive, like } = this.internalFilters ?? {}
|
||||
this.filterChange.emit({
|
||||
...this.filter,
|
||||
like,
|
||||
isActive: isActive ? [IsActive.Active] : [IsActive.Inactive]
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private _parseToInternalFilters(inputFilter: DescriptionTemplateTypeFilter): DescriptionTemplateTypeListingFilters {
|
||||
if (!inputFilter) {
|
||||
return this._getEmptyFilters();
|
||||
}
|
||||
|
||||
let { excludedIds, ids, isActive, like } = inputFilter;
|
||||
|
||||
return {
|
||||
isActive: (isActive ?? [])?.includes(IsActive.Active) || !isActive?.length,
|
||||
like: like
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private _getEmptyFilters(): DescriptionTemplateTypeListingFilters {
|
||||
return {
|
||||
isActive: true,
|
||||
like: null,
|
||||
}
|
||||
}
|
||||
|
||||
private _computeAppliedFilters(filters: DescriptionTemplateTypeListingFilters): number {
|
||||
let count = 0;
|
||||
if (filters?.isActive) {
|
||||
count++
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
clearFilters() {
|
||||
this.internalFilters = this._getEmptyFilters();
|
||||
}
|
||||
}
|
||||
|
||||
interface DescriptionTemplateTypeListingFilters {
|
||||
isActive: boolean;
|
||||
like: string;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||
import { NgModule } from "@angular/core";
|
||||
import { AutoCompleteModule } from "@app/library/auto-complete/auto-complete.module";
|
||||
import { UrlListingModule } from '@app/library/url-listing/url-listing.module';
|
||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||
import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module';
|
||||
import { HybridListingModule } from "@common/modules/hybrid-listing/hybrid-listing.module";
|
||||
import { TextFilterModule } from "@common/modules/text-filter/text-filter.module";
|
||||
import { UserSettingsModule } from "@common/modules/user-settings/user-settings.module";
|
||||
import { CommonUiModule } from '@common/ui/common-ui.module';
|
||||
import { NgxDropzoneModule } from "ngx-dropzone";
|
||||
import { DmpBlueprintRoutingModule } from './dmp-blueprint.routing';
|
||||
import { DmpBlueprintEditorComponent } from './editor/dmp-blueprint-editor.component';
|
||||
import { DmpBlueprintExternalAutocompleteFieldEditorComponent } from './editor/external-autocomplete/dmp-blueprint-external-autocomplete-field-editor.component';
|
||||
import { DialodConfirmationUploadDmpBlueprints } from './listing/criteria/dialog-confirmation-upload-blueprint/dialog-confirmation-upload-blueprints.component';
|
||||
import { DmpBlueprintCriteriaComponent } from './listing/criteria/dmp-blueprint-criteria.component';
|
||||
import { DmpBlueprintListingComponent } from './listing/dmp-blueprint-listing.component';
|
||||
import { DmpBlueprintListingFiltersComponent } from "./listing/filters/dmp-blueprint-listing-filters.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonUiModule,
|
||||
CommonFormsModule,
|
||||
UrlListingModule,
|
||||
ConfirmationDialogModule,
|
||||
DmpBlueprintRoutingModule,
|
||||
NgxDropzoneModule,
|
||||
DragDropModule,
|
||||
AutoCompleteModule,
|
||||
HybridListingModule,
|
||||
TextFilterModule,
|
||||
UserSettingsModule
|
||||
],
|
||||
declarations: [
|
||||
DmpBlueprintEditorComponent,
|
||||
DmpBlueprintListingComponent,
|
||||
DmpBlueprintListingFiltersComponent,
|
||||
DmpBlueprintCriteriaComponent,
|
||||
DialodConfirmationUploadDmpBlueprints,
|
||||
DmpBlueprintExternalAutocompleteFieldEditorComponent
|
||||
]
|
||||
})
|
||||
export class DmpBlueprintModule { }
|
|
@ -0,0 +1,18 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { AdminAuthGuard } from '@app/core/admin-auth-guard.service';
|
||||
import { DmpBlueprintEditorComponent } from './editor/dmp-blueprint-editor.component';
|
||||
import { DmpBlueprintListingComponent } from './listing/dmp-blueprint-listing.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: DmpBlueprintListingComponent, canActivate: [AdminAuthGuard] },
|
||||
{ path: 'new', component: DmpBlueprintEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-NEW' } },
|
||||
{ path: 'clone/:cloneid', component: DmpBlueprintEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-CLONE' } },
|
||||
{ path: ':id', component: DmpBlueprintEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-EDIT' } },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class DmpBlueprintRoutingModule { }
|
|
@ -1,10 +1,10 @@
|
|||
<div class="main-content">
|
||||
<div class="container-fluid dmp-profile-editor">
|
||||
<div class="container-fluid dmp-blueprint-editor">
|
||||
<div class="row align-items-center mb-4" *ngIf="formGroup">
|
||||
<div class="col-auto">
|
||||
<h3 *ngIf="isNew && !isClone">{{'DMP-PROFILE-EDITOR.TITLE.NEW' | translate}}</h3>
|
||||
<h3 *ngIf="isNew && !isClone">{{'DMP-BLUEPRINT-EDITOR.TITLE.NEW' | translate}}</h3>
|
||||
<h3 *ngIf="isNew && isClone">
|
||||
<span>{{'DMP-PROFILE-EDITOR.TITLE.NEW-PROFILE-CLONE' | translate}}</span>
|
||||
<span>{{'DMP-BLUEPRINT-EDITOR.TITLE.CLONE' | translate}}</span>
|
||||
{{formGroup.get('label').value}}
|
||||
</h3>
|
||||
<h3 *ngIf="!isNew">{{formGroup.get('label').value}}</h3>
|
||||
|
@ -13,23 +13,23 @@
|
|||
<div class="col-auto" *ngIf="!isNew">
|
||||
<button mat-button class="action-btn" type="button" (click)="delete()">
|
||||
<mat-icon>delete</mat-icon>
|
||||
{{'DMP-PROFILE-EDITOR.ACTIONS.DELETE' | translate}}
|
||||
{{'DMP-BLUEPRINT-EDITOR.ACTIONS.DELETE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="formGroup.get('status').value==1">
|
||||
<button mat-button class="finalize-btn" (click)="downloadXML()"
|
||||
type="button">{{'DMP-PROFILE-EDITOR.ACTIONS.DOWNLOAD-XML' | translate }}</button>
|
||||
type="button">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.DOWNLOAD-XML' | translate }}</button>
|
||||
</div>
|
||||
<div *ngIf="formGroup.get('status').value!=1" class="col-auto">
|
||||
<button mat-button class="finalize-btn" (click)="finalize()"
|
||||
[disabled]="!this.isFormValid()" type="button">{{'DMP-PROFILE-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
|
||||
[disabled]="!this.isFormValid()" type="button">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<form *ngIf="formGroup" (ngSubmit)="formSubmit()" [formGroup]="formGroup">
|
||||
<mat-card style="padding: 2em;">
|
||||
<!-- <mat-card-header>
|
||||
<mat-card-title *ngIf="isNew">
|
||||
<h4>{{'DMP-PROFILE-EDITOR.TITLE.NEW' | translate}}</h4>
|
||||
<h4>{{'DMP-BLUEPRINT-EDITOR.TITLE.NEW' | translate}}</h4>
|
||||
</mat-card-title>
|
||||
<mat-card-title *ngIf="!isNew">
|
||||
<h4>{{formGroup.get('label').value}}</h4>
|
||||
|
@ -148,7 +148,7 @@
|
|||
</div>
|
||||
<div [hidden]="viewOnly" class="field-delete col-1" (click)="removeSystemFieldWithIndex(sectionIndex, fieldIndex)">
|
||||
<mat-icon class="field-delete-icon">delete</mat-icon>
|
||||
<span class="field-delete-text">{{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
|
||||
<span class="field-delete-text">{{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
|
@ -192,7 +192,7 @@
|
|||
</div>
|
||||
<div [hidden]="viewOnly" class="field-delete col-1" (click)="removeExtraField(sectionIndex, fieldIndex)">
|
||||
<mat-icon class="field-delete-icon">delete</mat-icon>
|
||||
<span class="field-delete-text">{{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
|
||||
<span class="field-delete-text">{{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
|
@ -210,7 +210,7 @@
|
|||
<div class="col-12">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-checkbox formControlName="hasTemplates" (change)="checkForProfiles($event, sectionIndex)">
|
||||
<mat-checkbox formControlName="hasTemplates" (change)="checkForBlueprints($event, sectionIndex)">
|
||||
Description Templates
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
|
@ -222,9 +222,9 @@
|
|||
<div class="col-12">
|
||||
<mat-form-field>
|
||||
<mat-label>Description Templates</mat-label>
|
||||
<app-multiple-auto-complete placeholder="Description Templates" [disabled]="viewOnly" [value]="descriptionTemplatesPerSection[sectionIndex]" [hidePlaceholder]="true" required='false' [configuration]="profilesAutoCompleteConfiguration" (optionRemoved)="onRemoveTemplate($event, sectionIndex)" (optionSelected)="onOptionSelected($event, sectionIndex)">
|
||||
<app-multiple-auto-complete placeholder="Description Templates" [disabled]="viewOnly" [value]="descriptionTemplatesPerSection[sectionIndex]" [hidePlaceholder]="true" required='false' [configuration]="blueprintsAutoCompleteConfiguration" (optionRemoved)="onRemoveTemplate($event, sectionIndex)" (optionSelected)="onOptionSelected($event, sectionIndex)">
|
||||
</app-multiple-auto-complete>
|
||||
<!-- <button matSuffix class="input-btn" (click)="allAvailableProfiles($event)">
|
||||
<!-- <button matSuffix class="input-btn" (click)="allAvailableBlueprints($event)">
|
||||
<mat-icon class="icon-btn">view_list</mat-icon>
|
||||
</button> -->
|
||||
</mat-form-field>
|
||||
|
@ -267,7 +267,7 @@
|
|||
</div> -->
|
||||
<div [hidden]="viewOnly" class="action-list-item col-auto dlt-section-btn" (click)="removeSection(sectionIndex)" [disabled]="viewOnly">
|
||||
<mat-icon class="action-list-icon">delete</mat-icon>
|
||||
<span class="action-list-text">{{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
|
||||
<span class="action-list-text">{{'DMP-BLUEPRINT-EDITOR.STEPS.TOOLKIT.DELETE' | translate}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -285,105 +285,15 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="col-12">
|
||||
<div class="row" *ngFor="let fieldFormGroup of formGroup.get('definition').get('fields')['controls'];let i=index">
|
||||
<div class="col-10">
|
||||
<div class="row">
|
||||
<mat-form-field class="col">
|
||||
<input matInput placeholder="{{'DMP-PROFILE-EDITOR.FIELDS.LABEL' | translate}}" type="text" name="label" [formControl]="fieldFormGroup.get('label')"
|
||||
required>
|
||||
<mat-error *ngIf="fieldFormGroup.get('label').hasError('required')">
|
||||
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
<mat-error *ngIf="fieldFormGroup.get('label').hasError('backendError')">
|
||||
{{fieldFormGroup.get('label').getError('backendError').message}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col">
|
||||
<mat-select placeholder="{{'DMP-PROFILE-EDITOR.FIELDS.TYPE' | translate}}" [formControl]="fieldFormGroup.get('type')" required>
|
||||
<mat-option *ngFor="let fieldType of getDMPProfileFieldTypeValues()" [value]="fieldType">
|
||||
{{ getDMPProfileFieldTypeWithLanguage(fieldType) | translate}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="fieldFormGroup.get('type').hasError('required')">
|
||||
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
<mat-error *ngIf="fieldFormGroup.get('type').hasError('backendError')">
|
||||
{{fieldFormGroup.get('type').getError('backendError').message}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col">
|
||||
<mat-select placeholder="{{'DMP-PROFILE-EDITOR.FIELDS.DATATYPE' | translate}}" [formControl]="fieldFormGroup.get('dataType')"
|
||||
required>
|
||||
<mat-option *ngFor="let fieldDataType of getDMPProfileFieldDataTypeValues()" [value]="fieldDataType">
|
||||
{{ getDMPProfileFieldDataTypeWithLanguage(fieldDataType) | translate}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="fieldFormGroup.get('dataType').hasError('required')">
|
||||
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
||||
<mat-error *ngIf="fieldFormGroup.get('dataType').hasError('backendError')">
|
||||
{{fieldFormGroup.get('dataType').getError('backendError').message}}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<div class="centered-row-item col-auto">
|
||||
<mat-checkbox [formControl]="fieldFormGroup.get('required')">
|
||||
{{'DMP-PROFILE-EDITOR.FIELDS.REQUIRED' | translate}}
|
||||
</mat-checkbox>
|
||||
</div>
|
||||
<div *ngIf="isExternalAutocomplete(fieldFormGroup)" class="row">
|
||||
<app-dmp-profile-external-autocomplete-field-editor-component [form]="fieldFormGroup">
|
||||
</app-dmp-profile-external-autocomplete-field-editor-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-2">
|
||||
<div class="row">
|
||||
<div class="col-auto" *ngIf="!isNew">
|
||||
<button mat-icon-button type="button" (click)="removeField(i)" [disabled]="viewOnly">
|
||||
<mat-icon class="mat-24">delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="!isNew && formGroup.get('status').value==0 && i == (formGroup.get('definition').get('fields')['controls'].length - 1)">
|
||||
<button mat-mini-fab color="primary" type="button" (click)="addField()" [disabled]="viewOnly">
|
||||
<mat-icon class="mat-24">add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isNew && i != 0">
|
||||
<button mat-mini-fab class="remove" type="button" (click)="removeField(i)">
|
||||
<mat-icon class="mat-24">remove</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-auto" *ngIf="isNew && i == (formGroup.get('definition').get('fields')['controls'].length - 1)">
|
||||
<button mat-mini-fab color="primary" type="button" (click)="addField()" [disabled]="viewOnly">
|
||||
<mat-icon class="mat-24">add</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="row mt-4">
|
||||
<div class="col-auto">
|
||||
<button mat-button class="action-btn" (click)="cancel()" type="button">{{'DMP-PROFILE-EDITOR.ACTIONS.CANCEL' | translate}}</button>
|
||||
<button mat-button class="action-btn" (click)="cancel()" type="button">{{'DMP-BLUEPRINT-EDITOR.ACTIONS.CANCEL' | translate}}</button>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<!-- <div class="col-auto" *ngIf="!isNew">
|
||||
<button mat-raised-button color="primary" type="button" (click)="delete()">{{'DMP-PROFILE-EDITOR.ACTIONS.DELETE' | translate}}</button>
|
||||
</div>
|
||||
<button mat-raised-button *ngIf="formGroup.get('status').value!=1" class="col-auto" color="primary" (click)="finalize()"
|
||||
[disabled]="!formGroup.valid" type="button">{{'DMP-PROFILE-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
|
||||
<button mat-raised-button *ngIf="formGroup.get('status').value==1" class="col-auto" color="primary" (click)="downloadXML()"
|
||||
type="button">{{'DMP-PROFILE-EDITOR.ACTIONS.DOWNLOAD-XML' | translate }}</button>
|
||||
<div class="col-auto" *ngIf="!viewOnly">
|
||||
<button mat-raised-button color="primary" type="submit" [disabled]="!formGroup.valid">
|
||||
{{'DMP-PROFILE-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
</div> -->
|
||||
|
||||
<div class="col-auto" *ngIf="!viewOnly">
|
||||
<button mat-button class="action-btn" type="submit">
|
||||
{{'DMP-PROFILE-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
{{'DMP-BLUEPRINT-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
|
@ -1,4 +1,4 @@
|
|||
.dmp-profile-editor {
|
||||
.dmp-blueprint-editor {
|
||||
margin-top: 1.3rem;
|
||||
margin-left: 1em;
|
||||
margin-right: 3em;
|
|
@ -1,85 +1,80 @@
|
|||
|
||||
import { AfterViewInit, Component, ViewChild } from '@angular/core';
|
||||
import { UntypedFormArray, UntypedFormBuilder, FormControl, UntypedFormGroup, Validators } from '@angular/forms';
|
||||
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { AfterViewInit, Component } from '@angular/core';
|
||||
import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { DmpProfileFieldDataType } from '@app/core/common/enum/dmp-profile-field-type';
|
||||
import { DmpProfileStatus } from '@app/core/common/enum/dmp-profile-status';
|
||||
import { DmpProfileType } from '@app/core/common/enum/dmp-profile-type';
|
||||
import { DmpProfile } from '@app/core/model/dmp-profile/dmp-profile';
|
||||
import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service';
|
||||
import { DmpBlueprintFieldDataType } from '@app/core/common/enum/dmp-blueprint-field-type';
|
||||
import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status';
|
||||
import { DmpBlueprintType } from '@app/core/common/enum/dmp-blueprint-type';
|
||||
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
|
||||
import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile';
|
||||
import { DmpBlueprint, ExtraFieldType, FieldCategory, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint';
|
||||
import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria';
|
||||
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
|
||||
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { DmpProfileEditorModel, DmpProfileFieldEditorModel } from '@app/ui/admin/dmp-profile/editor/dmp-profile-editor.model';
|
||||
import { DmpProfileExternalAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dmp-profile/editor/external-autocomplete/dmp-profile-external-autocomplete-field-editor.model';
|
||||
import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
||||
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
|
||||
import { DmpBlueprintExternalAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dmp-blueprint/editor/external-autocomplete/dmp-blueprint-external-autocomplete-field-editor.model';
|
||||
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
||||
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
import { FormService } from '@common/forms/form-service';
|
||||
import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component';
|
||||
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { environment } from 'environments/environment';
|
||||
import * as FileSaver from 'file-saver';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { MatomoService } from '@app/core/services/matomo/matomo-service';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
|
||||
import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile';
|
||||
import { DataTableRequest } from '@app/core/model/data-table/data-table-request';
|
||||
import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria';
|
||||
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||
import { AvailableProfilesComponent } from '@app/ui/dmp/editor/available-profiles/available-profiles.component';
|
||||
import { DatasetPreviewDialogComponent } from '@app/ui/dmp/dataset-preview/dataset-preview-dialog.component';
|
||||
import { CdkDragDrop, CdkDropList, CdkDrag, moveItemInArray } from '@angular/cdk/drag-drop';
|
||||
import { DmpBlueprint, DmpBlueprintDefinition, ExtraFieldType, FieldCategory, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint';
|
||||
import { DescriptionTemplatesInSectionEditor, DmpBlueprintEditor, FieldInSectionEditor, SectionDmpBlueprintEditor } from './dmp-blueprint-editor.model';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
|
||||
import { DmpBlueprintListing } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing';
|
||||
import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component';
|
||||
import { DmpBlueprintEditorModel } from './dmp-profile-editor.model';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-dmp-profile-editor-component',
|
||||
templateUrl: 'dmp-profile-editor.component.html',
|
||||
styleUrls: ['./dmp-profile-editor.component.scss']
|
||||
selector: 'app-dmp-blueprint-editor-component',
|
||||
templateUrl: 'dmp-blueprint-editor.component.html',
|
||||
styleUrls: ['./dmp-blueprint-editor.component.scss']
|
||||
})
|
||||
export class DmpProfileEditorComponent extends BaseComponent implements AfterViewInit {
|
||||
export class DmpBlueprintEditorComponent extends BaseComponent implements AfterViewInit {
|
||||
|
||||
isNew = true;
|
||||
isClone = false;
|
||||
viewOnly = false;
|
||||
dmpProfileModel: DmpProfileEditorModel;
|
||||
dmpBlueprintModel: DmpBlueprintEditor;
|
||||
dmpBlueprintEditorModel = new DmpBlueprintEditorModel();
|
||||
dmpBlueprintEditor = new DmpBlueprintEditor();
|
||||
formGroup: UntypedFormGroup = null;
|
||||
host: string;
|
||||
dmpProfileId: string;
|
||||
breadCrumbs: Observable<BreadcrumbItem[]>;
|
||||
dmpBlueprintId: string;
|
||||
// breadCrumbs: Observable<BreadcrumbItem[]>;
|
||||
|
||||
dmpBlueprintsFormGroup: UntypedFormGroup = null;
|
||||
|
||||
profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
|
||||
blueprintsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
|
||||
|
||||
fieldList = [
|
||||
{label: 'Title', type: SystemFieldType.TEXT},
|
||||
{label: 'Description', type: SystemFieldType.HTML_TEXT},
|
||||
{label: 'Researchers', type: SystemFieldType.RESEARCHERS},
|
||||
{label: 'Organizations', type: SystemFieldType.ORGANIZATIONS},
|
||||
{label: 'Language', type: SystemFieldType.LANGUAGE},
|
||||
{label: 'Contact', type: SystemFieldType.CONTACT},
|
||||
{label: 'Funder', type: SystemFieldType.FUNDER},
|
||||
{label: 'Grant', type: SystemFieldType.GRANT},
|
||||
{label: 'Project', type: SystemFieldType.PROJECT},
|
||||
{label: 'License', type: SystemFieldType.LICENSE},
|
||||
{label: 'Access Rights', type: SystemFieldType.ACCESS_RIGHTS}
|
||||
{ label: 'Title', type: SystemFieldType.TEXT },
|
||||
{ label: 'Description', type: SystemFieldType.HTML_TEXT },
|
||||
{ label: 'Researchers', type: SystemFieldType.RESEARCHERS },
|
||||
{ label: 'Organizations', type: SystemFieldType.ORGANIZATIONS },
|
||||
{ label: 'Language', type: SystemFieldType.LANGUAGE },
|
||||
{ label: 'Contact', type: SystemFieldType.CONTACT },
|
||||
{ label: 'Funder', type: SystemFieldType.FUNDER },
|
||||
{ label: 'Grant', type: SystemFieldType.GRANT },
|
||||
{ label: 'Project', type: SystemFieldType.PROJECT },
|
||||
{ label: 'License', type: SystemFieldType.LICENSE },
|
||||
{ label: 'Access Rights', type: SystemFieldType.ACCESS_RIGHTS }
|
||||
];
|
||||
systemFieldListPerSection: Array<Array<any>> = new Array();
|
||||
descriptionTemplatesPerSection: Array<Array<DatasetProfileModel>> = new Array<Array<DatasetProfileModel>>();
|
||||
|
||||
constructor(
|
||||
private dmpProfileService: DmpProfileService,
|
||||
private dmpBlueprintService: DmpBlueprintService,
|
||||
private _service: DmpService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
|
@ -100,7 +95,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
ngAfterViewInit() {
|
||||
this.matomoService.trackPageView('Admin: DMP Profile Edit');
|
||||
|
||||
this.profilesAutoCompleteConfiguration = {
|
||||
this.blueprintsAutoCompleteConfiguration = {
|
||||
filterFn: this.filterProfiles.bind(this),
|
||||
initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||
displayFn: (item) => item['label'],
|
||||
|
@ -112,67 +107,67 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
this.route.params
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe((params: Params) => {
|
||||
this.dmpProfileId = params['id'];
|
||||
this.dmpBlueprintId = params['id'];
|
||||
const cloneId = params['cloneid'];
|
||||
|
||||
if (this.dmpProfileId != null) {
|
||||
if (this.dmpBlueprintId != null) {
|
||||
this.isNew = false;
|
||||
this.dmpProfileService.getSingleBlueprint(this.dmpProfileId).pipe(map(data => data as DmpBlueprint))
|
||||
this.dmpBlueprintService.getSingleBlueprint(this.dmpBlueprintId).pipe(map(data => data as any))
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(data => {
|
||||
this.dmpBlueprintModel = new DmpBlueprintEditor().fromModel(data);
|
||||
this.formGroup = this.dmpBlueprintModel.buildForm();
|
||||
this.dmpBlueprintEditor = new DmpBlueprintEditor().fromModel(data);
|
||||
this.formGroup = this.dmpBlueprintEditor.buildForm();
|
||||
this.buildSystemFields();
|
||||
this.fillDescriptionTemplatesInMultAutocomplete();
|
||||
if (this.dmpBlueprintModel.status == DmpProfileStatus.Finalized) {
|
||||
if (this.dmpBlueprintEditor.status == DmpBlueprintStatus.Finalized) {
|
||||
this.formGroup.disable();
|
||||
this.viewOnly = true
|
||||
}
|
||||
this.breadCrumbs = observableOf([{
|
||||
parentComponentName: 'DmpProfileListingComponent',
|
||||
label: this.language.instant('NAV-BAR.TEMPLATE'),
|
||||
url: '/dmp-profiles/' + this.dmpProfileId
|
||||
}]);
|
||||
// this.breadCrumbs = observableOf([{
|
||||
// parentComponentName: 'DmpBlueprintListingComponent',
|
||||
// label: this.language.instant('NAV-BAR.TEMPLATE'),
|
||||
// url: '/dmp-blueprints/' + this.dmpBlueprintId
|
||||
// }]);
|
||||
});
|
||||
} else if (cloneId != null) {
|
||||
this.isClone = true;
|
||||
this.dmpProfileService.clone(cloneId).pipe(map(data => data as DmpBlueprint), takeUntil(this._destroyed))
|
||||
this.dmpBlueprintService.clone(cloneId).pipe(map(data => data as any), takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
data => {
|
||||
this.dmpBlueprintModel = new DmpBlueprintEditor().fromModel(data);
|
||||
this.dmpBlueprintModel.id = null;
|
||||
this.dmpBlueprintModel.status = DmpProfileStatus.Draft;
|
||||
this.formGroup = this.dmpBlueprintModel.buildForm();
|
||||
this.dmpBlueprintEditor = new DmpBlueprintEditor().fromModel(data);
|
||||
this.dmpBlueprintEditor.id = null;
|
||||
this.dmpBlueprintEditor.status = DmpBlueprintStatus.Draft;
|
||||
this.formGroup = this.dmpBlueprintEditor.buildForm();
|
||||
this.buildSystemFields();
|
||||
this.fillDescriptionTemplatesInMultAutocomplete();
|
||||
},
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
} else {
|
||||
this.dmpProfileModel = new DmpProfileEditorModel();
|
||||
this.dmpBlueprintModel = new DmpBlueprintEditor();
|
||||
this.dmpBlueprintEditorModel = new DmpBlueprintEditorModel();
|
||||
this.dmpBlueprintEditor = new DmpBlueprintEditor();
|
||||
setTimeout(() => {
|
||||
// this.formGroup = this.dmpProfileModel.buildForm();
|
||||
// this.formGroup = this.dmpBlueprintModel.buildForm();
|
||||
// this.addField();
|
||||
this.dmpBlueprintModel.status = DmpProfileStatus.Draft;
|
||||
this.formGroup = this.dmpBlueprintModel.buildForm();
|
||||
this.dmpBlueprintEditor.status = DmpBlueprintStatus.Draft;
|
||||
this.formGroup = this.dmpBlueprintEditor.buildForm();
|
||||
});
|
||||
this.breadCrumbs = observableOf([{
|
||||
parentComponentName: 'DmpProfileListingComponent',
|
||||
label: this.language.instant('NAV-BAR.TEMPLATE'),
|
||||
url: '/dmp-profiles/' + this.dmpProfileId
|
||||
}]);
|
||||
// this.breadCrumbs = observableOf([{
|
||||
// parentComponentName: 'DmpBlueprintListingComponent',
|
||||
// label: this.language.instant('NAV-BAR.TEMPLATE'),
|
||||
// url: '/dmp-blueprints/' + this.dmpBlueprintId
|
||||
// }]);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
buildSystemFields(){
|
||||
buildSystemFields() {
|
||||
const sections = this.sectionsArray().controls.length;
|
||||
for(let i = 0; i < sections; i++){
|
||||
for (let i = 0; i < sections; i++) {
|
||||
let systemFieldsInSection = new Array();
|
||||
this.fieldsArray(i).controls.forEach((field) => {
|
||||
if((field.get('category').value == FieldCategory.SYSTEM || field.get('category').value == 'SYSTEM')){
|
||||
if ((field.get('category').value == FieldCategory.SYSTEM || field.get('category').value == 'SYSTEM')) {
|
||||
systemFieldsInSection.push(this.fieldList.find(f => f.type == field.get('type').value).type);
|
||||
}
|
||||
})
|
||||
|
@ -180,12 +175,12 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
}
|
||||
}
|
||||
|
||||
fillDescriptionTemplatesInMultAutocomplete(){
|
||||
fillDescriptionTemplatesInMultAutocomplete() {
|
||||
const sections = this.sectionsArray().controls.length;
|
||||
for(let i = 0; i < sections; i++){
|
||||
for (let i = 0; i < sections; i++) {
|
||||
let descriptionTemplatesInSection = new Array<DatasetProfileModel>();
|
||||
this.descriptionTemplatesArray(i).controls.forEach((template) => {
|
||||
descriptionTemplatesInSection.push({id: template.value.descriptionTemplateId, label: template.value.label, description: ""});
|
||||
descriptionTemplatesInSection.push({ id: template.value.descriptionTemplateId, label: template.value.label, description: "" });
|
||||
})
|
||||
this.descriptionTemplatesPerSection.push(descriptionTemplatesInSection);
|
||||
}
|
||||
|
@ -203,7 +198,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
const criteria = new DatasetProfileCriteria();
|
||||
criteria.like = value;
|
||||
request.criteria = criteria;
|
||||
return this._service.searchDMPProfiles(request);
|
||||
return this._service.searchDmpBlueprints(request);
|
||||
}
|
||||
|
||||
sectionsArray(): UntypedFormArray {
|
||||
|
@ -237,7 +232,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
field.id = Guid.create().toString();
|
||||
field.ordinal = this.fieldsArray(sectionIndex).length + 1;
|
||||
field.category = fieldCategory;
|
||||
if(!isNullOrUndefined(fieldType)){
|
||||
if (!isNullOrUndefined(fieldType)) {
|
||||
field.type = fieldType
|
||||
}
|
||||
field.required = (!isNullOrUndefined(fieldType) && (fieldType == 0 || fieldType == 1)) ? true : false;
|
||||
|
@ -268,7 +263,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
this.addField(sectionIndex, FieldCategory.SYSTEM, systemField);
|
||||
}
|
||||
|
||||
transfromEnumToString(type: SystemFieldType): string{
|
||||
transfromEnumToString(type: SystemFieldType): string {
|
||||
return this.fieldList.find(f => f.type == type).label;
|
||||
}
|
||||
|
||||
|
@ -308,8 +303,8 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
|
||||
removeSystemField(sectionIndex: number, systemField: SystemFieldType): void {
|
||||
let i = 0;
|
||||
for(let f of this.fieldsArray(sectionIndex).controls){
|
||||
if((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField){
|
||||
for (let f of this.fieldsArray(sectionIndex).controls) {
|
||||
if ((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField) {
|
||||
this.fieldsArray(sectionIndex).removeAt(i);
|
||||
return;
|
||||
}
|
||||
|
@ -361,12 +356,12 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
|
||||
drop(event: CdkDragDrop<string[]>, sectionIndex: number) {
|
||||
moveItemInArray(this.fieldsArray(sectionIndex).controls, event.previousIndex, event.currentIndex);
|
||||
moveItemInArray(this.fieldsArray(sectionIndex).value, event.previousIndex, event.currentIndex);
|
||||
moveItemInArray(this.fieldsArray(sectionIndex).value, event.previousIndex, event.currentIndex);
|
||||
}
|
||||
|
||||
dropSections(event: CdkDragDrop<string[]>) {
|
||||
moveItemInArray(this.sectionsArray().controls, event.previousIndex, event.currentIndex);
|
||||
moveItemInArray(this.sectionsArray().value, event.previousIndex, event.currentIndex);
|
||||
moveItemInArray(this.sectionsArray().value, event.previousIndex, event.currentIndex);
|
||||
this.sectionsArray().controls.forEach((section, index) => {
|
||||
section.get('ordinal').setValue(index + 1);
|
||||
});
|
||||
|
@ -377,8 +372,8 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
|
||||
const item = formArray.at(fromIndex);
|
||||
for (let i = fromIndex; i * dir < toIndex * dir; i = i + dir) {
|
||||
const current = formArray.at(i + dir);
|
||||
formArray.setControl(i, current);
|
||||
const current = formArray.at(i + dir);
|
||||
formArray.setControl(i, current);
|
||||
}
|
||||
formArray.setControl(toIndex, item);
|
||||
}
|
||||
|
@ -388,8 +383,8 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
// }
|
||||
|
||||
onRemoveTemplate(event, sectionIndex: number) {
|
||||
const profiles = this.descriptionTemplatesArray(sectionIndex).controls;
|
||||
const foundIndex = profiles.findIndex(profile => profile.get('descriptionTemplateId').value === event.id);
|
||||
const blueprints = this.descriptionTemplatesArray(sectionIndex).controls;
|
||||
const foundIndex = blueprints.findIndex(blueprint => blueprint.get('descriptionTemplateId').value === event.id);
|
||||
foundIndex !== -1 && this.descriptionTemplatesArray(sectionIndex).removeAt(foundIndex);
|
||||
}
|
||||
|
||||
|
@ -405,14 +400,14 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
// });
|
||||
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
// if (result) {
|
||||
// let profiles = this.sectionsArray().at(sectionIndex).get('descriptionTemplates').value;//this.formGroup.get('profiles').value;
|
||||
// const profile: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor();
|
||||
// profile.id = Guid.create().toString();
|
||||
// profile.descriptionTemplateId = event.id;
|
||||
// profile.label = event.label;
|
||||
// profiles.push(profile.buildForm());
|
||||
// this.sectionsArray().at(sectionIndex).get('descriptionTemplates').setValue(profiles);//this.formGroup.get('profiles').setValue(profiles);
|
||||
// this.profilesAutoCompleteConfiguration = {
|
||||
// let blueprints = this.sectionsArray().at(sectionIndex).get('descriptionTemplates').value;//this.formGroup.get('blueprints').value;
|
||||
// const blueprint: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor();
|
||||
// blueprint.id = Guid.create().toString();
|
||||
// blueprint.descriptionTemplateId = event.id;
|
||||
// blueprint.label = event.label;
|
||||
// blueprints.push(blueprint.buildForm());
|
||||
// this.sectionsArray().at(sectionIndex).get('descriptionTemplates').setValue(blueprints);//this.formGroup.get('blueprints').setValue(blueprints);
|
||||
// this.blueprintsAutoCompleteConfiguration = {
|
||||
// filterFn: this.filterProfiles.bind(this),
|
||||
// initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
|
||||
// displayFn: (item) => item['label'],
|
||||
|
@ -424,28 +419,28 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
// });
|
||||
// }
|
||||
|
||||
onOptionSelected(item, sectionIndex){
|
||||
const profile: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor();
|
||||
profile.id = Guid.create().toString();
|
||||
profile.descriptionTemplateId = item.id;
|
||||
profile.label = item.label;
|
||||
this.descriptionTemplatesArray(sectionIndex).push(profile.buildForm());
|
||||
onOptionSelected(item, sectionIndex) {
|
||||
const blueprint: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor();
|
||||
blueprint.id = Guid.create().toString();
|
||||
blueprint.descriptionTemplateId = item.id;
|
||||
blueprint.label = item.label;
|
||||
this.descriptionTemplatesArray(sectionIndex).push(blueprint.buildForm());
|
||||
}
|
||||
|
||||
checkValidity() {
|
||||
this.formService.touchAllFormFields(this.formGroup);
|
||||
if (!this.isFormValid()) { return false; }
|
||||
let errorMessages = [];
|
||||
if(!this.hasTitle()) {
|
||||
if (!this.hasTitle()) {
|
||||
errorMessages.push("Title should be set.");
|
||||
}
|
||||
if(!this.hasDescription()) {
|
||||
if (!this.hasDescription()) {
|
||||
errorMessages.push("Description should be set.");
|
||||
}
|
||||
if(!this.hasDescriptionTemplates()) {
|
||||
if (!this.hasDescriptionTemplates()) {
|
||||
errorMessages.push("At least one section should have description templates.");
|
||||
}
|
||||
if(errorMessages.length > 0) {
|
||||
if (errorMessages.length > 0) {
|
||||
this.showValidationErrorsDialog(undefined, errorMessages);
|
||||
return false;
|
||||
}
|
||||
|
@ -483,7 +478,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
autoFocus: false,
|
||||
restoreFocus: false,
|
||||
data: {
|
||||
errorMessages:errmess,
|
||||
errorMessages: errmess,
|
||||
projectOnly: projectOnly
|
||||
},
|
||||
});
|
||||
|
@ -491,7 +486,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
}
|
||||
|
||||
onSubmit(): void {
|
||||
this.dmpProfileService.createBlueprint(this.formGroup.value)
|
||||
this.dmpBlueprintService.createBlueprint(this.formGroup.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onCallbackSuccess(),
|
||||
|
@ -501,7 +496,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
|
||||
onCallbackSuccess(): void {
|
||||
this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
|
||||
this.router.navigate(['/dmp-profiles']);
|
||||
this.router.navigate(['/dmp-blueprints']);
|
||||
}
|
||||
|
||||
onCallbackError(errorResponse: any) {
|
||||
|
@ -511,32 +506,32 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
|
||||
public setErrorModel(validationErrorModel: ValidationErrorModel) {
|
||||
Object.keys(validationErrorModel).forEach(item => {
|
||||
(<any>this.dmpProfileModel.validationErrorModel)[item] = (<any>validationErrorModel)[item];
|
||||
(<any>this.dmpBlueprintEditor.validationErrorModel)[item] = (<any>validationErrorModel)[item];
|
||||
});
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
this.router.navigate(['/dmp-profiles']);
|
||||
this.router.navigate(['/dmp-blueprints']);
|
||||
}
|
||||
|
||||
// addField() {
|
||||
// (<FormArray>this.formGroup.get('definition').get('fields')).push(new DmpProfileFieldEditorModel().buildForm());
|
||||
// (<FormArray>this.formGroup.get('definition').get('fields')).push(new DmpBlueprintFieldEditorModel().buildForm());
|
||||
// }
|
||||
|
||||
// removeField(index: number) {
|
||||
// (<FormArray>this.formGroup.get('definition').get('fields')).controls.splice(index, 1);
|
||||
// }
|
||||
|
||||
getDMPProfileFieldDataTypeValues(): Number[] {
|
||||
let keys: string[] = Object.keys(DmpProfileFieldDataType);
|
||||
getDmpBlueprintFieldDataTypeValues(): Number[] {
|
||||
let keys: string[] = Object.keys(DmpBlueprintFieldDataType);
|
||||
keys = keys.slice(0, keys.length / 2);
|
||||
const values: Number[] = keys.map(Number);
|
||||
return values;
|
||||
}
|
||||
|
||||
getDMPProfileFieldDataTypeWithLanguage(fieldType: DmpProfileFieldDataType): string {
|
||||
getDmpBlueprintFieldDataTypeWithLanguage(fieldType: DmpBlueprintFieldDataType): string {
|
||||
let result = '';
|
||||
this.language.get(this.enumUtils.toDmpProfileFieldDataTypeString(fieldType))
|
||||
this.language.get(this.enumUtils.toDmpBlueprintFieldDataTypeString(fieldType))
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe((value: string) => {
|
||||
result = value;
|
||||
|
@ -544,16 +539,16 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
return result;
|
||||
}
|
||||
|
||||
getDMPProfileFieldTypeValues(): Number[] {
|
||||
let keys: string[] = Object.keys(DmpProfileType);
|
||||
getDmpBlueprintFieldTypeValues(): Number[] {
|
||||
let keys: string[] = Object.keys(DmpBlueprintType);
|
||||
keys = keys.slice(0, keys.length / 2);
|
||||
const values: Number[] = keys.map(Number);
|
||||
return values;
|
||||
}
|
||||
|
||||
getDMPProfileFieldTypeWithLanguage(profileType: DmpProfileType): string {
|
||||
getDmpBlueprintFieldTypeWithLanguage(blueprintType: DmpBlueprintType): string {
|
||||
let result = '';
|
||||
this.language.get(this.enumUtils.toDmpProfileTypeString(profileType))
|
||||
this.language.get(this.enumUtils.toDmpBlueprintTypeString(blueprintType))
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe((value: string) => {
|
||||
result = value;
|
||||
|
@ -562,54 +557,56 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
}
|
||||
|
||||
delete() {
|
||||
this.dialog.open(ConfirmationDialogComponent,{data:{
|
||||
isDeleteConfirmation: true,
|
||||
confirmButton: this.language.instant('DMP-PROFILE-EDITOR.CONFIRM-DELETE-DIALOG.CONFIRM-BUTTON'),
|
||||
cancelButton: this.language.instant("DMP-PROFILE-EDITOR.CONFIRM-DELETE-DIALOG.CANCEL-BUTTON"),
|
||||
message: this.language.instant("DMP-PROFILE-EDITOR.CONFIRM-DELETE-DIALOG.MESSAGE")
|
||||
}})
|
||||
.afterClosed()
|
||||
.subscribe(
|
||||
confirmed =>{
|
||||
if(confirmed){
|
||||
if(this.formGroup.get('status').value == DmpProfileStatus.Draft) {
|
||||
this.formGroup.get('status').setValue(DmpProfileStatus.Deleted);
|
||||
this.dmpProfileService.createBlueprint(this.formGroup.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onCallbackSuccess(),
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
}
|
||||
else {
|
||||
this.dmpProfileService.delete(this.dmpProfileId)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onCallbackSuccess(),
|
||||
error => {
|
||||
if (error.error.statusCode == 674) {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DMP-BLUEPRINT-DELETE'), SnackBarNotificationLevel.Error);
|
||||
} else {
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error);
|
||||
}
|
||||
}
|
||||
);
|
||||
this.dialog.open(ConfirmationDialogComponent, {
|
||||
data: {
|
||||
isDeleteConfirmation: true,
|
||||
confirmButton: this.language.instant('DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.CONFIRM-BUTTON'),
|
||||
cancelButton: this.language.instant("DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.CANCEL-BUTTON"),
|
||||
message: this.language.instant("DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.MESSAGE")
|
||||
}
|
||||
})
|
||||
.afterClosed()
|
||||
.subscribe(
|
||||
confirmed => {
|
||||
if (confirmed) {
|
||||
if (this.formGroup.get('status').value == DmpBlueprintStatus.Draft) {
|
||||
// this.formGroup.get('status').setValue(DmpBlueprintStatus.Deleted);
|
||||
this.dmpBlueprintService.createBlueprint(this.formGroup.value)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
complete => this.onCallbackSuccess(),
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
}
|
||||
else {
|
||||
// this.dmpBlueprintService.delete(this.dmpBlueprintId)
|
||||
// .pipe(takeUntil(this._destroyed))
|
||||
// .subscribe(
|
||||
// complete => this.onCallbackSuccess(),
|
||||
// error => {
|
||||
// if (error.error.statusCode == 674) {
|
||||
// this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DMP-BLUEPRINT-DELETE'), SnackBarNotificationLevel.Error);
|
||||
// } else {
|
||||
// this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error);
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
finalize() {
|
||||
if (this.checkValidity()) {
|
||||
this.formGroup.get('status').setValue(DmpProfileStatus.Finalized);
|
||||
this.formGroup.get('status').setValue(DmpBlueprintStatus.Finalized);
|
||||
this.onSubmit();
|
||||
}
|
||||
}
|
||||
|
||||
downloadXML(): void {
|
||||
this.dmpProfileService.downloadXML(this.dmpProfileId)
|
||||
this.dmpBlueprintService.downloadXML(this.dmpBlueprintId)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(response => {
|
||||
const blob = new Blob([response.body], { type: 'application/xml' });
|
||||
|
@ -639,7 +636,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
}
|
||||
|
||||
isExternalAutocomplete(formGroup: UntypedFormGroup) {
|
||||
if (formGroup.get('dataType').value == DmpProfileFieldDataType.ExternalAutocomplete) {
|
||||
if (formGroup.get('dataType').value == DmpBlueprintFieldDataType.ExternalAutocomplete) {
|
||||
this.addControl(formGroup);
|
||||
return true;
|
||||
} else {
|
||||
|
@ -650,7 +647,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie
|
|||
|
||||
addControl(formGroup: UntypedFormGroup) {
|
||||
if (formGroup.get('dataType').value == 3)
|
||||
formGroup.addControl('externalAutocomplete', new DmpProfileExternalAutoCompleteFieldDataEditorModel().buildForm());
|
||||
formGroup.addControl('externalAutocomplete', new DmpBlueprintExternalAutoCompleteFieldDataEditorModel().buildForm());
|
||||
}
|
||||
|
||||
removeControl(formGroup: UntypedFormGroup) {
|
|
@ -1,4 +1,5 @@
|
|||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
|
||||
import { DmpBlueprintStatus } from "@app/core/common/enum/dmp-blueprint-status";
|
||||
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, FieldCategory, FieldInSection, SectionDmpBlueprint } from "@app/core/model/dmp/dmp-blueprint/dmp-blueprint";
|
||||
import { BackendErrorValidator } from "@common/forms/validation/custom-validator";
|
||||
import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model";
|
||||
|
@ -8,7 +9,7 @@ export class DmpBlueprintEditor {
|
|||
public id: string;
|
||||
public label: string;
|
||||
public definition: DmpBlueprintDefinitionEditor = new DmpBlueprintDefinitionEditor();
|
||||
public status: number;
|
||||
public status: DmpBlueprintStatus;
|
||||
public created: Date;
|
||||
public modified: Date;
|
||||
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
|
|
@ -1,28 +1,29 @@
|
|||
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
|
||||
import { DmpProfileFieldDataType } from '@app/core/common/enum/dmp-profile-field-type';
|
||||
import { DmpProfileType } from '@app/core/common/enum/dmp-profile-type';
|
||||
import { DmpProfile, DmpProfileDefinition } from '@app/core/model/dmp-profile/dmp-profile';
|
||||
import { DmpProfileField } from '@app/core/model/dmp-profile/dmp-profile-field';
|
||||
import { DmpProfileExternalAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dmp-profile/editor/external-autocomplete/dmp-profile-external-autocomplete-field-editor.model';
|
||||
import { DmpBlueprintFieldDataType } from '@app/core/common/enum/dmp-blueprint-field-type';
|
||||
import { DmpBlueprintType } from '@app/core/common/enum/dmp-blueprint-type';
|
||||
import { DmpBlueprint } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||
import { DmpBlueprintField } from '@app/core/model/dmp-blueprint/dmp-blueprint-field';
|
||||
import { DmpBlueprintDefinition } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint';
|
||||
import { DmpBlueprintExternalAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dmp-blueprint/editor/external-autocomplete/dmp-blueprint-external-autocomplete-field-editor.model';
|
||||
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
|
||||
|
||||
export class DmpProfileEditorModel {
|
||||
export class DmpBlueprintEditorModel {
|
||||
|
||||
public id: string;
|
||||
public label: string;
|
||||
public definition: DmpProfileDefinitionEditorModel = new DmpProfileDefinitionEditorModel();
|
||||
public definition: DmpBlueprintDefinitionEditorModel = new DmpBlueprintDefinitionEditorModel();
|
||||
public status: number;
|
||||
public created: Date;
|
||||
public modified: Date;
|
||||
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
|
||||
|
||||
fromModel(item: DmpProfile): DmpProfileEditorModel {
|
||||
this.id = item.id;
|
||||
this.label = item.label;
|
||||
this.definition = new DmpProfileDefinitionEditorModel().fromModel(item.definition);
|
||||
this.status = item.status;
|
||||
this.created = item.created;
|
||||
this.modified = item.modified;
|
||||
fromModel(item: DmpBlueprint): DmpBlueprintEditorModel {
|
||||
// this.id = item.id;
|
||||
// this.label = item.label;
|
||||
// this.definition = new DmpBlueprintDefinitionEditorModel().fromModel(item.definition);
|
||||
// this.status = item.status;
|
||||
// this.created = item.created;
|
||||
// this.modified = item.modified;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -39,12 +40,12 @@ export class DmpProfileEditorModel {
|
|||
}
|
||||
}
|
||||
|
||||
export class DmpProfileDefinitionEditorModel {
|
||||
export class DmpBlueprintDefinitionEditorModel {
|
||||
|
||||
public fields: DmpProfileFieldEditorModel[] = new Array<DmpProfileFieldEditorModel>();
|
||||
public fields: DmpBlueprintFieldEditorModel[] = new Array<DmpBlueprintFieldEditorModel>();
|
||||
|
||||
fromModel(item: DmpProfileDefinition): DmpProfileDefinitionEditorModel {
|
||||
if (item.fields) { item.fields.map(x => this.fields.push(new DmpProfileFieldEditorModel().fromModel(x))); }
|
||||
fromModel(item: DmpBlueprintDefinition): DmpBlueprintDefinitionEditorModel {
|
||||
if (item.fields) { item.fields.map(x => this.fields.push(new DmpBlueprintFieldEditorModel().fromModel(x))); }
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -61,16 +62,16 @@ export class DmpProfileDefinitionEditorModel {
|
|||
}
|
||||
}
|
||||
|
||||
export class DmpProfileFieldEditorModel {
|
||||
export class DmpBlueprintFieldEditorModel {
|
||||
public id: string;
|
||||
public type: DmpProfileType;
|
||||
public dataType: DmpProfileFieldDataType;
|
||||
public type: DmpBlueprintType;
|
||||
public dataType: DmpBlueprintFieldDataType;
|
||||
public required = false;
|
||||
public label: string;
|
||||
public value: any;
|
||||
public externalAutocomplete?: DmpProfileExternalAutoCompleteFieldDataEditorModel;
|
||||
public externalAutocomplete?: DmpBlueprintExternalAutoCompleteFieldDataEditorModel;
|
||||
|
||||
fromModel(item: DmpProfileField): DmpProfileFieldEditorModel {
|
||||
fromModel(item: DmpBlueprintField): DmpBlueprintFieldEditorModel {
|
||||
this.type = item.type;
|
||||
this.dataType = item.dataType;
|
||||
this.required = item.required;
|
||||
|
@ -78,7 +79,7 @@ export class DmpProfileFieldEditorModel {
|
|||
this.id = item.id;
|
||||
this.value = item.value;
|
||||
if (item.externalAutocomplete)
|
||||
this.externalAutocomplete = new DmpProfileExternalAutoCompleteFieldDataEditorModel().fromModel(item.externalAutocomplete);
|
||||
this.externalAutocomplete = new DmpBlueprintExternalAutoCompleteFieldDataEditorModel().fromModel(item.externalAutocomplete);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<div class="container external-autocomplete">
|
||||
<div class="row external-autocomplete-field" *ngIf="form.get('externalAutocomplete')">
|
||||
<h5 style="font-weight: bold" class="col-auto">{{'DMP-BLUEPRINT-EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE.TITLE' | translate}}</h5>
|
||||
<mat-checkbox class="col-auto" [formControl]="this.form.get('externalAutocomplete').get('multiAutoComplete')">
|
||||
{{'DMP-BLUEPRINT-EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE.MULTIPLE-AUTOCOMPLETE' | translate}}
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-form-field class="col-md-12">
|
||||
<input matInput placeholder="{{'DMP-BLUEPRINT-EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE.URL' | translate}}" [formControl]="this.form.get('externalAutocomplete').get('url')">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-4">
|
||||
<input matInput placeholder="{{'DMP-BLUEPRINT-EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE.OPTIONS-ROOT' | translate}}"
|
||||
[formControl]="this.form.get('externalAutocomplete').get('optionsRoot')">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-4">
|
||||
<input matInput placeholder="{{'DMP-BLUEPRINT-EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE.LABEL' | translate}}" [formControl]="this.form.get('externalAutocomplete').get('label')">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-md-4">
|
||||
<input matInput placeholder="{{'DMP-BLUEPRINT-EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE.VALUE' | translate}}" [formControl]="this.form.get('externalAutocomplete').get('value')">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,17 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { UntypedFormGroup } from '@angular/forms';
|
||||
import { DmpBlueprintExternalAutoCompleteFieldDataEditorModel } from './dmp-blueprint-external-autocomplete-field-editor.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dmp-blueprint-external-autocomplete-field-editor-component',
|
||||
styleUrls: ['./dmp-blueprint-external-autocomplete-field-editor.component.scss'],
|
||||
templateUrl: './dmp-blueprint-external-autocomplete-field-editor.component.html'
|
||||
})
|
||||
export class DmpBlueprintExternalAutocompleteFieldEditorComponent implements OnInit {
|
||||
|
||||
@Input() form: UntypedFormGroup
|
||||
private externalAutocomplete: DmpBlueprintExternalAutoCompleteFieldDataEditorModel;
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { UntypedFormGroup, UntypedFormBuilder } from "@angular/forms";
|
||||
import { DmpProfileExternalAutoCompleteField } from "../../../../../core/model/dmp-profile/dmp-profile-external-autocomplete";
|
||||
import { DmpBlueprintExternalAutoCompleteField } from "../../../../../core/model/dmp-blueprint/dmp-blueprint-external-autocomplete";
|
||||
|
||||
export class DmpProfileExternalAutoCompleteFieldDataEditorModel {
|
||||
export class DmpBlueprintExternalAutoCompleteFieldDataEditorModel {
|
||||
|
||||
public url: string;
|
||||
public optionsRoot: string;
|
||||
|
@ -11,17 +11,17 @@ export class DmpProfileExternalAutoCompleteFieldDataEditorModel {
|
|||
|
||||
buildForm(disabled: boolean = false, skipDisable: Array<String> = []): UntypedFormGroup {
|
||||
const formGroup = new UntypedFormBuilder().group({
|
||||
url: [{ value: this.url, disabled: (disabled && !skipDisable.includes('DmpProfileExternalAutoCompleteFieldDataEditorModel.url')) }],
|
||||
optionsRoot: [{ value: this.optionsRoot, disabled: (disabled && !skipDisable.includes('DmpProfileExternalAutoCompleteFieldDataEditorModel.optionsRoot')) }],
|
||||
multiAutoComplete: [{ value: this.multiAutoComplete, disabled: (disabled && !skipDisable.includes('DmpProfileExternalAutoCompleteFieldDataEditorModel.multiAutoComplete')) }],
|
||||
label: [{ value: this.label, disabled: (disabled && !skipDisable.includes('DmpProfileExternalAutoCompleteFieldDataEditorModel.label')) }],
|
||||
value: [{ value: this.value, disabled: (disabled && !skipDisable.includes('DmpProfileExternalAutoCompleteFieldDataEditorModel.value')) }],
|
||||
url: [{ value: this.url, disabled: (disabled && !skipDisable.includes('DmpBlueprintExternalAutoCompleteFieldDataEditorModel.url')) }],
|
||||
optionsRoot: [{ value: this.optionsRoot, disabled: (disabled && !skipDisable.includes('DmpBlueprintExternalAutoCompleteFieldDataEditorModel.optionsRoot')) }],
|
||||
multiAutoComplete: [{ value: this.multiAutoComplete, disabled: (disabled && !skipDisable.includes('DmpBlueprintExternalAutoCompleteFieldDataEditorModel.multiAutoComplete')) }],
|
||||
label: [{ value: this.label, disabled: (disabled && !skipDisable.includes('DmpBlueprintExternalAutoCompleteFieldDataEditorModel.label')) }],
|
||||
value: [{ value: this.value, disabled: (disabled && !skipDisable.includes('DmpBlueprintExternalAutoCompleteFieldDataEditorModel.value')) }],
|
||||
|
||||
});
|
||||
return formGroup;
|
||||
}
|
||||
|
||||
fromModel(item: DmpProfileExternalAutoCompleteField): DmpProfileExternalAutoCompleteFieldDataEditorModel {
|
||||
fromModel(item: DmpBlueprintExternalAutoCompleteField): DmpBlueprintExternalAutoCompleteFieldDataEditorModel {
|
||||
this.url = item.url;
|
||||
this.optionsRoot = item.optionsRoot;
|
||||
this.multiAutoComplete = item.multiAutoComplete;
|
|
@ -10,7 +10,7 @@
|
|||
<div class="row">
|
||||
<div class="col-12">
|
||||
<ngx-dropzone class="drop-file" (change)="selectXML($event)" [accept]="'text/xml'" [multiple]="false">
|
||||
<ngx-dropzone-preview class="file-preview" [removable]="true" *ngIf="hasProfile()" (removed)="onRemove()">
|
||||
<ngx-dropzone-preview class="file-preview" [removable]="true" *ngIf="hasBlueprint()" (removed)="onRemove()">
|
||||
<ngx-dropzone-label class="file-label">{{ selectedFileName }}</ngx-dropzone-label>
|
||||
</ngx-dropzone-preview>
|
||||
</ngx-dropzone>
|
||||
|
@ -20,22 +20,22 @@
|
|||
<div class="col-12 d-flex justify-content-center attach-btn">
|
||||
<button mat-button type="button" class="col-auto attach-file" (click)="imgFileInput.click()">
|
||||
<mat-icon class="mr-2">input</mat-icon>
|
||||
<span *ngIf="!hasProfile()">{{'GENERAL.START-NEW-DMP-DIALOG.UPLOAD-FILE' | translate}}</span>
|
||||
<span *ngIf="hasProfile()">{{'GENERAL.START-NEW-DMP-DIALOG.REPLACE-FILE' | translate}}</span>
|
||||
<span *ngIf="!hasBlueprint()">{{'GENERAL.START-NEW-DMP-DIALOG.UPLOAD-FILE' | translate}}</span>
|
||||
<span *ngIf="hasBlueprint()">{{'GENERAL.START-NEW-DMP-DIALOG.REPLACE-FILE' | translate}}</span>
|
||||
</button>
|
||||
<input class="hidden" type="file" #imgFileInput (change)="selectXML($event)" accept="text/xml" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<mat-form-field class="col-12">
|
||||
<input matInput placeholder="{{'DMP-PROFILE-LISTING.UPLOAD.UPLOAD-XML-NAME'| translate}}" name="datasetProfileName" [(ngModel)]="data.name">
|
||||
<input matInput placeholder="{{'DMP-BLUEPRINT-LISTING.UPLOAD.UPLOAD-XML-NAME'| translate}}" name="datasetBlueprintName" [(ngModel)]="data.name">
|
||||
</mat-form-field>
|
||||
<div class="col-auto">
|
||||
<button mat-button type="button" class="cancel-btn" (click)="cancel()">{{ data.cancelButton }}</button>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<div class="col-auto">
|
||||
<button mat-button color="primary" class="next-btn" type="button" (click)="confirm()" [disabled]="!hasProfile()">{{ data.confirmButton }}</button>
|
||||
<button mat-button color="primary" class="next-btn" type="button" (click)="confirm()" [disabled]="!hasBlueprint()">{{ data.confirmButton }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue