no message

This commit is contained in:
Ioannis Kalyvas 2018-07-11 16:47:36 +03:00
parent efb7af10b5
commit 78b91ee3e0
144 changed files with 5181 additions and 2043 deletions

8
.env
View File

@ -1,6 +1,6 @@
TAG=6.2.1
ENV=dev
TAG=6.3.0
ENV=prod
PROFILE=production
AOT=no-aot
ELASTIC_VERSION=6.2.1
AOT=aot
ELASTIC_VERSION=6.3.0
ELASTIC_PASSWORD=changeme

2
.gitignore vendored
View File

@ -25,3 +25,5 @@ dmp-backend/web/src/main/ui-resources/static/
dmp-backend/data/target/data-1.0-SNAPSHOT.jar
dmp-backend/data/target/
dmp-backend/queryable/target/
dmp-backend/elastic/target/
dmp-backend/queryengine/target/

View File

@ -1,3 +1,3 @@
TAG=6.2.1
ELASTIC_VERSION=6.2.1
TAG=6.3.1
ELASTIC_VERSION=6.3.1
ELASTIC_PASSWORD=changeme

View File

@ -100,7 +100,72 @@ services:
networks: ['stack']
depends_on: ['kibana']
#volumes:
##########################DOCSBOX######################################################################
web:
restart: always
build: ./docsbox-master/docsbox
expose:
- "8000"
links:
- redis:redis
volumes:
- docsbox:/home/docsbox
- media:/home/docsbox/media
command: gunicorn -b :8000 docsbox:app
networks: ['stack']
rqworker:
restart: always
build: ./docsbox-master/docsbox
links:
- redis:redis
volumes:
- web
command: rq worker -c docsbox.settings
networks: ['stack']
rqscheduler:
restart: always
build: ./docsbox-master/docsbox
links:
- redis:redis
volumes:
- web
command: rqscheduler -H redis -p 6379 -d 0
networks: ['stack']
nginx:
restart: always
build: ./docsbox-master/nginx/
ports:
- "81:80"
volumes:
- web
links:
- web:web
networks: ['stack']
redis:
restart: always
image: redis:latest
expose:
- "6379"
volumes:
- redisdata:/data
networks: ['stack']
##########################SETTIGNS######################################################################
volumes:
#esdata:
# driver: local
#driver: local
redisdata:
driver: local
docsbox:
driver: local
media:
driver: local
networks: {stack: {}}

View File

@ -1,5 +1,11 @@
FROM openjdk:8-jdk-alpine
RUN apk add --update \
curl \
&& rm -rf /var/cache/apk/*
VOLUME /tmp
ARG PROFILE=dev
ARG PROFILE=production
ENV PROF $PROFILE
ADD web/src/main/resources/ProjectConfiguration.xml /tmp/ProjectConfiguration.xml
ADD web/src/main/resources/ExternalUrls.xml /tmp/ExternalUrls.xml
ADD web/target/web-1.0-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=${PROFILE}","-jar","/app.jar"]
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom" ,"-Dspring.profiles.active=${PROF}","-jar","/app.jar"]

View File

@ -21,5 +21,10 @@
<artifactId>queryable</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>eu.eudat</groupId>
<artifactId>elastic</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -1,6 +1,7 @@
package eu.eudat.data.dao.criteria;
import eu.eudat.data.entities.Dataset;
import eu.eudat.elastic.entities.Tag;
import java.util.Date;
import java.util.List;
@ -12,8 +13,10 @@ public class DatasetCriteria extends Criteria<Dataset> {
private Date periodStart;
private Date periodEnd;
private List<UUID> dmpIds;
private List<Tag> tags;
private boolean allVersions;
public boolean getAllVersions() {
return allVersions;
}
@ -53,4 +56,12 @@ public class DatasetCriteria extends Criteria<Dataset> {
public void setDmpIds(List<UUID> dmpIds) {
this.dmpIds = dmpIds;
}
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
}

View File

@ -14,15 +14,23 @@ import java.util.stream.Collectors;
@NamedEntityGraphs({
@NamedEntityGraph(
name = "datasetListingModel",
attributeNodes = {@NamedAttributeNode("services"), @NamedAttributeNode("datasetDataRepositories"), @NamedAttributeNode("datasetExternalDatasets"), @NamedAttributeNode("registries"),
attributeNodes = {@NamedAttributeNode("services"), @NamedAttributeNode(value = "datasetDataRepositories", subgraph = "datasetDataRepositories"), @NamedAttributeNode("datasetExternalDatasets"), @NamedAttributeNode("registries"),
@NamedAttributeNode(value = "dmp", subgraph = "dmp"), @NamedAttributeNode("profile"), @NamedAttributeNode("creator")},
subgraphs = @NamedSubgraph(name = "dmp", attributeNodes = {@NamedAttributeNode("creator"), @NamedAttributeNode("users")})),
subgraphs = {
@NamedSubgraph(name = "dmp", attributeNodes = {@NamedAttributeNode("creator"), @NamedAttributeNode("users")}),
@NamedSubgraph(name = "datasetDataRepositories", attributeNodes = {@NamedAttributeNode("dataRepository")})
}),
@NamedEntityGraph(
name = "datasetWizardModel",
attributeNodes = {@NamedAttributeNode("services"), @NamedAttributeNode("datasetDataRepositories"), @NamedAttributeNode("datasetExternalDatasets"), @NamedAttributeNode("registries"),
@NamedAttributeNode("dmp"), @NamedAttributeNode("profile"), @NamedAttributeNode("creator")}),
@NamedEntityGraph(
name = "datasetRecentActivity",
attributeNodes = {@NamedAttributeNode(value = "dmp", subgraph = "dmp")},
subgraphs = @NamedSubgraph(name = "dmp", attributeNodes = {@NamedAttributeNode("users")})),
@NamedEntityGraph(
name = "datasetDataRepositories",
attributeNodes = {@NamedAttributeNode(value = "dmp", subgraph = "dmp"), @NamedAttributeNode("creator")},
subgraphs = @NamedSubgraph(name = "dmp", attributeNodes = {@NamedAttributeNode("creator"), @NamedAttributeNode("users")}))
})
@ -291,10 +299,10 @@ public class Dataset implements DataEntity<Dataset, UUID> {
@Override
public void update(Dataset entity) {
this.setRegistries(entity.getRegistries());
if(this.getDatasetDataRepositories()==null) this.setDatasetDataRepositories(new HashSet<>());
if(!this.getDatasetDataRepositories().containsAll(entity.getDatasetDataRepositories())){
if (this.getDatasetDataRepositories() == null) this.setDatasetDataRepositories(new HashSet<>());
if (!this.getDatasetDataRepositories().containsAll(entity.getDatasetDataRepositories())) {
this.getDatasetDataRepositories().removeAll(this.getDatasetDataRepositories());
this.getDatasetDataRepositories().addAll(entity.getDatasetDataRepositories().stream().map(item->{
this.getDatasetDataRepositories().addAll(entity.getDatasetDataRepositories().stream().map(item -> {
item.setDataset(this);
return item;
}).collect(Collectors.toList()));
@ -302,8 +310,8 @@ public class Dataset implements DataEntity<Dataset, UUID> {
this.setDescription(entity.getDescription());
this.setLabel(entity.getLabel());
this.setProperties(entity.getProperties());
if(this.getDatasetExternalDatasets()==null) this.setDatasetExternalDatasets(new HashSet<>());
if(!this.getDatasetExternalDatasets().containsAll(entity.getDatasetExternalDatasets())) {
if (this.getDatasetExternalDatasets() == null) this.setDatasetExternalDatasets(new HashSet<>());
if (!this.getDatasetExternalDatasets().containsAll(entity.getDatasetExternalDatasets())) {
this.getDatasetExternalDatasets().removeAll(this.getDatasetExternalDatasets());
this.getDatasetExternalDatasets().addAll(entity.getDatasetExternalDatasets().stream().map(item -> {
item.setDataset(this);

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dmp-backend</artifactId>
<groupId>eu.eudat</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>elastic</artifactId>
</project>

View File

@ -0,0 +1,7 @@
package eu.eudat.elastic.criteria;
/**
* Created by ikalyvas on 7/5/2018.
*/
public abstract class Criteria {
}

View File

@ -0,0 +1,20 @@
package eu.eudat.elastic.criteria;
import eu.eudat.elastic.entities.Tag;
import java.util.List;
/**
* Created by ikalyvas on 7/5/2018.
*/
public class DatasetCriteria extends Criteria {
public List<Tag> tags;
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
}

View File

@ -0,0 +1,7 @@
package eu.eudat.elastic.criteria;
/**
* Created by ikalyvas on 7/5/2018.
*/
public class TagCriteria extends Criteria {
}

View File

@ -0,0 +1,60 @@
package eu.eudat.elastic.entities;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Created by ikalyvas on 7/5/2018.
*/
public class Dataset implements ElasticEntity<Dataset> {
private String id;
private List<Tag> tags = new LinkedList<>();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
@Override
public XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException {
builder.startObject();
builder.field("id", this.id);
builder.startArray("tags");
this.tags.forEach(x -> {
try {
x.toElasticEntity(builder);
} catch (IOException e) {
e.printStackTrace();
}
});
builder.endArray();
builder.endObject();
return builder;
}
@Override
public Dataset fromElasticEntity(Map<String, Object> fields) {
if (fields != null) {
this.id = (String) fields.get("id");
this.tags = ((List<Tag>) fields.get("tags"));
}
return this;
}
}

View File

@ -0,0 +1,15 @@
package eu.eudat.elastic.entities;
import org.elasticsearch.common.document.DocumentField;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.Map;
/**
* Created by ikalyvas on 7/5/2018.
*/
public interface ElasticEntity<T> {
XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException;
T fromElasticEntity(Map<String, Object> fields);
}

View File

@ -0,0 +1,45 @@
package eu.eudat.elastic.entities;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.Map;
/**
* Created by ikalyvas on 7/5/2018.
*/
public class Tag implements ElasticEntity {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException {
builder.startObject();
builder.field("id", this.id);
builder.field("name", this.name);
builder.endObject();
return builder;
}
@Override
public Object fromElasticEntity(Map fields) {
return null;
}
}

View File

@ -0,0 +1,72 @@
package eu.eudat.elastic.repository;
import eu.eudat.elastic.criteria.DatasetCriteria;
import eu.eudat.elastic.entities.Dataset;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
/**
* Created by ikalyvas on 7/5/2018.
*/
@Service("datasetRepository")
public class DatasetRepository extends ElasticRepository<Dataset, DatasetCriteria> {
@Autowired
public DatasetRepository(RestHighLevelClient client) {
super(client);
}
@Override
public Dataset createOrUpdate(Dataset entity) throws IOException {
XContentBuilder builder = XContentFactory.jsonBuilder();
IndexRequest request = new IndexRequest("datasets", "doc", entity.getId()).source(entity.toElasticEntity(builder));
this.getClient().index(request);
return entity;
}
@Override
public Dataset findDocument(String id) throws IOException {
GetRequest request = new GetRequest("datasets","doc",id);
GetResponse response = this.getClient().get(request);
return new Dataset().fromElasticEntity(response.getSourceAsMap());
}
@Override
public List<Dataset> query(DatasetCriteria criteria) throws ExecutionException, InterruptedException, IOException {
SearchRequest searchRequest = new SearchRequest();
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.should(QueryBuilders.termsQuery("tags.name.keyword", criteria.getTags().stream().map(x -> x.getName()).collect(Collectors.toList())));
searchSourceBuilder.query(boolQuery);
searchRequest.source(searchSourceBuilder);
SearchResponse response = this.getClient().search(searchRequest);
return Arrays.stream(response.getHits().getHits()).map(x -> this.transformFromString(x.getSourceAsString(), Dataset.class)).collect(Collectors.toList());
}
@Override
public boolean exists() throws IOException {
GetIndexRequest request = new GetIndexRequest();
request.indices("datasets");
return this.getClient().indices().exists(request);
}
}

View File

@ -0,0 +1,36 @@
package eu.eudat.elastic.repository;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.elastic.criteria.Criteria;
import eu.eudat.elastic.entities.ElasticEntity;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import java.io.IOException;
/**
* Created by ikalyvas on 7/5/2018.
*/
public abstract class ElasticRepository<T extends ElasticEntity,C extends Criteria> implements Repository<T,C> {
private RestHighLevelClient client;
public RestHighLevelClient getClient() {
return client;
}
public ElasticRepository(RestHighLevelClient client) {
this.client = client;
}
public <T> T transformFromString(String value, Class<T> tClass) {
ObjectMapper mapper = new ObjectMapper();
T item = null;
try {
item = mapper.readValue(value, tClass);
} catch (IOException e) {
e.printStackTrace();
}
return item;
}
}

View File

@ -0,0 +1,22 @@
package eu.eudat.elastic.repository;
import eu.eudat.elastic.criteria.Criteria;
import eu.eudat.elastic.entities.ElasticEntity;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* Created by ikalyvas on 7/5/2018.
*/
public interface Repository<ET extends ElasticEntity, C extends Criteria> {
ET createOrUpdate(ET entity) throws IOException;
ET findDocument(String id) throws IOException;
List<ET> query(C criteria) throws ExecutionException, InterruptedException, IOException;
boolean exists() throws IOException;
}

View File

@ -18,7 +18,8 @@
<module>web</module>
<module>data</module>
<module>logging</module>
<module>queryengine</module>
<module>elastic</module>
</modules>
<properties>
@ -65,6 +66,19 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.3.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.3.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
@ -172,6 +186,11 @@
<artifactId>hibernate-jpamodelgen</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.3.0</version>
</dependency>
</dependencies>
@ -188,7 +207,7 @@
<profile>
<id>production</id>
<properties>
<packaging.type>war</packaging.type>
<packaging.type>jar</packaging.type>
</properties>
<dependencies>
<dependency>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>dmp-backend</artifactId>
<groupId>eu.eudat</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>query-engine</artifactId>
<dependencies>
<dependency>
<groupId>eu.eudat</groupId>
<artifactId>data</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,14 @@
import eu.eudat.data.entities.DataRepository;
import eu.eudat.query.engine.builder.QueryBuilder;
import eu.eudat.query.engine.builder.QueryBuilderImpl;
/**
* Created by ikalyvas on 7/5/2018.
*/
public class Main {
public void Test(){
QueryBuilder<DataRepository> queryBuilder = new QueryBuilderImpl<>();
queryBuilder.where((entity, comparisonExpression) -> comparisonExpression.field("id").greaterThan(5));
//queryBuilder.and(((entity, expression) -> expression.field("id").greaterThan(4)),((entity, expression) -> expression.field("id").greaterThan(5)));
}
}

View File

@ -0,0 +1,16 @@
package eu.eudat.query.engine.builder;
import eu.eudat.query.engine.expressions.Expression;
import eu.eudat.query.engine.predicates.AndPredicate;
import eu.eudat.query.engine.predicates.ComparisonPredicate;
/**
* Created by ikalyvas on 7/5/2018.
*/
public interface QueryBuilder<T> {
Expression where(ComparisonPredicate<T> wherePredicate);
Expression and(AndPredicate<T> andPredicate);
}

View File

@ -0,0 +1,22 @@
package eu.eudat.query.engine.builder;
import eu.eudat.query.engine.expressions.Expression;
import eu.eudat.query.engine.predicates.AndPredicate;
import eu.eudat.query.engine.predicates.ComparisonPredicate;
/**
* Created by ikalyvas on 7/5/2018.
*/
public class QueryBuilderImpl<T> implements QueryBuilder<T> {
@Override
public Expression where(ComparisonPredicate wherePredicate) {
return null;
}
@Override
public Expression and(AndPredicate<T> andPredicate) {
return null;
}
}

View File

@ -0,0 +1,17 @@
package eu.eudat.query.engine.expressions;
/**
* Created by ikalyvas on 7/5/2018.
*/
public abstract class AbstractFieldExpression<T extends AbstractFieldExpression<T>> {
private String field;
protected String getField() {
return field;
}
public T field(String field) {
this.field = field;
return (T)this;
}
}

View File

@ -0,0 +1,43 @@
package eu.eudat.query.engine.expressions;
import eu.eudat.query.engine.types.expression.comparison.ComparisonExpressionType;
/**
* Created by ikalyvas on 7/5/2018.
*/
public class ComparisonExpression extends AbstractFieldExpression<ComparisonExpression> implements Expression {
private ComparisonExpressionType type;
private Object value;
public <T> Expression greaterThan(T value){
this.value = value;
this.type = ComparisonExpressionType.GREATER_THAN;
return this;
}
public <T> Expression greaterThanOrEqual(T value){
this.value = value;
this.type = ComparisonExpressionType.GREATER_OR_EQUAL_THAN;
return this;
}
public <T> Expression equal(T value){
this.value = value;
this.type = ComparisonExpressionType.EQUAL;
return this;
}
public <T> Expression lessThan(T value){
this.value = value;
this.type = ComparisonExpressionType.LESS_THAN;
return this;
}
public <T> Expression lessOrEqualThan(T value){
this.value = value;
this.type = ComparisonExpressionType.LESS_OR_EQUAL_THAN;
return this;
}
}

View File

@ -0,0 +1,7 @@
package eu.eudat.query.engine.expressions;
/**
* Created by ikalyvas on 7/5/2018.
*/
public interface Expression {
}

View File

@ -0,0 +1,11 @@
package eu.eudat.query.engine.predicates;
import eu.eudat.query.engine.expressions.ComparisonExpression;
import eu.eudat.query.engine.expressions.Expression;
/**
* Created by ikalyvas on 7/5/2018.
*/
public interface AndPredicate<T> {
<E extends Expression> Expression and(ComparisonPredicate<T>... predicates);
}

View File

@ -0,0 +1,9 @@
package eu.eudat.query.engine.predicates;
import eu.eudat.query.engine.expressions.ComparisonExpression;
/**
* Created by ikalyvas on 7/5/2018.
*/
public interface ComparisonPredicate<T> extends Predicate<T, ComparisonExpression> {
}

View File

@ -0,0 +1,11 @@
package eu.eudat.query.engine.predicates;
import eu.eudat.query.engine.expressions.Expression;
/**
* Created by ikalyvas on 7/5/2018.
*/
public interface Predicate<T,E extends Expression> {
Expression where(T entity, E expression);
}

View File

@ -0,0 +1,8 @@
package eu.eudat.query.engine.types.expression.comparison;
/**
* Created by ikalyvas on 7/5/2018.
*/
public enum ComparisonExpressionType {
EQUAL, GREATER_THAN, GREATER_OR_EQUAL_THAN, LESS_THAN, LESS_OR_EQUAL_THAN
}

View File

@ -31,6 +31,15 @@
<artifactId>queryable</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>eu.eudat</groupId>
<artifactId>elastic</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>

View File

@ -32,6 +32,7 @@ public class ResponsesCache {
caches.add(new GuavaCache("organisations", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build()));
caches.add(new GuavaCache("registries", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build()));
caches.add(new GuavaCache("services", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build()));
caches.add(new GuavaCache("tags", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build()));
caches.add(new GuavaCache("researchers", CacheBuilder.newBuilder().expireAfterAccess(HOW_MANY, TIME_UNIT).build()));
simpleCacheManager.setCaches(caches);
System.out.println("OK");

View File

@ -0,0 +1,39 @@
package eu.eudat.configurations;
import org.apache.http.HttpHost;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import java.net.InetAddress;
/**
* Created by ikalyvas on 7/5/2018.
*/
@Configuration
public class ElasticSearchConfiguration {
private Environment environment;
@Autowired
public ElasticSearchConfiguration(Environment environment) {
this.environment = environment;
}
@Bean
public RestHighLevelClient client() throws Exception {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost(this.environment.getProperty("elasticsearch.host"),
Integer.parseInt(this.environment.getProperty("elasticsearch.port")), "http")));
return client;
}
}

View File

@ -14,6 +14,7 @@ import javax.xml.bind.Unmarshaller;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.List;
@ -47,7 +48,7 @@ public class DynamicProjectConfigurationProdImpl implements DynamicProjectConfig
JAXBContext jaxbContext = JAXBContext.newInstance(Configuration.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
is = new URL("file:///" + System.getenv("CATALINA_HOME") + fileUrl).openStream();
is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream();
this.configuration = (Configuration) jaxbUnmarshaller.unmarshal(is);
} catch (Exception ex) {
ex.printStackTrace();

View File

@ -74,7 +74,8 @@ public class DatasetWizardController extends BaseController {
public @ResponseBody
ResponseEntity<ResponseItem<DatasetWizardModel>> getSingle(@PathVariable String id, Principal principal) {
try {
DatasetWizardModel dataset = new DatasetManager().getSingle(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), id);
DatasetWizardModel dataset = new DatasetManager().getSingle(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(),this.getApiContext().getOperationsContext().getDatasetRepository()
,id);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<DatasetWizardModel>().status(ApiMessageCode.NO_MESSAGE).payload(dataset));
} catch (Exception ex) {
ex.printStackTrace();

View File

@ -0,0 +1,67 @@
package eu.eudat.controllers;
import eu.eudat.elastic.criteria.TagCriteria;
import eu.eudat.elastic.entities.Dataset;
import eu.eudat.elastic.entities.Tag;
import eu.eudat.elastic.repository.Repository;
import eu.eudat.logic.proxy.config.exceptions.HugeResultSet;
import eu.eudat.logic.proxy.config.exceptions.NoURLFound;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.models.data.external.TagExternalSourcesModel;
import eu.eudat.models.data.helpers.responses.ResponseItem;
import eu.eudat.types.ApiMessageCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* Created by ikalyvas on 7/5/2018.
*/
@RestController
@CrossOrigin
@RequestMapping(value = {"/api"})
public class TagController extends BaseController{
private Repository<Dataset,TagCriteria> datasetRepository;
@Autowired
public TagController(ApiContext apiContext, Repository tagRepository) {
super(apiContext);
this.datasetRepository = tagRepository;
}
@Transactional
@RequestMapping(method = RequestMethod.POST, value = {"/tag/create"}, consumes = "application/json", produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<Dataset>> create(@RequestBody Dataset dataset) {
try {
Dataset tagEntity = this.datasetRepository.createOrUpdate(dataset);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Dataset>().payload(dataset).status(ApiMessageCode.SUCCESS_MESSAGE));
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem<Dataset>().status(ApiMessageCode.SUCCESS_MESSAGE).message(e.getMessage()));
}
}
@RequestMapping(method = RequestMethod.GET, value = {"/external/tags"}, produces = "application/json")
public @ResponseBody
ResponseEntity<ResponseItem<TagExternalSourcesModel>> listExternalTagModel(
@RequestParam(value = "query", required = false) String query,@RequestParam(value = "type", required = false) String type) {
try {
List<Map<String, String>> remoteRepos = this.getApiContext().getOperationsContext().getRemoteFetcher().getTags(query,type);
TagExternalSourcesModel researchersExternalSourcesModel = new TagExternalSourcesModel().fromExternalItem(remoteRepos);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<TagExternalSourcesModel>().payload(researchersExternalSourcesModel).status(ApiMessageCode.NO_MESSAGE));
} catch (NoURLFound ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem<TagExternalSourcesModel>().status(ApiMessageCode.ERROR_MESSAGE).message("External Url Not Found"));
} catch (HugeResultSet ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem<TagExternalSourcesModel>().status(ApiMessageCode.ERROR_MESSAGE).message("Huge Result Set"));
} catch (Exception ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem<TagExternalSourcesModel>().status(ApiMessageCode.ERROR_MESSAGE).message(ex.getMessage()));
}
}
}

View File

@ -20,6 +20,8 @@ public class CommonsManager {
.map(item-> new ExternalSourcesConfiguration.ExternalSourcesUrlModel(item.getKey(),item.getLabel())).collect(Collectors.toList()));
externalSourcesConfiguration.setServices(configLoader.getExternalUrls().getServices().getUrls().stream()
.map(item-> new ExternalSourcesConfiguration.ExternalSourcesUrlModel(item.getKey(),item.getLabel())).collect(Collectors.toList()));
externalSourcesConfiguration.setTags(configLoader.getExternalUrls().getTags().getUrls().stream()
.map(item-> new ExternalSourcesConfiguration.ExternalSourcesUrlModel(item.getKey(),item.getLabel())).collect(Collectors.toList()));
return externalSourcesConfiguration;
}
}

View File

@ -1,25 +1,27 @@
package eu.eudat.logic.managers;
import eu.eudat.logic.builders.entity.UserInfoBuilder;
import eu.eudat.data.dao.entities.*;
import eu.eudat.data.entities.*;
import eu.eudat.logic.utilities.documents.helpers.FileEnvelope;
import eu.eudat.logic.utilities.documents.word.WordBuilder;
import eu.eudat.logic.utilities.documents.xml.ExportXmlBuilder;
import eu.eudat.models.HintedModelFactory;
import eu.eudat.data.dao.criteria.DataRepositoryCriteria;
import eu.eudat.data.dao.criteria.ExternalDatasetCriteria;
import eu.eudat.data.dao.criteria.RegistryCriteria;
import eu.eudat.data.dao.criteria.ServiceCriteria;
import eu.eudat.data.dao.entities.*;
import eu.eudat.data.entities.*;
import eu.eudat.data.query.items.table.dataset.DatasetTableRequest;
import eu.eudat.elastic.criteria.DatasetCriteria;
import eu.eudat.elastic.repository.DatasetRepository;
import eu.eudat.logic.builders.entity.UserInfoBuilder;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.forms.VisibilityRuleService;
import eu.eudat.logic.utilities.documents.helpers.FileEnvelope;
import eu.eudat.logic.utilities.documents.word.WordBuilder;
import eu.eudat.logic.utilities.documents.xml.ExportXmlBuilder;
import eu.eudat.models.HintedModelFactory;
import eu.eudat.models.data.datasetwizard.DatasetWizardModel;
import eu.eudat.models.data.helpers.common.DataTableData;
import eu.eudat.models.data.listingmodels.DatasetListingModel;
import eu.eudat.models.data.security.Principal;
import eu.eudat.models.data.user.composite.PagedDatasetProfile;
import eu.eudat.queryable.QueryableList;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.forms.VisibilityRuleService;
import org.apache.commons.io.IOUtils;
import org.json.JSONObject;
import org.springframework.core.env.Environment;
@ -35,6 +37,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -42,8 +45,19 @@ import java.util.zip.ZipInputStream;
public class DatasetManager {
public DataTableData<DatasetListingModel> getPaged(ApiContext apiContext, DatasetTableRequest datasetTableRequest, Principal principal) throws Exception {
DatasetCriteria datasetCriteria = new DatasetCriteria();
datasetCriteria.setTags(datasetTableRequest.getCriteria().getTags());
List<eu.eudat.elastic.entities.Dataset> datasets = apiContext.getOperationsContext().getDatasetRepository().exists() ?
apiContext.getOperationsContext().getDatasetRepository().query(datasetCriteria) : new LinkedList<>();
UserInfo userInfo = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build();
QueryableList<eu.eudat.data.entities.Dataset> items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getWithCriteria(datasetTableRequest.getCriteria()).withHint(HintedModelFactory.getHint(DatasetListingModel.class));
if (datasetTableRequest.getCriteria().getTags() != null && !datasetTableRequest.getCriteria().getTags().isEmpty()) {
if (!datasets.isEmpty())
items.where((builder, root) -> root.get("id").in(datasets.stream().map(x -> UUID.fromString(x.getId())).collect(Collectors.toList())));
else
items.where((builder, root) -> root.get("id").in(new UUID[]{UUID.randomUUID()}));
}
QueryableList<eu.eudat.data.entities.Dataset> authItems = apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getAuthenticated(items, userInfo);
QueryableList<eu.eudat.data.entities.Dataset> pagedItems = PaginationManager.applyPaging(authItems, datasetTableRequest);
DataTableData<DatasetListingModel> dataTable = new DataTableData<DatasetListingModel>();
@ -62,11 +76,14 @@ public class DatasetManager {
return dataTable;
}
public DatasetWizardModel getSingle(DatasetDao datatasetRepository, String id) throws InstantiationException, IllegalAccessException {
public DatasetWizardModel getSingle(DatasetDao datatasetRepository, DatasetRepository elasticDatasetRepository, String id) throws InstantiationException, IllegalAccessException, IOException {
DatasetWizardModel dataset = new DatasetWizardModel();
eu.eudat.data.entities.Dataset datasetEntity = datatasetRepository.find(UUID.fromString(id), HintedModelFactory.getHint(DatasetWizardModel.class));
eu.eudat.elastic.entities.Dataset datasetElastic = elasticDatasetRepository.exists() ?
elasticDatasetRepository.findDocument(id) : new eu.eudat.elastic.entities.Dataset();
dataset.setDatasetProfileDefinition(getPagedProfile(dataset, datasetEntity));
dataset.fromDataModel(datasetEntity);
dataset.setTags(datasetElastic.getTags());
return dataset;
}
@ -75,7 +92,7 @@ public class DatasetManager {
datasetprofile.setStatus(dataset.getStatus());
if (datasetEntity.getProperties() != null) {
JSONObject jobject = new JSONObject(datasetEntity.getProperties());
Map<String, Object> properties = (Map<String, Object>) jobject.toMap();
Map<String, Object> properties = jobject.toMap();
datasetprofile.fromJsonObject(properties);
}
PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile();
@ -180,15 +197,16 @@ public class DatasetManager {
return newFile;
}
public static eu.eudat.data.entities.Dataset createOrUpdate(ApiContext apiContext, DatasetWizardModel profile, Principal principal) throws Exception {
eu.eudat.data.entities.Dataset dataset = profile.toDataModel();
propertiesModelToString(profile, dataset);
public static eu.eudat.data.entities.Dataset createOrUpdate(ApiContext apiContext, DatasetWizardModel datasetWizardModel, Principal principal) throws Exception {
eu.eudat.data.entities.Dataset dataset = datasetWizardModel.toDataModel();
propertiesModelToString(datasetWizardModel, dataset);
UserInfo userInfo = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build();
dataset.setCreator(userInfo);
updateTags(apiContext.getOperationsContext().getDatasetRepository(), datasetWizardModel);
createRegistriesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getRegistryDao(), dataset);
createDataRepositoriesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDataRepositoryDao(), dataset);
createServicesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDatasetServiceDao(),apiContext.getOperationsContext().getDatabaseRepository().getServiceDao(), dataset);
createExternalDatasetsIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDatasetExternalDatasetDao(),apiContext.getOperationsContext().getDatabaseRepository().getExternalDatasetDao(), dataset);
createServicesIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDatasetServiceDao(), apiContext.getOperationsContext().getDatabaseRepository().getServiceDao(), dataset);
createExternalDatasetsIfTheyDontExist(apiContext.getOperationsContext().getDatabaseRepository().getDatasetExternalDatasetDao(), apiContext.getOperationsContext().getDatabaseRepository().getExternalDatasetDao(), dataset);
return apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().createOrUpdate(dataset);
}
@ -200,6 +218,15 @@ public class DatasetManager {
dataset.setProperties(jobject.toString());
}
private static void updateTags(DatasetRepository datasetRepository, DatasetWizardModel datasetWizardModel) throws IOException {
if (datasetWizardModel.getTags() != null && !datasetWizardModel.getTags().isEmpty()) {
eu.eudat.elastic.entities.Dataset dataset = new eu.eudat.elastic.entities.Dataset();
dataset.setId(datasetWizardModel.getId().toString());
dataset.setTags(datasetWizardModel.getTags());
datasetRepository.createOrUpdate(dataset);
}
}
private static void createRegistriesIfTheyDontExist(RegistryDao registryDao, eu.eudat.data.entities.Dataset dataset) {
if (dataset.getRegistries() != null && !dataset.getRegistries().isEmpty()) {
@ -226,8 +253,7 @@ public class DatasetManager {
datasetDataRepository.getDataRepository().setId(entries.get(0).getId());
datasetDataRepository.setDataset(dataset);
dataset.getDatasetDataRepositories().add(datasetDataRepository);
}
else {
} else {
DataRepository dataRepository = dataRepositoryDao.createOrUpdate(datasetDataRepository.getDataRepository());
datasetDataRepository.setDataRepository(dataRepository);
dataset.getDatasetDataRepositories().add(datasetDataRepository);
@ -236,7 +262,7 @@ public class DatasetManager {
}
}
private static void createServicesIfTheyDontExist(DatasetServiceDao datasetServiceDao,ServiceDao serviceDao, eu.eudat.data.entities.Dataset dataset) {
private static void createServicesIfTheyDontExist(DatasetServiceDao datasetServiceDao, ServiceDao serviceDao, eu.eudat.data.entities.Dataset dataset) {
Set<DatasetService> services = dataset.getServices();
dataset.setServices(new HashSet<>());
if (services != null && !services.isEmpty()) {
@ -244,21 +270,20 @@ public class DatasetManager {
ServiceCriteria criteria = new ServiceCriteria();
criteria.setLike(datasetService.getService().getLabel());
List<eu.eudat.data.entities.Service> entries = serviceDao.getWithCriteria(criteria).toList();
if (entries != null && !entries.isEmpty()){
if (entries != null && !entries.isEmpty()) {
datasetService.getService().setId(entries.get(0).getId());
datasetService.setDataset(dataset);
dataset.getServices().add(datasetService);
}
else {
} else {
Service service = serviceDao.createOrUpdate(datasetService.getService());
datasetService.setService(service );
datasetService.setService(service);
dataset.getServices().add(datasetService);
}
}
}
}
private static void createExternalDatasetsIfTheyDontExist(DatasetExternalDatasetDao datasetExternalDatasetDao,ExternalDatasetDao externalDatasetDao, eu.eudat.data.entities.Dataset dataset) {
private static void createExternalDatasetsIfTheyDontExist(DatasetExternalDatasetDao datasetExternalDatasetDao, ExternalDatasetDao externalDatasetDao, eu.eudat.data.entities.Dataset dataset) {
Set<DatasetExternalDataset> externalDatasets = dataset.getDatasetExternalDatasets();
dataset.setDatasetExternalDatasets(new HashSet<>());
if (externalDatasets != null && !externalDatasets.isEmpty()) {
@ -270,8 +295,7 @@ public class DatasetManager {
datasetExternalDataset.getExternalDataset().setId(entries.get(0).getId());
datasetExternalDataset.setDataset(dataset);
dataset.getDatasetExternalDatasets().add(datasetExternalDataset);
}
else {
} else {
ExternalDataset externalDataset = externalDatasetDao.createOrUpdate(datasetExternalDataset.getExternalDataset());
datasetExternalDataset.setExternalDataset(externalDataset);
dataset.getDatasetExternalDatasets().add(datasetExternalDataset);

View File

@ -23,6 +23,7 @@ public class ExternalUrls implements Serializable {
ResearcherUrls researchers;
OrganisationUrls organisations;
DatasetUrls datasets;
TagUrls tags;
public RegistryUrls getRegistries() {
@ -59,6 +60,15 @@ public class ExternalUrls implements Serializable {
return researchers;
}
public TagUrls getTags() {
return tags;
}
@XmlElement(name = "tags")
public void setTags(TagUrls tags) {
this.tags = tags;
}
@XmlElement(name = "researchers")
public void setResearchers(ResearcherUrls researchers) {
this.researchers = researchers;

View File

@ -11,6 +11,7 @@ import javax.xml.bind.Unmarshaller;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Paths;
/**
* Created by ikalyvas on 2/9/2018.
@ -34,7 +35,7 @@ public class ProductionConfigLoader implements ConfigLoader {
JAXBContext jaxbContext = JAXBContext.newInstance(ExternalUrls.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
is = new URL("file:///" + System.getenv("CATALINA_HOME") + fileUrl).openStream();
is = new URL(Paths.get(fileUrl).toUri().toURL().toString()).openStream();
externalUrls = (ExternalUrls) jaxbUnmarshaller.unmarshal(is);
} catch (Exception ex) {

View File

@ -0,0 +1,35 @@
package eu.eudat.logic.proxy.config.entities;
import eu.eudat.logic.proxy.config.FetchStrategy;
import eu.eudat.logic.proxy.config.UrlConfiguration;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import java.util.List;
/**
* Created by ikalyvas on 7/9/2018.
*/
public class TagUrls {
List<UrlConfiguration> urls;
FetchStrategy fetchMode;
public List<UrlConfiguration> getUrls() {
return urls;
}
@XmlElementWrapper
@XmlElement(name = "urlConfig")
public void setUrls(List<UrlConfiguration> urls) {
this.urls = urls;
}
public FetchStrategy getFetchMode() {
return fetchMode;
}
@XmlElement(name = "fetchMode")
public void setFetchMode(FetchStrategy fetchMode) {
this.fetchMode = fetchMode;
}
}

View File

@ -85,6 +85,15 @@ public class RemoteFetcher {
return getAll(urlConfigs, fetchStrategy, query);
}
@Cacheable("tags")
public List<Map<String, String>> getTags(String query, String key) throws NoURLFound, HugeResultSet {
List<UrlConfiguration> urlConfigs =
key != null && !key.isEmpty() ? configLoader.getExternalUrls().getTags().getUrls().stream().filter(item -> item.getKey().equals(key)).collect(Collectors.toList())
: configLoader.getExternalUrls().getTags().getUrls();
FetchStrategy fetchStrategy = configLoader.getExternalUrls().getTags().getFetchMode();
return getAll(urlConfigs, fetchStrategy, query);
}
@Cacheable("datasets")
public List<Map<String, String>> getDatasets(String query, String key) throws NoURLFound, HugeResultSet {
List<UrlConfiguration> urlConfigs =

View File

@ -3,6 +3,7 @@ package eu.eudat.logic.services;
import eu.eudat.logic.services.helpers.HelpersService;
import eu.eudat.logic.services.operations.OperationsContext;
import eu.eudat.logic.services.utilities.UtilitiesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -13,6 +14,7 @@ public class ApiContextImpl implements ApiContext {
private HelpersService helpersService;
private UtilitiesService utilitiesService;
@Autowired
public ApiContextImpl(OperationsContext operationsContext, HelpersService helpersService, UtilitiesService utilitiesService) {
this.operationsContext = operationsContext;
this.helpersService = helpersService;

View File

@ -1,5 +1,6 @@
package eu.eudat.logic.services.operations;
import eu.eudat.elastic.repository.DatasetRepository;
import eu.eudat.logic.builders.BuilderFactory;
import eu.eudat.logic.proxy.fetching.RemoteFetcher;
import eu.eudat.logic.services.helpers.FileStorageService;
@ -20,4 +21,5 @@ public interface OperationsContext {
FileStorageService getFileStorageService();
DatasetRepository getDatasetRepository();
}

View File

@ -1,5 +1,6 @@
package eu.eudat.logic.services.operations;
import eu.eudat.elastic.repository.DatasetRepository;
import eu.eudat.logic.builders.BuilderFactory;
import eu.eudat.logic.proxy.fetching.RemoteFetcher;
import eu.eudat.logic.services.helpers.FileStorageService;
@ -18,15 +19,17 @@ public class OperationsContextImpl implements OperationsContext {
private RemoteFetcher remoteFetcher;
private BuilderFactory builderFactory;
private FileStorageService fileStorageService;
private DatasetRepository datasetRepository;
@Autowired
public OperationsContextImpl(DatabaseRepository databaseRepository, ApplicationContext applicationContext, RemoteFetcher remoteFetcher
, BuilderFactory builderFactory, FileStorageService fileStorageService) {
, BuilderFactory builderFactory, FileStorageService fileStorageService,DatasetRepository datasetRepository) {
this.databaseRepository = databaseRepository;
this.applicationContext = applicationContext;
this.remoteFetcher = remoteFetcher;
this.builderFactory = builderFactory;
this.fileStorageService = fileStorageService;
this.datasetRepository = datasetRepository;
}
@Override
@ -53,4 +56,13 @@ public class OperationsContextImpl implements OperationsContext {
public FileStorageService getFileStorageService() {
return fileStorageService;
}
@Override
public DatasetRepository getDatasetRepository() {
return datasetRepository;
}
public void setDatasetRepository(DatasetRepository datasetRepository) {
this.datasetRepository = datasetRepository;
}
}

View File

@ -1,6 +1,7 @@
package eu.eudat.models.data.datasetwizard;
import eu.eudat.data.entities.*;
import eu.eudat.elastic.entities.Tag;
import eu.eudat.models.DataModel;
import eu.eudat.models.data.dataset.DataRepository;
import eu.eudat.models.data.dataset.Registry;
@ -29,6 +30,7 @@ public class DatasetWizardModel implements DataModel<Dataset, DatasetWizardModel
private List<Registry> registries;
private List<Service> services;
private List<DataRepository> dataRepositories;
private List<Tag> tags;
private List<ExternalDatasetListingModel> externalDatasets;
private DatasetProfileListingModel profile;
@ -144,6 +146,14 @@ public class DatasetWizardModel implements DataModel<Dataset, DatasetWizardModel
this.externalDatasets = externalDatasets;
}
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
@Override
public DatasetWizardModel fromDataModel(Dataset entity) {
this.id = entity.getId();

View File

@ -0,0 +1,22 @@
package eu.eudat.models.data.external;
import java.util.List;
import java.util.Map;
/**
* Created by ikalyvas on 7/9/2018.
*/
public class TagExternalSourcesModel extends ExternalListingItem<TagExternalSourcesModel> {
@Override
public TagExternalSourcesModel fromExternalItem(List<Map<String, String>> values) {
for (Map<String, String> item : values) {
ExternalSourcesItemModel model = new ExternalSourcesItemModel();
model.setId(item.get("pid"));
model.setUri(item.get("label"));
model.setName(item.get("name"));
this.add(model);
}
return this;
}
}

View File

@ -37,6 +37,15 @@ public class ExternalSourcesConfiguration {
private List<ExternalSourcesUrlModel> dataRepositories;
private List<ExternalSourcesUrlModel> services;
private List<ExternalSourcesUrlModel> externalDatasets;
private List<ExternalSourcesUrlModel> tags;
public List<ExternalSourcesUrlModel> getTags() {
return tags;
}
public void setTags(List<ExternalSourcesUrlModel> tags) {
this.tags = tags;
}
public List<ExternalSourcesUrlModel> getRegistries() {
return registries;

View File

@ -44,6 +44,45 @@
<fetchMode>FIRST</fetchMode> <!-- EITHER 'FIRST' OR 'ALL' -->
</registries>
<tags>
<urls>
<urlConfig>
<key>cristin</key>
<label>Cristin</label>
<ordinal>1</ordinal>
<url>https://eestore.paas2.uninett.no/api/tags/</url>
<data>
<path>$['data'][*]['attributes']</path>
<fields>
<id>'pid'</id>
<name>'name'</name>
<uri>'uri'</uri>
<description>'description'</description>
</fields>
</data>
<paginationpath>$['meta']['pagination']['page','pages','count']</paginationpath>
</urlConfig>
<urlConfig>
<key>openAire</key>
<label>OpenAIRE</label>
<ordinal>1</ordinal>
<url>https://eestore.paas2.uninett.no/api/tags/</url>
<data>
<path>$['data'][*]['attributes']</path>
<fields>
<id>'pid'</id>
<name>'name'</name>
<uri>'uri'</uri>
<description>'description'</description>
</fields>
</data>
<paginationpath>$['meta']['pagination']['page','pages','count']</paginationpath>
</urlConfig>
</urls>
<fetchMode>FIRST</fetchMode> <!-- EITHER 'FIRST' OR 'ALL' -->
</tags>
<projects>

View File

@ -15,8 +15,8 @@ production.database.password=dmpt00lu$r
##########################/Persistence##########################################
###################Allowed Proxy Service Host ############################
eu.eudat.logic.proxy.allowed.host=https://eestore.paas2.uninett.no
configuration.externalUrls=/classes/ExternalUrls.xml
configuration.dynamicProjectUrl=/classes/ProjectConfiguration.xml
configuration.externalUrls=/tmp/ExternalUrls.xml
configuration.dynamicProjectUrl=/tmp/ProjectConfiguration.xml
#######################################################
########################/Email#############################
@ -59,7 +59,7 @@ b2access.externallogin.redirect_uri=http://dmp.eudat.org:4200/api/oauth/authoriz
b2access.externallogin.clientid=eudatdmptool
b2access.externallogin.clientSecret=A3b*1*92
#################################################################################
pdf.converter.url=http://localhost/
pdf.converter.url=http://localhost:81/
files.storage.temp = temp
files.storage.final = final
#################################################################################
@ -69,4 +69,7 @@ project.configuration.grant.name = Grant
#################################################################################
http-logger.initial-delay = 0
http-logger.delay = 10
http-logger.server-address = http://logstash:31311
http-logger.server-address = http://logstash:31311
#############################Elastic Search######################################
elasticsearch.host = localhost
elasticsearch.port = 9201

View File

@ -1,60 +0,0 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "dmp-frontend"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"styles.scss"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json",
"exclude": "**/node_modules/**"
},
{
"project": "src/tsconfig.spec.json",
"exclude": "**/node_modules/**"
},
{
"project": "e2e/tsconfig.e2e.json",
"exclude": "**/node_modules/**"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "css",
"component": {}
}
}

View File

@ -5,9 +5,11 @@ RUN npm cache clear --force && npm install
COPY ./ /app/
ARG env=dev
ARG aot=--no-aot
RUN ng build --$env --$aot
RUN echo $env
RUN echo $aot
RUN if [ "$env" = "prod" ]; then ng build --$env --$aot; else ng build --$aot; fi
# Stage 1, based on Nginx, to have only the compiled app, ready for production with Nginx
FROM nginx:1.13
COPY --from=angular /app/dist/ /usr/share/nginx/html
COPY ./nginx-custom.conf /etc/nginx/conf.d/default.conf
COPY ./nginx-custom.conf /etc/nginx/conf.d/default.conf

132
dmp-frontend/angular.json Normal file
View File

@ -0,0 +1,132 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"dmp-frontend": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"tsConfig": "src/tsconfig.app.json",
"polyfills": "src/polyfills.ts",
"assets": [
"src/assets",
"src/favicon.ico"
],
"styles": [
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "dmp-frontend:build"
},
"configurations": {
"production": {
"browserTarget": "dmp-frontend:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "dmp-frontend:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"karmaConfig": "./karma.conf.js",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"scripts": [],
"styles": [
"src/styles.scss"
],
"assets": [
"src/assets",
"src/favicon.ico"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"dmp-frontend-e2e": {
"root": "",
"sourceRoot": "e2e",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "./protractor.conf.js",
"devServerTarget": "dmp-frontend:serve"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"e2e/tsconfig.e2e.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "dmp-frontend",
"schematics": {
"@schematics/angular:component": {
"prefix": "app",
"styleext": "css"
},
"@schematics/angular:directive": {
"prefix": "app"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -12,32 +12,33 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^5.2.0",
"@angular/cdk": "^5.2.4",
"@angular/common": "^5.2.0",
"@angular/compiler": "^5.2.0",
"@angular/core": "^5.2.0",
"@angular/flex-layout": "5.0.0-beta.14",
"@angular/forms": "^5.2.0",
"@angular/http": "^5.2.0",
"@angular/material": "^5.2.4",
"@angular/platform-browser": "^5.2.0",
"@angular/platform-browser-dynamic": "^5.2.0",
"@angular/router": "^5.2.0",
"@covalent/core": "1.0.0",
"@angular/animations": "6.0.7",
"@angular/cdk": "6.1.0",
"@angular/common": "6.0.7",
"@angular/compiler": "6.0.7",
"@angular/core": "6.0.7",
"@angular/flex-layout": "6.0.0-beta.16",
"@angular/forms": "6.0.7",
"@angular/http": "6.0.7",
"@angular/material": "6.1.0",
"@angular/platform-browser": "6.0.7",
"@angular/platform-browser-dynamic": "6.0.7",
"@angular/router": "6.0.7",
"@covalent/core": "2.0.0-beta.2",
"@ngx-translate/core": "10.0.1",
"@ngx-translate/http-loader": "3.0.1",
"@swimlane/ngx-datatable": "^11.3.2",
"@swimlane/ngx-datatable": "13.0.1",
"@types/file-saver": "1.3.0",
"core-js": "^2.4.1",
"file-saver": "1.3.3",
"rxjs": "^5.6.0-forward-compat.4",
"zone.js": "^0.8.19"
"rxjs": "^6.2.1",
"rxjs-compat": "^6.1.0",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular/cli": "~1.7.4",
"@angular/compiler-cli": "^5.2.0",
"@angular/language-service": "^5.2.0",
"@angular/cli": "^6.0.8",
"@angular/compiler-cli": "6.0.7",
"@angular/language-service": "6.0.7",
"@types/jasmine": "~2.8.3",
"@types/jasminewd2": "~2.0.2",
"@types/node": "~6.0.60",
@ -52,6 +53,7 @@
"protractor": "^5.3.2",
"ts-node": "~4.1.0",
"tslint": "~5.9.1",
"typescript": "~2.5.3"
"typescript": "2.7.2",
"@angular-devkit/build-angular": "~0.6.8"
}
}

View File

@ -1,4 +1,4 @@
<app-navigation [(sidenavOpen)]="sideNavOpen"></app-navigation>
<app-navigation></app-navigation>
<div class="container-fluid">
<div class="row">

View File

@ -1,6 +1,3 @@
.example-container {
width: 400px;
height: 200px;
margin: 10px;
border: 1px solid #555;
background: rgb(250, 248, 248);
}

View File

@ -38,11 +38,10 @@ import { RecentActivityComponent } from './users/activity/recent-activity.compon
import { LanguageResolverService } from './services/language-resolver/language-resolver.service';
import { LanguageService } from './services/language/language.service';
import { UsersModule } from './users/users.module';
import { HelpContentComponent } from './shared/help-content/help-content.component';
import { HelpContentComponent, AsideHelpContentComponent } from './shared/help-content/help-content.component';
import { AuthGuard } from './shared/guards/auth.guard';
import { UrlUtilities } from './utilities/UrlUtilities';
import { BreadCrumbResolverService } from './services/breadcrumb/breadcrumb-resolver.service';
import { McBreadcrumbsModule } from 'ngx-breadcrumbs';
@NgModule({
declarations: [
@ -52,12 +51,12 @@ import { McBreadcrumbsModule } from 'ngx-breadcrumbs';
RecentActivityComponent,
WelcomepageComponent,
HelpContentComponent,
AsideHelpContentComponent,
B2AccessLoginComponent,
],
imports: [
BrowserModule,
ReactiveFormsModule,
McBreadcrumbsModule.forRoot(),
FormsModule,
HttpModule,
HttpClientModule,

View File

@ -1,45 +1,45 @@
<div>
<div [formGroup]="form">
<div class="row">
<mat-form-field>
<input matInput placeholder='Id' type="text" formControlName="id">
</mat-form-field>
<div>
<div formGroupName="viewStyle">
<mat-form-field>
<mat-select placeholder="View Style" formControlName="renderStyle" (change)="onchangeCombo($event)">
<mat-option value="textarea">textarea</mat-option>
<mat-option value="booleanDecision">booleanDecision</mat-option>
<mat-option value='combobox'>combobox</mat-option>
<mat-option value="checkBox">checkBox</mat-option>
<mat-option value="freetext">freetext</mat-option>
<mat-option value="radiobox">radiobox</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div [formGroup]="form">
<div class="row">
<mat-form-field>
<input matInput placeholder='Id' type="text" formControlName="id">
</mat-form-field>
<div>
<div formGroupName="viewStyle">
<mat-form-field>
<mat-select placeholder="View Style" formControlName="renderStyle" (change)="onchangeCombo()">
<mat-option value="textarea">textarea</mat-option>
<mat-option value="booleanDecision">booleanDecision</mat-option>
<mat-option value='combobox'>combobox</mat-option>
<mat-option value="checkBox">checkBox</mat-option>
<mat-option value="freetext">freetext</mat-option>
<mat-option value="radiobox">radiobox</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="form" [ngSwitch]="form.get('viewStyle').get('renderStyle').value">
<div *ngSwitchCase="'combobox'">
<combobox-component [form]="form" [dataModel]="dataModel"></combobox-component>
</div>
<div *ngSwitchCase="'radiobox'">
<radiobox-component [form]="form" [dataModel]="dataModel"></radiobox-component>
</div>
<div *ngSwitchCase="'freetext'">
<freetext-component [form]="form" [dataModel]="dataModel"></freetext-component>
</div>
<div *ngSwitchCase="'textarea'">
<textarea-component [form]="form" [dataModel]="dataModel"></textarea-component>
</div>
<div *ngSwitchCase="'booleanDecision'">
<booleanDecision-component [form]="form" [dataModel]="dataModel"></booleanDecision-component>
</div>
<div *ngSwitchCase="'checkBox'">
<checkbox-component [form]="form" [dataModel]="dataModel"></checkbox-component>
</div>
</div>
<!-- <div class="row">
</div>
</div>
<div class="form" [ngSwitch]="form.get('viewStyle').get('renderStyle').value">
<div *ngSwitchCase="'combobox'">
<combobox-component [form]="form" [dataModel]="dataModel"></combobox-component>
</div>
<div *ngSwitchCase="'radiobox'">
<radiobox-component [form]="form" [dataModel]="dataModel"></radiobox-component>
</div>
<div *ngSwitchCase="'freetext'">
<freetext-component [form]="form" [dataModel]="dataModel"></freetext-component>
</div>
<div *ngSwitchCase="'textarea'">
<textarea-component [form]="form" [dataModel]="dataModel"></textarea-component>
</div>
<div *ngSwitchCase="'booleanDecision'">
<booleanDecision-component [form]="form" [dataModel]="dataModel"></booleanDecision-component>
</div>
<div *ngSwitchCase="'checkBox'">
<checkbox-component [form]="form" [dataModel]="dataModel"></checkbox-component>
</div>
</div>
<!-- <div class="row">
<div class="form-group col-md-6">
<label>description</label>
<input type="text" class="form-control" formControlName="description">
@ -49,57 +49,57 @@
<input type="text" class="form-control" formControlName="extendedDescription">
</div>
</div> -->
<div class="row">
<div *ngIf="isFieldMultiplicityEnabled" formGroupName="multiplicity">
<div>
<h5>Multiplicity</h5>
<mat-form-field class="full-width">
<input matInput type="number" placeholder="Min" formControlName="min">
</mat-form-field>
<div class="row">
<div *ngIf="isFieldMultiplicityEnabled" formGroupName="multiplicity">
<div>
<h5>Multiplicity</h5>
<mat-form-field class="full-width">
<input matInput type="number" placeholder="Min" formControlName="min">
</mat-form-field>
<mat-form-field class="full-width">
<input matInput type="number" placeholder="Max" formControlName="max">
</mat-form-field>
</div>
</div>
<mat-form-field class="full-width">
<input matInput type="number" placeholder="Ordinal" formControlName="ordinal">
</mat-form-field>
<div formGroupName="defaultValue">
<mat-form-field class="full-width">
<input matInput type="text" placeholder="Default Value" formControlName="value">
</mat-form-field>
</div>
<div class="col-md-5">
<div formArrayName="validations">
<div *ngFor="let validation of form.controls.validations.controls; let i=index">
<mat-form-field>
<mat-select placeholder='Validation' [formControlName]="i">
<mat-option *ngFor="let option of validationsOptions" [value]="option.key">{{option.value}}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<mat-form-field class="full-width">
<input matInput type="number" placeholder="Max" formControlName="max">
</mat-form-field>
</div>
</div>
<mat-form-field class="full-width">
<input matInput type="number" placeholder="Ordinal" formControlName="ordinal">
</mat-form-field>
<div formGroupName="defaultValue">
<mat-form-field class="full-width">
<input matInput type="text" placeholder="Default Value" formControlName="value">
</mat-form-field>
</div>
<div class="col-md-5">
<div formArrayName="validations">
<div *ngFor="let validation of form['controls']['validations']['controls']; let i=index">
<mat-form-field>
<mat-select placeholder='Validation' [formControlName]="i">
<mat-option *ngFor="let option of validationsOptions" [value]="option.key">{{option.value}}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
</div>
<mat-checkbox *ngIf="showMultiplicity" [(ngModel)]="isFieldMultiplicityEnabled" (ngModelChange)="onIsFieldMultiplicityEnabledChange(isFieldMultiplicityEnabled)">Multiplicity</mat-checkbox>
<mat-expansion-panel *ngFor="let rule of dataModel.visible.rules let i=index;">
<mat-expansion-panel-header>
<mat-panel-title>{{i + 1}}. Rule {{i + 1}}</mat-panel-title>
</div>
<mat-checkbox *ngIf="showMultiplicity" [(ngModel)]="isFieldMultiplicityEnabled" (ngModelChange)="onIsFieldMultiplicityEnabledChange(isFieldMultiplicityEnabled)">Multiplicity</mat-checkbox>
<mat-expansion-panel *ngFor="let rule of dataModel.visible.rules let i=index;">
<mat-expansion-panel-header>
<mat-panel-title>{{i + 1}}. Rule {{i + 1}}</mat-panel-title>
<div class="btn-group pull-right">
<button type="button" class="btn btn-sm" style="margin-left:5px;" (click)="DeleteRule(i);">
<span class="glyphicon glyphicon-erase"></span>
</button>
</div>
</mat-expansion-panel-header>
<rule-form [form]="form.get('visible').get('rules').get(''+i)" [dataModel]="rule"></rule-form>
</mat-expansion-panel>
<a (click)="addNewRule()" style="cursor: pointer">
Add Rule +
</a>
<div class="btn-group pull-right">
<button type="button" class="btn btn-sm" style="margin-left:5px;" (click)="DeleteRule(i);">
<span class="glyphicon glyphicon-erase"></span>
</button>
</div>
</mat-expansion-panel-header>
<rule-form [form]="form.get('visible').get('rules').get(''+i)" [dataModel]="rule"></rule-form>
</mat-expansion-panel>
<a (click)="addNewRule()" style="cursor: pointer">
Add Rule +
</a>
</div>
</div>

View File

@ -1,78 +1,78 @@
<div>
<div class="row" [formGroup]="form">
<div class="col-md-6">
<mat-form-field class="full-width">
<input matInput type="text" placeholder="Title" formControlName="title">
</mat-form-field>
<mat-form-field class="full-width">
<input matInput type="text" placeholder="Id" formControlName="id">
</mat-form-field>
<mat-form-field class="full-width">
<input matInput type="number" placeholder="Ordinal" formControlName="ordinal">
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field class="full-width">
<mat-select placeholder='Page' formControlName="page">
<mat-option *ngFor="let pageGroup of form.root.get('pages').controls;" [value]="pageGroup.get('id').value">{{pageGroup.get('title').value}}</mat-option>
</mat-select>
<!-- <div *ngIf="form.get('page').invalid && (form.get('page').dirty || form.get('page').touched)" class="alert alert-danger">Page is required</div> -->
</mat-form-field>
<label>Default Visibility</label>
<mat-radio-group formControlName="defaultVisibility" class="full-width">
<mat-radio-button [value]="true">true</mat-radio-button>
<mat-radio-button [value]="false">false</mat-radio-button>
</mat-radio-group>
</div>
<div class="row" [formGroup]="form">
<div class="col-md-6">
<mat-form-field class="full-width">
<input matInput type="text" placeholder="Title" formControlName="title">
</mat-form-field>
<mat-form-field class="full-width">
<input matInput type="text" placeholder="Id" formControlName="id">
</mat-form-field>
<mat-form-field class="full-width">
<input matInput type="number" placeholder="Ordinal" formControlName="ordinal">
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field class="full-width">
<mat-select placeholder='Page' formControlName="page">
<mat-option *ngFor="let pageGroup of form.root.get('pages')['controls'];" [value]="pageGroup.get('id').value">{{pageGroup.get('title').value}}</mat-option>
</mat-select>
<!-- <div *ngIf="form.get('page').invalid && (form.get('page').dirty || form.get('page').touched)" class="alert alert-danger">Page is required</div> -->
</mat-form-field>
<label>Default Visibility</label>
<mat-radio-group formControlName="defaultVisibility" class="full-width">
<mat-radio-button [value]="true">true</mat-radio-button>
<mat-radio-button [value]="false">false</mat-radio-button>
</mat-radio-group>
<div *ngIf="dataModel.sections.length > 0">
<mat-expansion-panel *ngFor="let section of dataModel.sections; let i=index;">
<mat-expansion-panel-header>
<mat-panel-title *ngIf="form.get('sections').get(''+i).get('title').value">{{i + 1}}. {{form.get('sections').get(''+i).get('title').value}}</mat-panel-title>
<div class="btn-group pull-right">
<button type="button" class="btn btn-sm" style="margin-left:5px;" (click)="DeleteSectionInSection(i);">
<span class="glyphicon glyphicon-erase"></span>
</button>
</div>
</mat-expansion-panel-header>
<div id="{{indexPath + 's' + i}}">
<section-form [form]="form.get('sections').get(''+i)" [dataModel]="section" [indexPath]="indexPath + 's' + i"></section-form>
</div>
</mat-expansion-panel>
</div>
</div>
<div *ngIf="dataModel.sections.length > 0">
<mat-expansion-panel *ngFor="let section of dataModel.sections; let i=index;">
<mat-expansion-panel-header>
<mat-panel-title *ngIf="form.get('sections').get(''+i).get('title').value">{{i + 1}}. {{form.get('sections').get(''+i).get('title').value}}</mat-panel-title>
<div class="btn-group pull-right">
<button type="button" class="btn btn-sm" style="margin-left:5px;" (click)="DeleteSectionInSection(i);">
<span class="glyphicon glyphicon-erase"></span>
</button>
</div>
</mat-expansion-panel-header>
<div id="{{indexPath + 's' + i}}">
<section-form [form]="form.get('sections').get(''+i)" [dataModel]="section" [indexPath]="indexPath + 's' + i"></section-form>
</div>
</mat-expansion-panel>
</div>
<!-- <div *ngFor="let fieldGroup of dataModel.fieldGroups let i=index;">
<!-- <div *ngFor="let fieldGroup of dataModel.fieldGroups let i=index;">
<groupfield-form [form]="form.get('fieldGroups').get(''+i)" [dataModel]="fieldGroup" [indexPath]="indexPath + 'g' + i"></groupfield-form>
</div> -->
<div>
<mat-expansion-panel *ngFor="let field of dataModel.fieldSets let i=index;" class="panel panel-default">
<mat-expansion-panel-header>
<!-- <a *ngIf="form.get('compositeFields').get(''+i).get('title').value" data-toggle="collapse" href="#{{'compositeFieldCollapse' + i}}"
<div>
<mat-expansion-panel *ngFor="let field of dataModel.fieldSets let i=index;" class="panel panel-default">
<mat-expansion-panel-header>
<!-- <a *ngIf="form.get('compositeFields').get(''+i).get('title').value" data-toggle="collapse" href="#{{'compositeFieldCollapse' + i}}"
class="panel-title pull-left" style="padding-top: 7.5px;">{{i + 1}}. {{form.get('compositeFields').get(''+i).get('title').value}}</a>
<a *ngIf="!form.get('compositeFields').get(''+i).get('title').value" data-toggle="collapse" href="#{{'compositeFieldCollapse' + i}}"
class="panel-title pull-left" style="padding-top: 7.5px;">{{i + 1}}. Field {{i + 1}}</a> -->
<mat-panel-title>{{i + 1}}. Field {{i + 1}}</mat-panel-title>
<mat-panel-title>{{i + 1}}. Field {{i + 1}}</mat-panel-title>
<div>
<button type="button" class="btn btn-sm" style="margin-left:5px;" (click)="DeleteFieldSet(i);">
<span class="glyphicon glyphicon-erase"></span>
</button>
</div>
</mat-expansion-panel-header>
<div>
<button type="button" class="btn btn-sm" style="margin-left:5px;" (click)="DeleteFieldSet(i);">
<span class="glyphicon glyphicon-erase"></span>
</button>
</div>
</mat-expansion-panel-header>
<compositefield-form [form]="form.get('fieldSets').get(''+i)" [dataModel]="field" [indexPath]="indexPath + 'cf' + i"></compositefield-form>
<compositefield-form [form]="form.get('fieldSets').get(''+i)" [dataModel]="field" [indexPath]="indexPath + 'cf' + i"></compositefield-form>
</mat-expansion-panel>
</div>
</mat-expansion-panel>
</div>
<!--
<!--
<div *ngIf="dataModel.fieldGroups" class="panel-group" style="margin-top:10px;">
<div *ngFor="let fieldGroup of dataModel.fieldGroups let i=index;" class="panel panel-default">
<div class="panel-heading clearfix">
@ -93,19 +93,19 @@
</div>
</div>
</div> -->
<!-- <div>
<!-- <div>
<a (click)="addGroupField()" style="cursor: pointer">
Add Group +
</a>
</div> -->
<div>
<a (click)="addField()" style="cursor: pointer">
Add Field +
</a>
</div>
<div>
<a (click)="addSectioninSection()" style="cursor: pointer">
Add Section +
</a>
</div>
</div>
<div>
<a (click)="addField()" style="cursor: pointer">
Add Field +
</a>
</div>
<div>
<a (click)="addSectioninSection()" style="cursor: pointer">
Add Section +
</a>
</div>
</div>

View File

@ -13,15 +13,11 @@
<button mat-raised-button color="primary" *ngIf="datasetWizardModel&&datasetWizardModel?.status == 1" style="margin-top: 15px;margin-bottom: 15px;margin-right: 15px;"
(click)="downloadXML();" type="button">Download XML</button>
<div class="fill-space"></div>
<mat-menu #actionsMenu="matMenu">
<button mat-menu-item (click)="redirectToProject()">
<mat-icon>arrow_right_alt</mat-icon>{{'DATASET-WIZARD.ACTIONS.GO-TO-PROJECT' | translate}}</button>
<button mat-menu-item (click)="redirectToDmp()">
<mat-icon>arrow_right_alt</mat-icon>{{'DATASET-WIZARD.ACTIONS.GO-TO-DMP' | translate}}</button>
</mat-menu>
<button mat-icon-button type="button" style="margin-top: 15px;margin-bottom: 15px;margin-right: 15px;" [matMenuTriggerFor]="actionsMenu">
<mat-icon>more_vert</mat-icon>
</button>
<button mat-button (click)="redirectToProject()">
<mat-icon>arrow_right_alt</mat-icon>{{'DATASET-WIZARD.ACTIONS.GO-TO-PROJECT' | translate}}</button>
<button mat-button (click)="redirectToDmp()">
<mat-icon>arrow_right_alt</mat-icon>{{'DATASET-WIZARD.ACTIONS.GO-TO-DMP' | translate}}</button>
</div>
<mat-horizontal-stepper [linear]="isLinear" #stepper>
<mat-step [stepControl]="formGroup">
@ -54,8 +50,9 @@
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('dataRepositories') && dataRepositoriesTemplate && externalSourcesConfiguration"
[options]="externalSourcesConfiguration.dataRepositories" placeholder="{{'DATASET-EDITOR.FIELDS.DATAREPOSITORIES' | translate}}"
[parentTemplate]='dataRepositoriesTemplate' [displayFunction]='dataRepositoryDisplayFunc' [formGroup]="formGroup.get('dataRepositories')"
[autoCompleteConfiguration]="dataRepositoriesAutoCompleteConfiguration" (onItemChange)="dataRepositoriesOnItemChange($event)">
[parentTemplate]='dataRepositoriesTemplate' [displayFunction]='dataRepositoryDisplayFunc' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc'
[formGroup]="formGroup.get('dataRepositories')" [autoCompleteConfiguration]="dataRepositoriesAutoCompleteConfiguration"
(onItemChange)="dataRepositoriesOnItemChange($event)">
</app-external-item-listing>
@ -86,8 +83,9 @@
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('externalDatasets') && externalDatasetsTemplate && externalSourcesConfiguration"
[options]="externalSourcesConfiguration.externalDatasets" placeholder="{{'DATASET-EDITOR.FIELDS.EXTERNAL-DATASETS' | translate}}"
[parentTemplate]='externalDatasetsTemplate' [displayFunction]='externalDatasetDisplayFunc' [formGroup]="formGroup.get('externalDatasets')"
[autoCompleteConfiguration]="externalDatasetAutoCompleteConfiguration" (onItemChange)="externalDatasetsOnItemChange($event)">
[parentTemplate]='externalDatasetsTemplate' [displayFunction]='externalDatasetDisplayFunc' [subtitleFunction]='dataRepositoryDisplaySubtitleFunc'
[formGroup]="formGroup.get('externalDatasets')" [autoCompleteConfiguration]="externalDatasetAutoCompleteConfiguration"
(onItemChange)="externalDatasetsOnItemChange($event)">
</app-external-item-listing>
@ -128,7 +126,8 @@
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('registries') && registriesTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.registries"
placeholder="{{'DATASET-EDITOR.FIELDS.REGISTRIES' | translate}}" [parentTemplate]='registriesTemplate' [displayFunction]='registriesDisplayFunc'
[formGroup]="formGroup.get('registries')" [autoCompleteConfiguration]="registriesAutoCompleteConfiguration" (onItemChange)="registriesOnItemChange($event)">
[formGroup]="formGroup.get('registries')" [subtitleFunction]='dataRepositoryDisplaySubtitleFunc' [autoCompleteConfiguration]="registriesAutoCompleteConfiguration"
(onItemChange)="registriesOnItemChange($event)">
</app-external-item-listing>
@ -154,7 +153,8 @@
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('services') && servicesTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.services"
placeholder="{{'DATASET-EDITOR.FIELDS.SERVICES' | translate}}" [parentTemplate]='servicesTemplate' [displayFunction]='servicesDisplayFunc'
[formGroup]="formGroup.get('services')" [autoCompleteConfiguration]="servicesAutoCompleteConfiguration" (onItemChange)="servicesOnItemChange($event)">
[formGroup]="formGroup.get('services')" [subtitleFunction]='dataRepositoryDisplaySubtitleFunc' [autoCompleteConfiguration]="servicesAutoCompleteConfiguration"
(onItemChange)="servicesOnItemChange($event)">
</app-external-item-listing>
@ -172,6 +172,33 @@
</ng-template>
</mat-card>
<mat-card>
<mat-card-header>
<mat-card-title class="thick">
{{'DATASET-EDITOR.FIELDS.TAG' | translate}}
</mat-card-title>
</mat-card-header>
<app-external-item-listing *ngIf="formGroup.get('tags') && tagsTemplate && externalSourcesConfiguration" [options]="externalSourcesConfiguration.tags"
placeholder="{{'DATASET-EDITOR.FIELDS.TAGS' | translate}}" [parentTemplate]='tagsTemplate' [displayFunction]='tagsDisplayFunc'
[formGroup]="formGroup.get('tags')" [subtitleFunction]='tagsDisplaySubtitleFunc' [autoCompleteConfiguration]="tagsAutoCompleteConfiguration"
(onItemChange)="tagsOnItemChange($event)">
</app-external-item-listing>
<ng-template #tagsTemplate let-suggestion let-i="index" let-callback="function">
<div>
<p>
{{i+1}}) {{suggestion.get('name').value}}
</p>
</div>
<div>
<button mat-button (click)="callback(i)">
<mat-icon>close</mat-icon>
</button>
</div>
</ng-template>
</mat-card>
<div class="navigation-buttons-container">
<button matStepperPrevious mat-raised-button color="primary">{{'DATASET-WIZARD.ACTIONS.BACK' | translate}}</button>
<button matStepperNext mat-raised-button color="primary" style="float:right;" (click)="getDefinition()">{{'DATASET-WIZARD.ACTIONS.NEXT' | translate}}</button>

View File

@ -33,6 +33,8 @@ import { ExternalSourcesConfiguration } from '../../models/external-sources/Exte
import { IBreadCrumbComponent } from '../../shared/components/breadcrumb/definition/IBreadCrumbComponent';
import { Observable } from 'rxjs/Observable';
import { BreadcrumbItem } from '../../shared/components/breadcrumb/definition/breadcrumb-item';
import { TagsCriteria } from '../../models/criteria/tags/TagsCriteria';
import { TagModel } from '../../models/tags/TagModel';
@Component({
selector: 'app-dataset-wizard-component',
@ -45,16 +47,26 @@ export class DatasetWizardComponent implements OnInit, IBreadCrumbComponent {
@ViewChild('stepper') stepper: MatStepper;
//autocomplete Display Functions;
externalDatasetDisplayFunc = (item) => item ? item.label + " (" + item.tag + ")" : null;
registriesDisplayFunc = (item) => item ? item.label + " (" + item.tag + ")" : null;
dataRepositoryDisplayFunc = (item) => item ? (item.name + " (" + item.tag + ")") : null;
servicesDisplayFunc = (item) => item ? item.label + " (" + item.tag + ")" : null;
externalDatasetDisplayFunc = (item) => item ? item.label : null;
registriesDisplayFunc = (item) => item ? item.label : null;
dataRepositoryDisplayFunc = (item) => item ? item.name : null;
servicesDisplayFunc = (item) => item ? item.label : null;
tagsDisplayFunc = (item) => item ? item.name : null;
//autocomplete Display Functions;
externalDatasetDisplaySubtitleFunc = (item) => item ? item.tag : null;
registriesDisplaySubtitleFunc = (item) => item ? item.tag : null;
dataRepositoryDisplaySubtitleFunc = (item) => item ? item.tag : null;
servicesDisplaySubtitleFunc = (item) => item ? item.tag : null;
tagsDisplaySubtitleFunc = (item) => item ? item.tag : null;
//autocomplete Configurations;
externalDatasetAutoCompleteConfiguration: AutoCompleteConfiguration;
registriesAutoCompleteConfiguration: AutoCompleteConfiguration;
dataRepositoriesAutoCompleteConfiguration: AutoCompleteConfiguration;
servicesAutoCompleteConfiguration: AutoCompleteConfiguration;
tagsAutoCompleteConfiguration: AutoCompleteConfiguration;
externalSourcesConfiguration: ExternalSourcesConfiguration;
datasetWizardModel: DatasetWizardModel;
@ -103,12 +115,17 @@ export class DatasetWizardComponent implements OnInit, IBreadCrumbComponent {
servicesRequestItem.criteria = new ServicesCriteria();
this.servicesAutoCompleteConfiguration = new AutoCompleteConfiguration(this.externalSourcesService.searchDatasetService.bind(this.externalSourcesService), servicesRequestItem)
let tagsRequestItem: RequestItem<TagsCriteria> = new RequestItem();
tagsRequestItem.criteria = new TagsCriteria();
this.tagsAutoCompleteConfiguration = new AutoCompleteConfiguration(this.externalSourcesService.searchDatasetTags.bind(this.externalSourcesService), tagsRequestItem)
this.externalSourcesConfigurationService.getExternalSourcesConfiguration().subscribe(result => {
this.externalSourcesConfiguration = result;
this.externalSourcesConfiguration.dataRepositories.push({ key: '', label: "All" })
this.externalSourcesConfiguration.externalDatasets.push({ key: '', label: "All" })
this.externalSourcesConfiguration.registries.push({ key: '', label: "All" })
this.externalSourcesConfiguration.services.push({ key: '', label: "All" })
this.externalSourcesConfiguration.tags.push({ key: '', label: "All" })
})
let dmpAutoCompleteConfiguration = {}
this.route.params.subscribe((params: Params) => {
@ -243,7 +260,6 @@ export class DatasetWizardComponent implements OnInit, IBreadCrumbComponent {
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
data: { message: this.isNew ? 'GENERAL.SNACK-BAR.SUCCESSFUL-CREATION' : 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language },
duration: 3000,
extraClasses: ['snackbar-success']
})
}
@ -316,6 +332,12 @@ export class DatasetWizardComponent implements OnInit, IBreadCrumbComponent {
(<FormArray>this.formGroup.get("services")).push(serviceModel.buildForm());
}
tagsOnItemChange(event) {
let serviceModel = new TagModel(event.id, event.name);
(<FormArray>this.formGroup.get("tags")).push(serviceModel.buildForm());
}
dataRepositoriesOnItemChange(event) {
let dataRepositoryModel = new DataRepositoryModel(event.id, event.name, event.pid, event.uri);
(<FormArray>this.formGroup.get("dataRepositories")).push(dataRepositoryModel.buildForm());

View File

@ -88,7 +88,6 @@ export class DataManagementPlanProfileEditorComponent implements AfterViewInit {
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
data: { message: this.isNew ? 'GENERAL.SNACK-BAR.SUCCESSFUL-CREATION' : 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language },
duration: 3000,
extraClasses: ['snackbar-success']
})
this.router.navigate(['/dmp-profiles']);
}

View File

@ -31,6 +31,7 @@ import { RouterModule } from '@angular/router';
import { ResearcherService } from '../services/researchers/researchers.service';
import { InvitationService } from '../services/invitation/invitation.service';
import { DatasetService } from '../services/dataset/dataset.service';
import { FlexLayoutModule } from '@angular/flex-layout';
@NgModule({
imports: [

View File

@ -11,19 +11,28 @@
<h3>{{formGroup.get('label').value}} </h3>
</mat-card-title>
<div class="fill-space"></div>
<mat-menu #actionsMenu="matMenu">
<button mat-menu-item (click)="redirectToProject()">
<mat-icon>arrow_right_alt</mat-icon>{{'DMP-EDITOR.ACTIONS.GO-TO-PROJECT' | translate}}</button>
<button mat-menu-item (click)="redirectToDatasets()">
<mat-icon>arrow_right_alt</mat-icon>{{'DMP-EDITOR.ACTIONS.GO-TO-DATASETS' | translate}}</button>
<button mat-menu-item (click)="newVersion(this.dataManagementPlan.id, this.dataManagementPlan.label)">
<mat-icon>queue</mat-icon>{{'DMP-LISTING.ACTIONS.NEW-VERSION' | translate}}</button>
<button mat-menu-item (click)="clone(this.dataManagementPlan.id)">
<mat-icon>filter_none</mat-icon>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</button>
</mat-menu>
<button mat-icon-button type="button" [matMenuTriggerFor]="actionsMenu">
<mat-icon>more_vert</mat-icon>
</button>
<div *ngIf="!isNew" flexLayout="row">
<div fxFlex>
<button mat-button type="button" (click)="redirectToProject()">
<mat-icon>arrow_right_alt</mat-icon>{{'DMP-EDITOR.ACTIONS.GO-TO-PROJECT' | translate}}</button>
</div>
<div fxFlex>
<button mat-button type="button" (click)="redirectToDatasets()">
<mat-icon>arrow_right_alt</mat-icon>{{'DMP-EDITOR.ACTIONS.GO-TO-DATASETS' | translate}}</button>
</div>
<mat-menu #actionsMenu="matMenu">
<button mat-menu-item (click)="newVersion(this.dataManagementPlan.id, this.dataManagementPlan.label)">
<mat-icon>queue</mat-icon>{{'DMP-LISTING.ACTIONS.NEW-VERSION' | translate}}</button>
<button mat-menu-item (click)="clone(this.dataManagementPlan.id)">
<mat-icon>filter_none</mat-icon>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</button>
</mat-menu>
<div fxFlex>
<button fxFlex mat-icon-button type="button" [matMenuTriggerFor]="actionsMenu">
<mat-icon>more_vert</mat-icon>
</button>
</div>
</div>
</mat-card-header>
<mat-card-content>
<mat-form-field class="full-width">
@ -97,7 +106,7 @@
<mat-progress-bar [style.height.px]="2" *ngIf="filteringResearchersAsync" mode="indeterminate"></mat-progress-bar>
</td-chips>
<button style="display:inline-block;" mat-icon-button (click)="addResearcher()">
<button style="display:inline-block;" mat-icon-button type="button" (click)="addResearcher()">
<mat-icon aria-label="Example icon-button with a heart icon">add_circle</mat-icon>
</button>
</div>

View File

@ -154,7 +154,6 @@ export class DataManagementPlanEditorComponent implements AfterViewInit, IBreadC
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
data: { message: this.isNew ? 'GENERAL.SNACK-BAR.SUCCESSFUL-CREATION' : 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language },
duration: 3000,
extraClasses: ['snackbar-success']
})
this.router.navigate(['/dmps']);
}

View File

@ -1,19 +1,19 @@
<div class="dmp-wizard">
<mat-horizontal-stepper [linear]="isLinear" #stepper>
<mat-step>
<ng-template matStepLabel>{{'DMP-WIZARD.FIRST-STEP.DMP' | translate}}</ng-template>
<app-dmp-wizard-editor-component [formGroup]="formGroup" *ngIf="formGroup"></app-dmp-wizard-editor-component>
<div class="navigation-buttons-container">
<button style="float:right;" matStepperNext mat-raised-button color="primary">{{'DATASET-WIZARD.ACTIONS.NEXT' | translate}}</button>
</div>
</mat-step>
<mat-step>
<ng-template matStepLabel>{{'DMP-WIZARD.FIRST-STEP.DATASETS' | translate}}</ng-template>
<app-dataset-wizard-listing-component [formGroup]="formGroup" [dmpId]="formGroup.get('id').value" *ngIf="formGroup"></app-dataset-wizard-listing-component>
<div class="navigation-buttons-container">
<button matStepperPrevious mat-raised-button color="primary">{{'DATASET-WIZARD.ACTIONS.BACK' | translate}}</button>
<button style="float:right;" matStepperNext mat-raised-button (click)='submit()' color="primary">{{'DMP-WIZARD.ACTIONS.SAVE' | translate}}</button>
</div>
</mat-step>
</mat-horizontal-stepper>
</div>
<mat-horizontal-stepper #stepper>
<mat-step>
<ng-template matStepLabel>{{'DMP-WIZARD.FIRST-STEP.DMP' | translate}}</ng-template>
<app-dmp-wizard-editor-component [formGroup]="formGroup" *ngIf="formGroup"></app-dmp-wizard-editor-component>
<div class="navigation-buttons-container">
<button style="float:right;" matStepperNext mat-raised-button color="primary">{{'DATASET-WIZARD.ACTIONS.NEXT' | translate}}</button>
</div>
</mat-step>
<mat-step>
<ng-template matStepLabel>{{'DMP-WIZARD.FIRST-STEP.DATASETS' | translate}}</ng-template>
<app-dataset-wizard-listing-component [formGroup]="formGroup" [dmpId]="formGroup.get('id').value" *ngIf="formGroup"></app-dataset-wizard-listing-component>
<div class="navigation-buttons-container">
<button matStepperPrevious mat-raised-button color="primary">{{'DATASET-WIZARD.ACTIONS.BACK' | translate}}</button>
<button style="float:right;" matStepperNext mat-raised-button (click)='submit()' color="primary">{{'DMP-WIZARD.ACTIONS.SAVE' | translate}}</button>
</div>
</mat-step>
</mat-horizontal-stepper>
</div>

View File

@ -26,10 +26,10 @@ export class DataManagementPlanWizardComponent implements OnInit, IBreadCrumbCom
private router: Router
) { }
itemId: string
dataManagementPlan: DataManagementPlanModel;
formGroup: FormGroup
isClone: boolean
public itemId: string
public dataManagementPlan: DataManagementPlanModel;
public formGroup: FormGroup
public isClone: boolean
ngOnInit(): void {
@ -65,7 +65,6 @@ export class DataManagementPlanWizardComponent implements OnInit, IBreadCrumbCom
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language },
duration: 3000,
extraClasses: ['snackbar-success']
})
this.router.navigate(['/dmps']);
}

View File

@ -100,7 +100,6 @@ export class DataManagementPlanWizardEditorComponent implements AfterViewInit {
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
data: { message: this.isNew ? 'GENERAL.SNACK-BAR.SUCCESSFUL-CREATION' : 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language },
duration: 3000,
extraClasses: ['snackbar-success']
})
this.router.navigate(['/dmps']);
}

View File

@ -23,11 +23,11 @@ export class AutocompleteRemoteComponent implements OnInit/* , ControlValueAcces
@Input() disabled = false
@Input() form: FormGroup;
private autoCompleteConfiguration: AutoCompleteConfiguration;
private loading: boolean;
private datasetId;
values: any[] = new Array();
typeaheadMS: number = 1400;
public autoCompleteConfiguration: AutoCompleteConfiguration;
public loading: boolean;
public datasetId;
public values: any[] = new Array();
public typeaheadMS: number = 1400;
constructor(private datasetProfileService: DatasetProfileService, route: ActivatedRoute) {
this.datasetId = route.snapshot.params['id'];

View File

@ -11,8 +11,8 @@
<div *ngSwitchCase="'freetext'">
<mat-form-field>
<input matInput formControlName="value" placeholder="{{field.data.label}}" [required]="field.validationRequired">
<mat-error *ngIf="form.get('value').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<input matInput formControlName="value" placeholder="{{field.data.label}}" [required]="field.validationRequired">
<mat-error *ngIf="form.get('value')['errors'] && form.get('value')['errors']['required']">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
@ -33,11 +33,12 @@
<div *ngSwitchCase="'textarea'">
<mat-form-field>
<textarea matInput formControlName="value" matTextareaAutosize matAutosizeMinRows="2" matAutosizeMaxRows="10" [required]="field.validationRequired"> </textarea>
<textarea matInput formControlName="value" matTextareaAutosize matAutosizeMinRows="2" matAutosizeMaxRows="10" [required]="field.validationRequired">
</textarea>
<button mat-button *ngIf="form.get('value').value" matSuffix mat-icon-button aria-label="Clear" (click)="this.form.patchValue({'value': ''})">
<mat-icon>close</mat-icon>
</button>
<mat-error *ngIf="form.get('value').errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<mat-icon>close</mat-icon>
</button>
<mat-error *ngIf="form.get('value')['errors'] && form.get('value')['errors']['required']">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
@ -55,7 +56,7 @@
<!--<div [hidden]="isValid">
<mat-error *ngIf="isValidRequired">The field "{{field.data.label}}" <strong>required</strong></mat-error>
<div class="invalid-feedbackCustom" *ngIf="isValidRequired">The field "{{field.label}}" is required</div>
<div class="invalid-feedbackCustom" *ngIf="isValidRequired">The field "{{field.label}}" is required</div>
<div class="invalid-feedbackCustom" *ngIf="isValidPattern">The field {{field.label}} must match a regular expression {{field.regex}}</div>
<div class="invalid-feedbackCustom" *ngIf="isValidCustom">The field {{field.label}} custom Validation</div>
</div>-->
@ -79,13 +80,13 @@
<option *ngFor="let opt of field.options" [value]="opt.key">{{opt.value}}</option>
</select>
<input *ngSwitchCase="'checkbox'" [formControlName]="field.key" [(ngModel)]="field.value"
[id]="field.key" [type]="field.type" (change)="field.value = ckb.checked" #ckb>
</div>
</div>
<div class="alert alert-danger" *ngIf="!isValid">{{field.label}} is required</div>
@ -98,7 +99,7 @@
<!-- <div *ngSwitchCase="'dropdown'">
<autocomplete-remote *ngIf="field.url" formControlName="value" [url]="field.url" ></autocomplete-remote>
<select *ngIf="!field.url" class="form-control" [id]="field.key" formControlName="field.key" [required]="field.required" (change)="toggleVisibility($event, field, false)">
<option *ngFor="let opt of field.options" [value]="opt._value" >{{opt._label}}</option>
</select>
@ -121,14 +122,14 @@
<div *ngIf="rule._type == 'fieldVisible'; else otherRuleBlock">
<div hidden="{{ruleVisibleMethod(field, rule, dataModel)}}">
<label [attr.for]="field.key">{{field.label}}</label>
<input *ngSwitchCase="'textbox'" class="form-control" [formControlName]="field.key" [id]="field.key" [type]="field.type"
required="field.required">
<select [id]="field.key" *ngSwitchCase="'dropdown'" class="form-control" [formControlName]="field.key">
<option *ngFor="let opt of field.options" [value]="opt.key">{{opt.value}}</option>
</select>
<input *ngSwitchCase="'checkbox'" [formControlName]="field.key" [(ngModel)]="field.value" [id]="field.key" [type]="field.type"
(change)="field.value = ckb.checked" #ckb>
</div>
@ -136,23 +137,23 @@
</div>
</div>
</div>
<ng-template #elseBlock>
<label [attr.for]="field.key">{{field.label}}</label>
<input *ngSwitchCase="'textbox'" class="form-control" [formControlName]="field.key" [id]="field.key" [type]="field.type"
required="field.required">
<select [id]="field.key" *ngSwitchCase="'dropdown'" class="form-control" [formControlName]="field.key">
<option *ngFor="let opt of field.options" [value]="opt.key">{{opt.value}}</option>
</select>
<input *ngSwitchCase="'checkbox'" [formControlName]="field.key" [(ngModel)]="field.value" [id]="field.key" [type]="field.type"
(change)="field.value = ckb.checked" #ckb>
</ng-template>
<ng-template #otherRuleBlock>
<ng-template #otherRuleBlock>
</ng-template>
</div> -->
</div> -->

View File

@ -21,7 +21,7 @@ export class DynamicFormFieldComponent implements OnInit {
@Input() pathName: string;
@Input() path: string;
constructor(private route: ActivatedRoute, private visibilityRulesService: VisibilityRulesService) { }
constructor(private route: ActivatedRoute, public visibilityRulesService: VisibilityRulesService) { }
ngOnInit() {
this.form.get('value').valueChanges.subscribe(item => {

View File

@ -21,7 +21,7 @@ export class DynamicFormGroupComponent implements OnInit {
@Input() path: string;
constructor(private visibilityRulesService: VisibilityRulesService) {
constructor(public visibilityRulesService: VisibilityRulesService) {
}
ngOnInit() {

View File

@ -19,7 +19,7 @@ export class DynamicFormSectionComponent implements OnInit {
@Input() form: FormGroup;
@Input() pathName: string;
@Input() path: string;
constructor(private visibilityRulesService: VisibilityRulesService) { }
constructor(public visibilityRulesService: VisibilityRulesService) { }
ngOnInit() {
}

View File

@ -1,5 +1,5 @@
<!-- <p-progressBar [value]="value" [style]="{'height': '30px'}" [styleClass]="'alwaysVisible'"></p-progressBar> -->
<div class="demo-progress-bar-container">
<mat-progress-bar class="form-progress-bar" mode="determinate" [value]="value" [color]="color"></mat-progress-bar>
</div>
<mat-progress-bar class="form-progress-bar" mode="determinate" [value]="value"></mat-progress-bar>
</div>

View File

@ -16,7 +16,7 @@ export class ProgressBarComponent implements OnInit {
constructor(private visibilityRulesService: VisibilityRulesService) { }
private value: number = 0;
public value: number = 0;
ngOnInit() {
this.calculateValueForProgressbar()
this.formGroup

View File

@ -1,7 +1,7 @@
<!-- All contents in the first page -->
<ul>
<li *ngFor="let section of model.sections let i = index">
<!-- && field.label for sections without field label as data summery -->
<table-of-contents-section [page]='section.page' [model]="section" [index]="i+1" [path]="i+1"> </table-of-contents-section>
</li>
</ul>
<li *ngFor="let section of model['sections'] let i = index">
<!-- && field.label for sections without field label as data summery -->
<table-of-contents-section [page]='section.page' [model]="section" [index]="i+1" [path]="i+1"> </table-of-contents-section>
</li>
</ul>

View File

@ -9,17 +9,18 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
selector: 'table-of-content',
templateUrl: './table-of-contents.component.html',
styleUrls: ['./toc.component.css'],
providers: []
providers: []
})
export class TableOfContentsComponent implements OnInit{
export class TableOfContentsComponent implements OnInit {
@Input() model:DatasetProfileDefinitionModel;
public path:string="";
@Input()
public model: DatasetProfileDefinitionModel;
public path: string = "";
/* @Output()
setPage:EventEmitter<number> = new EventEmitter<number>();
*/ ngOnInit(){
*/ ngOnInit() {
}
}
}
}

View File

@ -12,8 +12,8 @@ import { AuthService } from '../services/auth/auth.service';
})
export class HomepageComponent implements OnInit {
private userInfo: any;
private dashboardStatisticsData: DashboardStatisticsModel = new DashboardStatisticsModel();
public userInfo: any;
public dashboardStatisticsData: DashboardStatisticsModel = new DashboardStatisticsModel();
constructor(
private route: ActivatedRoute,

View File

@ -1,7 +1,9 @@
import { BaseCriteria } from "../BaseCriteria";
import { ExternalSourcesItemModel } from "../../external-sources/ExternalSourcesItemModel";
export class DatasetCriteria extends BaseCriteria {
public status: Number;
public dmpIds: String[] = [];
public allVersions: boolean;
public status: Number;
public dmpIds: String[] = [];
public tags: ExternalSourcesItemModel[] = [];
public allVersions: boolean;
}

View File

@ -0,0 +1,6 @@
import { BaseCriteria } from "../BaseCriteria";
import { ExternalSourcesItemModel } from "../../external-sources/ExternalSourcesItemModel";
export class TagsCriteria extends BaseCriteria {
public type: string;
}

View File

@ -12,6 +12,7 @@ import { JsonSerializer } from "../../utilities/JsonSerializer";
import { RegisterModel } from "../registers/RegisterModel";
import { DataRepositoryModel } from "../dataRepositories/DataRepositoryModel";
import { ExternalDatasetModel } from '../../models/external-dataset/ExternalDatasetModel';
import { TagModel } from '../tags/TagModel';
export class DatasetWizardModel implements Serializable<DatasetWizardModel> {
public id: string;
@ -23,6 +24,7 @@ export class DatasetWizardModel implements Serializable<DatasetWizardModel> {
public services: ServiceModel[] = [];
public registries: RegisterModel[] = [];
public dataRepositories: DataRepositoryModel[] = [];
public tags: TagModel[] = [];
public externalDatasets: ExternalDatasetModel[] = [];
public dmp: DataManagementPlanModel = new DataManagementPlanModel();
public datasetProfileDefinition;
@ -42,6 +44,7 @@ export class DatasetWizardModel implements Serializable<DatasetWizardModel> {
this.profile = JsonSerializer.fromJSONObject(item.profile, DatasetProfileModel);
this.externalDatasets = JsonSerializer.fromJSONArray(item.externalDatasets, ExternalDatasetModel);
this.datasetProfileDefinition = JsonSerializer.fromJSONObject(item.datasetProfileDefinition, DatasetProfileDefinitionModel);
this.tags = JsonSerializer.fromJSONArray(item.tags, TagModel);
return this;
}
@ -54,7 +57,7 @@ export class DatasetWizardModel implements Serializable<DatasetWizardModel> {
uri: [{ value: this.uri, disabled: disabled }, context.getValidation('uri').validators],
status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators],
description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators],
dmp: [{ value: this.dmp, disabled: disabled }, context.getValidation('dmp').validators]
dmp: [{ value: this.dmp, disabled: disabled }, context.getValidation('dmp').validators],
});
const externalDatasetsFormArray = new Array<FormGroup>();
@ -67,6 +70,16 @@ export class DatasetWizardModel implements Serializable<DatasetWizardModel> {
}
formGroup.addControl('externalDatasets', formBuilder.array(externalDatasetsFormArray));
const tagsFormArray = new Array<FormGroup>();
if (this.tags && this.tags.length > 0) {
this.tags.forEach(item => {
tagsFormArray.push(item.buildForm(context.getValidation('tags').descendantValidations, disabled))
})
} else {
//externalDatasetsFormArray.push(new ExternalDatasetModel().buildForm(context.getValidation('externalDatasets').descendantValidations, disabled));
}
formGroup.addControl('tags', formBuilder.array(tagsFormArray));
const registriesFormArray = new Array<FormGroup>();
if (this.registries && this.registries.length > 0) {
this.registries.forEach(item => {
@ -116,6 +129,7 @@ export class DatasetWizardModel implements Serializable<DatasetWizardModel> {
baseContext.validation.push({ key: 'externalDatasets', validators: [BackendErrorValidator(this.errorModel, 'externalDatasets')] });
baseContext.validation.push({ key: 'dmp', validators: [BackendErrorValidator(this.errorModel, 'dmp')] }); //TODO
baseContext.validation.push({ key: 'datasetProfileDefinition', validators: [BackendErrorValidator(this.errorModel, 'datasetProfileDefinition')] }); //TODO
baseContext.validation.push({ key: 'tags', validators: [BackendErrorValidator(this.errorModel, 'datasetProfileDefinition')] }); //TODO
return baseContext;
}

View File

@ -1,8 +1,9 @@
import { ExternalSourcesUrlModel } from "./ExternalSourcesUrlModel";
export class ExternalSourcesConfiguration {
public registries: Array<ExternalSourcesUrlModel>
public dataRepositories: Array<ExternalSourcesUrlModel>
public services: Array<ExternalSourcesUrlModel>
public externalDatasets: Array<ExternalSourcesUrlModel>
}
public registries: Array<ExternalSourcesUrlModel>
public dataRepositories: Array<ExternalSourcesUrlModel>
public services: Array<ExternalSourcesUrlModel>
public externalDatasets: Array<ExternalSourcesUrlModel>
public tags: Array<ExternalSourcesUrlModel>
}

View File

@ -0,0 +1,27 @@
import { Serializable } from "../Serializable";
import { ValidationContext } from "../../utilities/validators/ValidationContext";
import { FormGroup, FormBuilder } from "@angular/forms";
export class TagModel implements Serializable<TagModel> {
public id: string;
public name: string;
constructor(id?: string, name?: string) {
this.id = id;
this.name = name;
}
fromJSONObject(item: any): TagModel {
this.id = item.id;
this.name = item.name;
return this;
}
buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup {
return new FormBuilder().group({
id: [this.id],
name: [this.name]
})
}
}

View File

@ -93,7 +93,6 @@ export class ProjectEditorComponent implements OnInit, IBreadCrumbComponent {
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
data: { message: this.isNew ? 'GENERAL.SNACK-BAR.SUCCESSFUL-CREATION' : 'GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE', language: this.language },
duration: 3000,
extraClasses: ['snackbar-success']
})
this.router.navigate(['/projects']);
}

View File

@ -34,11 +34,11 @@ export class ProjectListingComponent implements OnInit, IBreadCrumbComponent {
displayedColumns: String[] = ['avatar', 'name', 'abbreviation', 'start', 'end', "dmps"];
constructor(
private projectService: ProjectService,
private router: Router,
private languageService: TranslateService,
public projectService: ProjectService,
public router: Router,
public languageService: TranslateService,
public snackBar: MatSnackBar,
private languageResolverService: LanguageResolverService
public languageResolverService: LanguageResolverService
) {
}

View File

@ -133,7 +133,6 @@ export class AuthService {
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
data: { message: 'GENERAL.SNACK-BAR.SUCCESSFUL-LOGOUT', language: this.language },
duration: 3000,
extraClasses: ['snackbar-success']
})
this.router.navigate(['/login']);
}
@ -142,7 +141,6 @@ export class AuthService {
this.snackBar.openFromComponent(SnackBarNotificationComponent, {
data: { message: 'GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGOUT', language: this.language },
duration: 3000,
extraClasses: ['snackbar-warning']
})
this.router.navigate(['/login']);
}

View File

@ -12,6 +12,7 @@ import { ExternalDatasetCriteria } from '../../models/criteria/external-dataset/
import { RegistryCriteria } from '../../models/criteria/registry/RegistryCriteria';
import { DataRepositoryCriteria } from '../../models/criteria/data-repository/DataRepositoryCriteria';
import { ServicesCriteria } from '../../models/criteria/services/ServicesCriteria';
import { TagsCriteria } from '../../models/criteria/tags/TagsCriteria';
@Injectable()
@ -41,6 +42,20 @@ export class ExternalSourcesService {
return this.http.get<ExternalSourcesItemModel[]>(this.actionUrl + "services" + "?query=" + requestItem.criteria.like + "&type=" + requestItem.criteria.type, { headers: this.headers });
}
public searchDatasetTags(requestItem: RequestItem<TagsCriteria>): Observable<ExternalSourcesItemModel[]> {
return Observable.of([
{ id: "1", name: "Tag 1", description: "" },
{ id: "2", name: "Tag 2", description: "" },
{ id: "3", name: "Tag 3", description: "" },
{ id: "4", name: "Tag 4", description: "" },
{ id: "5", name: "Tag 5", description: "" },
{ id: "6", name: "Tag 6", description: "" },
{ id: "7", name: "Tag 7", description: "" },
{ id: "8", name: "Tag 8", description: "" },
])
//return this.http.get<ExternalSourcesItemModel[]>(this.actionUrl + "tags" + "?query=" + requestItem.criteria.like + "&type=" + requestItem.criteria.type, { headers: this.headers });
}
public searchDatasetSExternalDatasetservice(requestItem: RequestItem<ExternalDatasetCriteria>): Observable<ExternalSourcesItemModel[]> {
return this.http.get<ExternalSourcesItemModel[]>(this.actionUrl + "datasets" + "?query=" + requestItem.criteria.like + "&type=" + requestItem.criteria.type, { headers: this.headers });
}

View File

@ -14,7 +14,7 @@ import { ResearcherService } from '../../../services/researchers/researchers.ser
})
export class AddResearchersComponent implements OnInit {
private formGroup: FormGroup;
public formGroup: FormGroup;
constructor(
private researcherService: ResearcherService,

View File

@ -7,7 +7,9 @@
<mat-progress-spinner matSuffix mode="indeterminate" *ngIf="loading" [diameter]="22"></mat-progress-spinner>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFunction" (optionSelected)="this.optionSelected($event)">
<mat-option *ngFor="let option of options" [value]="option">
{{ this.printText(option) }}
{{ this.printText(option) }} |
<small *ngIf="_subtitleFn">{{subtitleFn(option)}}</small>
</mat-option>
</mat-autocomplete>
</mat-form-field>

View File

@ -17,6 +17,8 @@ export class AutoCompleteComponent implements OnInit, ErrorStateMatcher {
@Input() formCtrl: FormControl;
@Input() required = false;
@Input() displayFunction: Function;
@Input() _subtitleFn: Function;
@Input() assignValueFunction: Function;
@Input() transformFunction: Function;
@Input() inputData: AutoCompleteConfiguration;
@ -86,6 +88,10 @@ export class AutoCompleteComponent implements OnInit, ErrorStateMatcher {
else return item;
}
subtitleFn(item) {
return this._subtitleFn(item);
}
getValue(item: any): string {
if (this.assignValueFunction) {
if (this.transformFunction) return this.assignValueFunction(this.transformFunction(item))

View File

@ -25,17 +25,16 @@
</div> -->
<mat-form-field>
<input matInput [matAutocomplete]="auto" [formControl]="control" placeholder="{{placeholder}}" [required]="required" >
<mat-error *ngIf="control.errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<mat-error *ngIf="validationErrorString">{{errorString}}</mat-error>
<mat-progress-spinner matSuffix mode="indeterminate" *ngIf="loading" [diameter]="22"></mat-progress-spinner>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayWith.bind(this)" (optionSelected)="this.optionSelected($event)">
<mat-option *ngFor="let item of filteredItems " [value]="item">
<span *ngIf="titleKey">{{item[titleKey]}}</span>
<span *ngIf="subtitleKey">{{item[subtitleKey]}}</span>
</mat-option>
<!-- <mat-option *ngIf="filteredItems.length == 0" value="das">
<input matInput [matAutocomplete]="auto" [formControl]="control" placeholder="{{placeholder}}" [required]="required">
<mat-error *ngIf="control['errors'] && control['errors']['required']">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<mat-progress-spinner matSuffix mode="indeterminate" *ngIf="loading" [diameter]="22"></mat-progress-spinner>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayWith.bind(this)" (optionSelected)="this.optionSelected($event)">
<mat-option *ngFor="let item of filteredItems " [value]="item">
<span *ngIf="titleKey">{{item[titleKey]}}</span>
<span *ngIf="subtitleKey">{{item[subtitleKey]}}</span>
</mat-option>
<!-- <mat-option *ngIf="filteredItems.length == 0" value="das">
<span>{{'GENERAL.AUTOCOMPLETE.NO-ITEMS' | translate}}</span>
</mat-option> -->
</mat-autocomplete>
</mat-form-field>
</mat-autocomplete>
</mat-form-field>

View File

@ -1,22 +1,21 @@
<mat-form-field>
<mat-chip-list #chipList [required]="required">
<mat-chip *ngFor="let item of selectedItems" (remove)="remove(item)">
{{item.name}}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
<input matInput [matChipInputFor]="chipList" [matAutocomplete]="auto" [formControl]="control"
placeholder="{{placeholder}}" [required]="required" #chipInput>
</mat-chip-list>
<mat-error *ngIf="control.errors?.required">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<mat-error *ngIf="validationErrorString">{{errorString}}</mat-error>
<mat-progress-spinner matSuffix mode="indeterminate" *ngIf="loading" [diameter]="22"></mat-progress-spinner>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayWith.bind(this)" (optionSelected)="this.optionSelected($event)">
<mat-option *ngFor="let item of filteredItems " [value]="item">
<span *ngIf="titleKey">{{item[titleKey]}}</span>
<span *ngIf="subtitleKey">{{item[subtitleKey]}}</span>
</mat-option>
<!-- <mat-option *ngIf="filteredItems.length == 0" value="das">
<mat-chip-list #chipList [required]="required">
<mat-chip *ngFor="let item of selectedItems" (remove)="remove(item)">
{{item.name}}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
<input matInput [matChipInputFor]="chipList" [matAutocomplete]="auto" [formControl]="control" placeholder="{{placeholder}}"
[required]="required" #chipInput>
</mat-chip-list>
<mat-error *ngIf="control['errors']['required']">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
<mat-progress-spinner matSuffix mode="indeterminate" *ngIf="loading" [diameter]="22"></mat-progress-spinner>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayWith.bind(this)" (optionSelected)="this.optionSelected($event)">
<mat-option *ngFor="let item of filteredItems " [value]="item">
<span *ngIf="titleKey">{{item[titleKey]}}</span>
<span *ngIf="subtitleKey">{{item[subtitleKey]}}</span>
</mat-option>
<!-- <mat-option *ngIf="filteredItems.length == 0" value="das">
<span>{{'GENERAL.AUTOCOMPLETE.NO-ITEMS' | translate}}</span>
</mat-option> -->
</mat-autocomplete>
</mat-form-field>
</mat-autocomplete>
</mat-form-field>

View File

@ -15,9 +15,9 @@ import { DatasetProfileModule } from '../../../dataset-profile-form/dataset-prof
})
export class AvailableProfilesComponent implements OnInit {
private formGroup: FormGroup;
private profiles: DatasetProfileModel[] = [];
private selectedProfiles: DatasetProfileModel[] = [];
public formGroup: FormGroup;
public profiles: DatasetProfileModel[] = [];
public selectedProfiles: DatasetProfileModel[] = [];
constructor(
private datasetService: DatasetService,

View File

@ -2,13 +2,13 @@
<mat-card-content aria-label="breadcrumb">
<ol class="no-style" fxLayout="row">
<div fxFlex="nogrow" *ngFor="let breadcrumb of buildBreadCrumb(this.activatedRoute) | async ; let i = index; let length = count ">
<div fxLayout="row" fxLayoutAlign="start center">
<li fxFlex>
<a fxFlex [routerLink]="[breadcrumb.url]" [queryParams]="breadcrumb.params">
<div fxLayout="row">
<li fxFlex="nogrow">
<a [routerLink]="[breadcrumb.url]" [queryParams]="breadcrumb.params">
{{ breadcrumb.label }}
</a>
</li>
<mat-icon fxFlex *ngIf="length > 1 && i != ( length - 1 )">chevron_right</mat-icon>
<mat-icon fxFlex="nogrow" *ngIf="length > 1 && i != ( length - 1 )">chevron_right</mat-icon>
</div>
</div>
</ol>

View File

@ -3,100 +3,100 @@ import { FormControl, FormGroup, NgForm, FormArray, AbstractControl } from '@ang
import { BaseCriteriaErrorModel } from '../../../../models/criteria/BaseCriteriaErrorModel';
@Component({
selector: 'base-criteria-component',
template: '',
providers: [
selector: 'base-criteria-component',
template: '',
providers: [
]
]
})
export class BaseCriteriaComponent implements OnInit {
public refreshCallback: Function = null;
public formGroup: FormGroup = null;
public refreshCallback: Function = null;
public formGroup: FormGroup = null;
constructor(
public baseErrorModel?: BaseCriteriaErrorModel,
) {
}
constructor(
public baseErrorModel?: BaseCriteriaErrorModel,
) {
}
ngOnInit() {
if (this.baseErrorModel == null) { this.baseErrorModel = new BaseCriteriaErrorModel(); }
}
ngOnInit() {
if (this.baseErrorModel == null) { this.baseErrorModel = new BaseCriteriaErrorModel(); }
}
controlModified(): void {
this.clearErrorModel();
if (!this.isFormValid()) { return; }
if (this.refreshCallback != null) { this.refreshCallback(); }
}
controlModified(): void {
this.clearErrorModel();
if (!this.isFormValid()) { return; }
if (this.refreshCallback != null) { this.refreshCallback(); }
}
public isFormValid(): boolean {
this.touchAllFormFields(this.formGroup);
this.validateAllFormFields(this.formGroup);
return this.formGroup.valid;
}
public isFormValid(): boolean {
this.touchAllFormFields(this.formGroup);
this.validateAllFormFields(this.formGroup);
return this.formGroup.valid;
}
public getFormData(): any {
return this.formGroup.value;
}
public getFormData(): any {
return this.formGroup.value;
}
public getFormControl(controlName: string): AbstractControl {
return this.formGroup.get(controlName);
}
public getFormControl(controlName: string): AbstractControl {
return this.formGroup.get(controlName);
}
public disableFormFields(formControl: AbstractControl) {
formControl.disable();
}
public disableFormFields(formControl: AbstractControl) {
formControl.disable();
}
public validateAllFormFields(formControl: AbstractControl) {
if (formControl instanceof FormControl) {
formControl.updateValueAndValidity({ emitEvent: false })
} else if (formControl instanceof FormGroup) {
Object.keys(formControl.controls).forEach(item => {
const control = formControl.get(item);
this.validateAllFormFields(control);
})
} else if (formControl instanceof FormArray) {
formControl.controls.forEach(item => {
this.validateAllFormFields(item);
})
}
}
public validateAllFormFields(formControl: AbstractControl) {
if (formControl instanceof FormControl) {
formControl.updateValueAndValidity({ emitEvent: false })
} else if (formControl instanceof FormGroup) {
Object.keys(formControl.controls).forEach(item => {
const control = formControl.get(item);
this.validateAllFormFields(control);
})
} else if (formControl instanceof FormArray) {
formControl.controls.forEach(item => {
this.validateAllFormFields(item);
})
}
}
public touchAllFormFields(formControl: AbstractControl) {
if (formControl instanceof FormControl) {
formControl.markAsTouched();
} else if (formControl instanceof FormGroup) {
Object.keys(formControl.controls).forEach(item => {
const control = formControl.get(item);
this.touchAllFormFields(control);
})
} else if (formControl instanceof FormArray) {
formControl.controls.forEach(item => {
this.touchAllFormFields(item);
})
}
}
public touchAllFormFields(formControl: AbstractControl) {
if (formControl instanceof FormControl) {
formControl.markAsTouched();
} else if (formControl instanceof FormGroup) {
Object.keys(formControl.controls).forEach(item => {
const control = formControl.get(item);
this.touchAllFormFields(control);
})
} else if (formControl instanceof FormArray) {
formControl.controls.forEach(item => {
this.touchAllFormFields(item);
})
}
}
setRefreshCallback(callback: Function): void {
this.refreshCallback = callback;
}
setRefreshCallback(callback: Function): void {
this.refreshCallback = callback;
}
onCallbackError(error: any) {
this.setErrorModel(error.error);
this.validateAllFormFields(this.formGroup);
}
onCallbackError(error: any) {
this.setErrorModel(error.error);
this.validateAllFormFields(this.formGroup);
}
public setErrorModel(errorModel: BaseCriteriaErrorModel) {
Object.keys(errorModel).forEach(item => {
(<any>this.baseErrorModel)[item] = (<any>errorModel)[item];
})
}
public setErrorModel(errorModel: BaseCriteriaErrorModel) {
Object.keys(errorModel).forEach(item => {
(<any>this.baseErrorModel)[item] = (<any>errorModel)[item];
})
}
public clearErrorModel() {
Object.keys(this.baseErrorModel).forEach(item => {
(<any>this.baseErrorModel)[item] = '';
})
}
public clearErrorModel() {
Object.keys(this.baseErrorModel).forEach(item => {
(<any>this.baseErrorModel)[item] = '';
})
}
}

View File

@ -68,12 +68,7 @@ export class DataManagementPlanCriteriaComponent extends BaseCriteriaComponent i
requestItem.criteria = criteria;
this.projectService.get(requestItem).subscribe(items => {
this.filteredProjects = items;
this.filteringProjectsAsync = false;
// this.filteredProjects = items.filter((filteredObj: any) => {
// return this.objectsModel ? this.objectsModel.indexOf(filteredObj) < 0 : true;
// });
this.filteringProjectsAsync = false;
});
}
}

View File

@ -20,14 +20,14 @@
<mat-datepicker #periodStartPicker></mat-datepicker>
</mat-form-field>
</div> -->
<div class="col-md-6">
<div class="col-md-4">
<mat-form-field>
<input matInput placeholder=" {{'CRITERIA.PROJECTS.LIKE'| translate}}" name="datasetCriteriaName" [(ngModel)]="criteria.like"
(ngModelChange)="controlModified()">
<mat-error *ngIf="baseErrorModel?.name">{{baseErrorModel['Criteria.like']}}</mat-error>
<mat-error *ngIf="baseErrorModel['name']">{{baseErrorModel['Criteria.like']}}</mat-error>
</mat-form-field>
</div>
<div class="col-md-6">
<div class="col-md-4">
<mat-form-field>
<mat-select placeholder=" {{'CRITERIA.DATA-SETS.STATUS'| translate}}" name="datasetCriteriastatus" [(ngModel)]="criteria.status"
(ngModelChange)="controlModified()">
@ -35,9 +35,24 @@
{{status.viewValue}}
</mat-option>
</mat-select>
<mat-error *ngIf="baseErrorModel?.status">{{baseErrorModel['Criteria.status']}}</mat-error>
<mat-error *ngIf="baseErrorModel['status']">{{baseErrorModel['Criteria.status']}}</mat-error>
</mat-form-field>
</div>
<div class="col-md-4">
<td-chips color="accent" [items]="filteredTags" [(ngModel)]="criteria.tags" (ngModelChange)="controlModified()" placeholder="{{'CRITERIA.DATA-SETS.TAGS' | translate}}"
(inputChange)="filterTags($event)" name="tags" requireMatch>
<ng-template td-chip let-chip="chip">
<div class="tc-grey-100 bgc-teal-700" td-chip-avatar>{{chip.name.substring(0, 1).toUpperCase()}}</div>
{{chip.name}}
</ng-template>
<ng-template td-autocomplete-option let-option="option">
<div layout="row" layout-align="start center">
{{option.name}}
</div>
</ng-template>
<mat-progress-bar [style.height.px]="2" *ngIf="filteringTagsAsync" mode="indeterminate"></mat-progress-bar>
</td-chips>
</div>
</div>
</mat-card>
</form>

View File

@ -6,52 +6,78 @@ import { ValidationContext, Validation } from '../../../../utilities/validators/
import { BackendErrorValidator } from '../../../../utilities/validators/BackendErrorValidator';
import { DatasetCriteriaErrorModel } from '../../../../models/criteria/dataset/DatasetCriteriaErrorModel';
import { DatasetCriteria } from '../../../../models/criteria/dataset/DatasetCriteria';
import { TagsCriteria } from '../../../../models/criteria/tags/TagsCriteria';
import { ExternalSourcesService } from '../../../../services/external-sources/external-sources.service';
import { RequestItem } from '../../../../models/criteria/RequestItem';
import { TagModel } from '../../../../models/tags/TagModel';
import { ExternalSourcesItemModel } from '../../../../models/external-sources/ExternalSourcesItemModel';
@Component({
selector: 'app-datasets-criteria-component',
templateUrl: './datasets-criteria.component.html',
styleUrls: ['./datasets-criteria.component.scss'],
providers: [
]
selector: 'app-datasets-criteria-component',
templateUrl: './datasets-criteria.component.html',
styleUrls: ['./datasets-criteria.component.scss'],
providers: [
ExternalSourcesService
]
})
export class DatasetCriteriaComponent extends BaseCriteriaComponent implements OnInit {
// public form: ProjectType;
// public formStatus: ProjectStatus;
public criteria: DatasetCriteria= new DatasetCriteria();
// public form: ProjectType;
// public formStatus: ProjectStatus;
public criteria: DatasetCriteria = new DatasetCriteria();
public filteringTagsAsync: boolean = false;
public filteredTags: ExternalSourcesItemModel[];
statuses = [
{value: '0', viewValue: 'Saved'},
{value: '1', viewValue: 'Finalised'}
];
statuses = [
{ value: '0', viewValue: 'Saved' },
{ value: '1', viewValue: 'Finalised' }
];
constructor(
public language: TranslateService,
public formBuilder: FormBuilder
) {
super(new DatasetCriteriaErrorModel());
}
constructor(
public language: TranslateService,
public formBuilder: FormBuilder,
public externalSourcesService: ExternalSourcesService
) {
super(new DatasetCriteriaErrorModel());
}
ngOnInit() {
super.ngOnInit();
if (this.criteria == null) { this.criteria = new DatasetCriteria(); }
}
ngOnInit() {
super.ngOnInit();
if (this.criteria == null) { this.criteria = new DatasetCriteria(); }
}
setCriteria(criteria: DatasetCriteria): void {
this.criteria = criteria;
}
setCriteria(criteria: DatasetCriteria): void {
this.criteria = criteria;
}
onCallbackError(error: any) {
this.setErrorModel(error.error);
}
onCallbackError(error: any) {
this.setErrorModel(error.error);
}
controlModified(): void {
this.clearErrorModel();
if (this.refreshCallback != null &&
(this.criteria.like == null || this.criteria.like.length == 0 || this.criteria.like.length > 2)
) {
this.refreshCallback();
}
}
controlModified(): void {
this.clearErrorModel();
if (this.refreshCallback != null &&
(this.criteria.like == null || this.criteria.like.length == 0 || this.criteria.like.length > 2)
) {
this.refreshCallback();
}
}
filterTags(value: string): void {
this.filteredTags = undefined;
if (value) {
this.filteringTagsAsync = true;
let requestItem: RequestItem<TagsCriteria> = new RequestItem();
let criteria: TagsCriteria = new TagsCriteria();
criteria.like = value;
requestItem.criteria = criteria;
this.externalSourcesService.searchDatasetTags(requestItem).subscribe(items => {
this.filteredTags = items;
this.filteringTagsAsync = false;
});
}
}
}

View File

@ -27,7 +27,7 @@
<mat-form-field>
<input matInput (focus)="periodEndPicker.open()" (click)="periodEndPicker.open()" name="projectCriteriaPeriodEnd" placeholder=" {{this.languageResolver.getBy('criteriaEnd')| translate}}"
[matDatepicker]="periodEndPicker" [(ngModel)]="criteria.periodEnd" (ngModelChange)="controlModified()">
<mat-error *ngIf="baseErrorModel?.criteria?.periodEnd">{{baseErrorModel['criteria.periodEnd']}}</mat-error>
<mat-error *ngIf="baseErrorModel['criteria.periodEnd']">{{baseErrorModel['criteria.periodEnd']}}</mat-error>
<mat-datepicker-toggle matSuffix [for]="periodEndPicker"></mat-datepicker-toggle>
<mat-datepicker #periodEndPicker></mat-datepicker>
</mat-form-field>

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