Merge branch 'dmp-refactoring' of code-repo.d4science.org:MaDgiK-CITE/argos into dmp-refactoring
|
@ -1,3 +0,0 @@
|
|||
ELK_VERSION=7.6.0
|
||||
# Leave blank to use the "basic" image flavours, which include X-Pack.
|
||||
# see https://www.elastic.co/subscriptions
|
|
@ -1,2 +0,0 @@
|
|||
# Declare files that will always have LF line endings on checkout.
|
||||
*.sh text eol=lf
|
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Anthony Lapenna
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1,4 +0,0 @@
|
|||
Init default users and retrieve passwords
|
||||
|
||||
1) connect to elasticsearch container with docker exec -it elastichsearch /bin/bash
|
||||
2) run ./bin/elasticsearch-setup-passwords auto >./data/passwords.txt (press y and enter when the console shows nothing)
|
|
@ -1,87 +0,0 @@
|
|||
version: '2.4'
|
||||
|
||||
services:
|
||||
elasticsearch:
|
||||
user: 1002:1002 #develuser
|
||||
restart: unless-stopped
|
||||
mem_limit: 2048m
|
||||
environment:
|
||||
- cluster.name=open-dmp-cluster
|
||||
- bootstrap.memory_lock=true
|
||||
- "ES_JAVA_OPTS=-Xmx1024m -Xms1024m"
|
||||
- xpack.license.self_generated.type=basic
|
||||
- xpack.monitoring.collection.enabled=true
|
||||
- xpack.security.enabled=true
|
||||
ulimits:
|
||||
nproc: 65535
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
volumes:
|
||||
- ./shared/config-elk/elasticsearch/config/log4j2.properties:/usr/share/elasticsearch/config/log4j2.properties:ro
|
||||
- ./shared/config-elk/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro
|
||||
- ./shared/data-elk/elasticsearch-01-data:/usr/share/elasticsearch/data
|
||||
- ./shared/data-elk/elasticsearch-01-log:/usr/share/elasticsearch/logs
|
||||
#ports:
|
||||
# - 51056:9200
|
||||
# - 51057:9300
|
||||
ports:
|
||||
- "9200:9200"
|
||||
expose:
|
||||
- "9300"
|
||||
networks:
|
||||
open-dmp-elk-network:
|
||||
|
||||
logstash:
|
||||
# user: 1002:1002 #develuser
|
||||
volumes:
|
||||
- ./shared/config-elk/logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
|
||||
- ./shared/config-elk/logstash/config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
|
||||
- ./shared/config-elk/logstash/config/log4j2.properties:/usr/share/logstash/config/log4j2.properties:ro
|
||||
- ./shared/config-elk/logstash/pipeline:/usr/share/logstash/pipeline:ro
|
||||
- ./shared/config-elk/logstash/logstash/templates:/usr/share/logstash/templates
|
||||
- ./shared/data-elk/logstash-log:/usr/share/logstash/logs
|
||||
- ./shared/data-elk/logstash-queue:/usr/share/logstash/queue
|
||||
- ./shared/data-elk/logstash-dead_letter_queue:/usr/share/logstash/dead_letter_queue
|
||||
expose:
|
||||
- "31311"
|
||||
- "31312"
|
||||
restart: on-failure
|
||||
mem_limit: 2048m
|
||||
environment:
|
||||
- LS_JAVA_OPTS=-Xmx1024m -Xms1024m
|
||||
- xpack.license.self_generated.type=basic
|
||||
- xpack.security.enabled=true
|
||||
networks:
|
||||
open-dmp-elk-network:
|
||||
|
||||
kibana:
|
||||
# user: 1002:1002 #develuser
|
||||
mem_limit: 512m
|
||||
environment:
|
||||
- xpack.license.self_generated.type=basic
|
||||
- xpack.security.enabled=true
|
||||
|
||||
volumes:
|
||||
- ./shared/config-elk/kibana/config:/usr/share/kibana/config:ro
|
||||
#- ./shared/config-elk/kibana/certificates:/usr/share/kibana/certificates
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "51058:5601"
|
||||
networks:
|
||||
- open-dmp-elk-network
|
||||
|
||||
filebeat:
|
||||
restart: unless-stopped
|
||||
mem_limit: 256m
|
||||
#command: [ "-e=false" ] # to overwrite the -e that disables logging to file!
|
||||
volumes:
|
||||
- ./shared/config-elk/filebeat/config/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
|
||||
- ~/openDMP/logs:/usr/share/filebeat/log_data/dmp/
|
||||
- ./shared/data-elk/filebeat-log:/usr/share/filebeat/logs
|
||||
- ./shared/data-elk/filebeat-data:/usr/share/filebeat/data #For windows if we mount the data directory we get "Writing of registry returned error: sync /usr/share/filebeat/data/registry/filebeat: invalid argument."
|
||||
networks:
|
||||
- open-dmp-elk-network
|
||||
|
||||
networks:
|
||||
open-dmp-elk-network:
|
|
@ -1,43 +0,0 @@
|
|||
version: '2.4'
|
||||
|
||||
services:
|
||||
elasticsearch:
|
||||
image: ${DOCKER_REGISTRY}elasticsearch
|
||||
container_name: elasticsearch
|
||||
build:
|
||||
context: elasticsearch/
|
||||
args:
|
||||
ELK_VERSION: $ELK_VERSION
|
||||
healthcheck:
|
||||
# test: curl --cacert /usr/share/elasticsearch/config/certificates/ca/ca.crt -s https://localhost:9200 >/dev/null; if [[ $$? == 52 ]]; then echo 0; else echo 1; fi
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
|
||||
logstash:
|
||||
image: ${DOCKER_REGISTRY}logstash
|
||||
container_name: logstash
|
||||
build:
|
||||
context: logstash/
|
||||
args:
|
||||
ELK_VERSION: $ELK_VERSION
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
|
||||
kibana:
|
||||
image: ${DOCKER_REGISTRY}kibana
|
||||
build:
|
||||
context: kibana/
|
||||
args:
|
||||
ELK_VERSION: $ELK_VERSION
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
filebeat:
|
||||
image: ${DOCKER_REGISTRY}filebeat
|
||||
build:
|
||||
context: filebeat/
|
||||
args:
|
||||
ELK_VERSION: $ELK_VERSION
|
||||
depends_on:
|
||||
- logstash
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
ARG ELK_VERSION
|
||||
|
||||
# https://github.com/elastic/elasticsearch-docker
|
||||
FROM docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}
|
||||
|
||||
RUN /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-icu && \
|
||||
/usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-phonetic
|
||||
|
||||
RUN groupmod -g 1002 elasticsearch
|
||||
RUN usermod -u 1002 -g 1002 elasticsearch
|
||||
RUN chown -R elasticsearch /usr/share/elasticsearch
|
||||
RUN sed -i -e 's/--userspec=1000/--userspec=1002/g' \
|
||||
-e 's/UID 1000/UID 1002/' \
|
||||
-e 's/chown -R 1000/chown -R 1002/' /usr/local/bin/docker-entrypoint.sh
|
||||
RUN chown elasticsearch /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
ENV JAVA_HOME /usr/share/elasticsearch/jdk
|
||||
|
||||
# RUN mkdir /usr/share/elasticsearch/custom-plugins
|
||||
# COPY plugins/elasticsearch-analysis-greeklish-7.5.1.zip /usr/share/elasticsearch/custom-plugins/elasticsearch-analysis-greeklish-7.5.1.zip
|
||||
|
||||
# RUN /usr/share/elasticsearch/bin/elasticsearch-plugin install file:///usr/share/elasticsearch/custom-plugins/elasticsearch-analysis-greeklish-7.5.1.zip
|
|
@ -1,15 +0,0 @@
|
|||
ARG ELK_VERSION
|
||||
|
||||
FROM docker.elastic.co/beats/filebeat:${ELK_VERSION}
|
||||
|
||||
# USER root
|
||||
# RUN groupmod -g 1002 filebeat
|
||||
# RUN usermod -u 1002 -g 1002 filebeat
|
||||
# RUN chown -R filebeat /usr/share/filebeat
|
||||
# RUN sed -i -e 's/--userspec=1000/--userspec=1002/g' \
|
||||
# -e 's/UID 1000/UID 1002/' \
|
||||
# -e 's/chown -R 1000/chown -R 1002/' /usr/local/bin/docker-entrypoint
|
||||
# RUN chown filebeat /usr/local/bin/docker-entrypoint
|
||||
|
||||
# USER 1002:1002
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
ARG ELK_VERSION
|
||||
|
||||
# https://github.com/elastic/kibana-docker
|
||||
FROM docker.elastic.co/kibana/kibana:${ELK_VERSION}
|
||||
|
||||
# USER root
|
||||
# RUN groupmod -g 1002 kibana
|
||||
# RUN usermod -g 1002 root
|
||||
# RUN usermod -u 1002 -g 1002 kibana
|
||||
# RUN chown -R kibana /usr/share/kibana
|
||||
|
||||
# USER 1002:1002
|
||||
|
||||
# Add your kibana plugins setup here
|
||||
# Example: RUN kibana-plugin install <name|url>
|
|
@ -1,20 +0,0 @@
|
|||
ARG ELK_VERSION
|
||||
|
||||
# https://github.com/elastic/logstash-docker
|
||||
FROM docker.elastic.co/logstash/logstash:${ELK_VERSION}
|
||||
|
||||
# USER root
|
||||
# RUN groupmod -g 1002 logstash
|
||||
# RUN usermod -u 1002 -g 1002 logstash
|
||||
# RUN chown -R logstash /usr/share/logstash
|
||||
# RUN sed -i -e 's/--userspec=1000/--userspec=1002/g' \
|
||||
# -e 's/UID 1000/UID 1002/' \
|
||||
# -e 's/chown -R 1000/chown -R 1002/' /usr/local/bin/docker-entrypoint
|
||||
# RUN chown logstash /usr/local/bin/docker-entrypoint
|
||||
|
||||
# USER 1002:1002
|
||||
|
||||
# Add your logstash plugins setup here
|
||||
# Example: RUN logstash-plugin install logstash-filter-json
|
||||
RUN logstash-plugin update logstash-input-beats
|
||||
RUN logstash-plugin update logstash-filter-grok
|
|
@ -1,3 +0,0 @@
|
|||
TAG=6.3.1
|
||||
ELASTIC_VERSION=6.3.1
|
||||
ELASTIC_PASSWORD=changeme
|
|
@ -1 +0,0 @@
|
|||
**/*~
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
language: python
|
||||
python: ['3.5']
|
||||
script: make
|
||||
|
||||
sudo: required
|
||||
services: ['docker']
|
|
@ -1,201 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -1,30 +0,0 @@
|
|||
SHELL=/bin/bash
|
||||
|
||||
ifndef ELASTIC_VERSION
|
||||
ELASTIC_VERSION := $(shell awk 'BEGIN { FS = "[= ]" } /^ELASTIC_VERSION=/ { print $$2 }' .env)
|
||||
endif
|
||||
export ELASTIC_VERSION
|
||||
|
||||
ifndef GIT_BRANCH
|
||||
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
|
||||
endif
|
||||
|
||||
TARGETS := apm-server elasticsearch logstash kibana beats
|
||||
|
||||
images: $(TARGETS)
|
||||
push: $(TARGETS:%=%-push)
|
||||
clean: $(TARGETS:%=%-clean)
|
||||
|
||||
$(TARGETS): $(TARGETS:%=%-checkout)
|
||||
(cd stack/$@ && make)
|
||||
|
||||
$(TARGETS:%=%-push): $(TARGETS:%=%-checkout)
|
||||
(cd stack/$(@:%-push=%) && make push)
|
||||
|
||||
$(TARGETS:%=%-checkout):
|
||||
test -d stack/$(@:%-checkout=%) || \
|
||||
git clone https://github.com/elastic/$(@:%-checkout=%)-docker.git stack/$(@:%-checkout=%)
|
||||
(cd stack/$(@:%-checkout=%) && git fetch && git reset --hard && git checkout origin/$(GIT_BRANCH))
|
||||
|
||||
$(TARGETS:%=%-clean):
|
||||
rm -rf stack/$(@:%-clean=%)
|
|
@ -1,25 +0,0 @@
|
|||
# stack-docker
|
||||
This example Docker Compose configuration demonstrates many components of the
|
||||
Elastic Stack, all running on a single machine under Docker.
|
||||
|
||||
## Prerequisites
|
||||
- Docker and Compose. Windows and Mac users get Compose installed automatically
|
||||
with Docker. Linux users can:
|
||||
```
|
||||
pip install docker-compose
|
||||
```
|
||||
|
||||
- At least 4GiB of RAM for the containers. Windows and Mac users _must_
|
||||
configure their Docker virtual machine to have more than the default 2 GiB of
|
||||
RAM:
|
||||
|
||||
![Docker VM memory settings](screenshots/docker-vm-memory-settings.png)
|
||||
|
||||
## Starting the stack
|
||||
Try `docker-compose up` to create a demonstration Elastic Stack with
|
||||
Elasticsearch, Kibana, Logstash, Auditbeat, Metricbeat, Filebeat, Packetbeat,
|
||||
and Heartbeat.
|
||||
|
||||
Point a browser at [`http://localhost:5601`](http://localhost:5601) to see the results.
|
||||
|
||||
Log in with `elastic` / `changeme`.
|
|
@ -1,28 +0,0 @@
|
|||
input {
|
||||
http {
|
||||
port => 31311 # default: 8080
|
||||
}
|
||||
}
|
||||
|
||||
filter {
|
||||
grok{
|
||||
match => { "message" => "%{GREEDYDATA:request}"}
|
||||
}
|
||||
json{
|
||||
source => "request"
|
||||
target => "parsed"
|
||||
}
|
||||
split{
|
||||
field=>"entries"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
output {
|
||||
elasticsearch {
|
||||
hosts => [ 'elasticsearch' ]
|
||||
user => 'elastic'
|
||||
password => 'changeme'
|
||||
index => "data-management-plan-%{[entries][indexType]}-%{+YYYY.MM.dd}"
|
||||
}
|
||||
}
|
|
@ -1,171 +0,0 @@
|
|||
---
|
||||
version: '3'
|
||||
services:
|
||||
# The environment variable "TAG" is used throughout this file to
|
||||
# specify the version of the images to run. The default is set in the
|
||||
# '.env' file in this folder. It can be overridden with any normal
|
||||
# technique for setting environment variables, for example:
|
||||
#
|
||||
# TAG=6.0.0-beta1 docker-compose up
|
||||
#
|
||||
# REF: https://docs.docker.com/compose/compose-file/#variable-substitution
|
||||
#
|
||||
# Also be sure to set the ELASTIC_VERSION variable. For released versions,
|
||||
# ${TAG} and ${ELASTIC_VERSION} will be identical, but for pre-release
|
||||
# versions, ${TAG} might contain an extra build identifier, like
|
||||
# "6.0.0-beta1-3eab5b40", so a full invocation might look like:
|
||||
#
|
||||
# ELASTIC_VERSION=6.0.0-beta1 TAG=6.0.0-beta1-3eab5b40 docker-compose up
|
||||
#
|
||||
elasticsearch:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:${TAG}
|
||||
container_name: elasticsearch
|
||||
#volumes:
|
||||
# - esdata:/usr/share/elasticsearch/data
|
||||
environment: ['http.host=0.0.0.0', 'transport.host=127.0.0.1', 'ELASTIC_PASSWORD=${ELASTIC_PASSWORD}']
|
||||
ports: ['0.0.0.0:9200:9200']
|
||||
networks: ['stack']
|
||||
|
||||
kibana:
|
||||
image: docker.elastic.co/kibana/kibana:${TAG}
|
||||
container_name: kibana
|
||||
ports: ['0.0.0.0:5601:5601']
|
||||
networks: ['stack']
|
||||
depends_on: ['elasticsearch']
|
||||
|
||||
logstash:
|
||||
image: docker.elastic.co/logstash/logstash:${TAG}
|
||||
container_name: logstash
|
||||
# Provide a simple pipeline configuration for Logstash with a bind-mounted file.
|
||||
volumes:
|
||||
- ./config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
|
||||
ports: ['0.0.0.0:31311:31311']
|
||||
|
||||
networks: ['stack']
|
||||
depends_on: ['elasticsearch', 'setup_logstash']
|
||||
|
||||
filebeat:
|
||||
image: docker.elastic.co/beats/filebeat:${TAG}
|
||||
container_name: filebeat
|
||||
command: -e -E 'output.elasticsearch.password=${ELASTIC_PASSWORD}'
|
||||
# If the host system has logs at "/var/log", mount them at "/mnt/log"
|
||||
# inside the container, where Filebeat can find them.
|
||||
# volumes: ['/var/log:/mnt/log:ro']
|
||||
networks: ['stack']
|
||||
depends_on: ['elasticsearch', 'setup_filebeat']
|
||||
|
||||
heartbeat:
|
||||
image: docker.elastic.co/beats/heartbeat:${TAG}
|
||||
container_name: heartbeat
|
||||
command: -e -E 'output.elasticsearch.password=${ELASTIC_PASSWORD}'
|
||||
networks: ['stack']
|
||||
depends_on: ['elasticsearch', 'setup_heartbeat']
|
||||
|
||||
# Run a short-lived container to set up Logstash.
|
||||
setup_logstash:
|
||||
image: centos:7
|
||||
container_name: setup_logstash
|
||||
volumes: ['./scripts/setup-logstash.sh:/usr/local/bin/setup-logstash.sh:ro']
|
||||
# The script may have CR/LF line endings if using Docker for Windows, so
|
||||
# make sure that they don't confuse Bash.
|
||||
command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-logstash.sh | tr -d "\r" | bash']
|
||||
environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}']
|
||||
networks: ['stack']
|
||||
depends_on: ['elasticsearch']
|
||||
|
||||
setup_kibana:
|
||||
image: centos:7
|
||||
container_name: setup_kibana
|
||||
volumes: ['./scripts/setup-kibana.sh:/usr/local/bin/setup-kibana.sh:ro']
|
||||
command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-kibana.sh | tr -d "\r" | bash']
|
||||
environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}']
|
||||
networks: ['stack']
|
||||
depends_on: ['elasticsearch']
|
||||
|
||||
setup_filebeat:
|
||||
image: docker.elastic.co/beats/filebeat:${TAG}
|
||||
container_name: setup_filebeat
|
||||
volumes: ['./scripts/setup-beat.sh:/usr/local/bin/setup-beat.sh:ro']
|
||||
command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-beat.sh | tr -d "\r" | bash -s filebeat']
|
||||
environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}']
|
||||
networks: ['stack']
|
||||
depends_on: ['kibana']
|
||||
|
||||
setup_heartbeat:
|
||||
image: docker.elastic.co/beats/heartbeat:${TAG}
|
||||
container_name: setup_heartbeat
|
||||
volumes: ['./scripts/setup-beat.sh:/usr/local/bin/setup-beat.sh:ro']
|
||||
command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-beat.sh | tr -d "\r" | bash -s heartbeat']
|
||||
environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}']
|
||||
networks: ['stack']
|
||||
depends_on: ['kibana']
|
||||
|
||||
|
||||
##########################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
|
||||
redisdata:
|
||||
driver: local
|
||||
docsbox:
|
||||
driver: local
|
||||
media:
|
||||
driver: local
|
||||
networks: {stack: {}}
|
||||
|
Before Width: | Height: | Size: 46 KiB |
|
@ -1,18 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
beat=$1
|
||||
|
||||
until curl -s http://kibana:5601; do
|
||||
sleep 2
|
||||
done
|
||||
sleep 5
|
||||
|
||||
# Load the sample dashboards for the Beat.
|
||||
# REF: https://www.elastic.co/guide/en/beats/metricbeat/master/metricbeat-sample-dashboards.html
|
||||
${beat} setup \
|
||||
-E setup.kibana.host=kibana \
|
||||
-E setup.kibana.username=elastic \
|
||||
-E setup.kibana.password=${ELASTIC_PASSWORD} \
|
||||
-E output.elasticsearch.password=${ELASTIC_PASSWORD}
|
|
@ -1,10 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
es_url=http://elastic:${ELASTIC_PASSWORD}@elasticsearch:9200
|
||||
|
||||
# Wait for Elasticsearch to start up before doing anything.
|
||||
until curl -s $es_url -o /dev/null; do
|
||||
sleep 1
|
||||
done
|
|
@ -1,10 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
es_url=http://elastic:${ELASTIC_PASSWORD}@elasticsearch:9200
|
||||
|
||||
# Wait for Elasticsearch to start up before doing anything.
|
||||
until curl -s $es_url -o /dev/null; do
|
||||
sleep 1
|
||||
done
|
|
@ -1,2 +0,0 @@
|
|||
*
|
||||
!/.gitignore
|
|
@ -1,20 +0,0 @@
|
|||
---
|
||||
## Default Elasticsearch configuration from elasticsearch-docker.
|
||||
## from https://github.com/elastic/elasticsearch-docker/blob/master/build/elasticsearch/elasticsearch.yml
|
||||
#
|
||||
network.host: 0.0.0.0
|
||||
|
||||
# minimum_master_nodes need to be explicitly set when bound on a public IP
|
||||
# set to 1 to allow single node clusters
|
||||
# Details: https://github.com/elastic/elasticsearch/pull/17288
|
||||
# discovery.zen.minimum_master_nodes: 1
|
||||
|
||||
## Use single node discovery in order to disable production mode and avoid bootstrap checks
|
||||
## see https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
|
||||
#
|
||||
discovery.type: single-node
|
||||
## Search Guard
|
||||
#
|
||||
cluster.routing.allocation.disk.watermark.flood_stage: 99%
|
||||
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
#https://github.com/elastic/elasticsearch/blob/7.4/distribution/src/config/log4j2.properties
|
||||
|
||||
status = error
|
||||
|
||||
# log action execution errors for easier debugging
|
||||
logger.action.name = org.elasticsearch.action
|
||||
logger.action.level = debug
|
||||
|
||||
appender.console.type = Console
|
||||
appender.console.name = console
|
||||
appender.console.layout.type = PatternLayout
|
||||
appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] [%node_name]%marker %m%n
|
||||
|
||||
######## Server JSON ############################
|
||||
appender.rolling.type = RollingFile
|
||||
appender.rolling.name = rolling
|
||||
appender.rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_server.json
|
||||
appender.rolling.layout.type = ESJsonLayout
|
||||
appender.rolling.layout.type_name = server
|
||||
|
||||
appender.rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}-%d{yyyy-MM-dd}-%i.json.gz
|
||||
appender.rolling.policies.type = Policies
|
||||
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
|
||||
appender.rolling.policies.time.interval = 1
|
||||
appender.rolling.policies.time.modulate = true
|
||||
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.rolling.policies.size.size = 128MB
|
||||
appender.rolling.strategy.type = DefaultRolloverStrategy
|
||||
appender.rolling.strategy.fileIndex = nomax
|
||||
appender.rolling.strategy.action.type = Delete
|
||||
appender.rolling.strategy.action.basepath = ${sys:es.logs.base_path}
|
||||
appender.rolling.strategy.action.condition.type = IfFileName
|
||||
appender.rolling.strategy.action.condition.glob = ${sys:es.logs.cluster_name}-*
|
||||
appender.rolling.strategy.action.condition.nested_condition.type = IfAccumulatedFileSize
|
||||
appender.rolling.strategy.action.condition.nested_condition.exceeds = 2GB
|
||||
################################################
|
||||
######## Server - old style pattern ###########
|
||||
appender.rolling_old.type = RollingFile
|
||||
appender.rolling_old.name = rolling_old
|
||||
appender.rolling_old.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}.log
|
||||
appender.rolling_old.layout.type = PatternLayout
|
||||
appender.rolling_old.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] [%node_name]%marker %m%n
|
||||
|
||||
appender.rolling_old.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}-%d{yyyy-MM-dd}-%i.log.gz
|
||||
appender.rolling_old.policies.type = Policies
|
||||
appender.rolling_old.policies.time.type = TimeBasedTriggeringPolicy
|
||||
appender.rolling_old.policies.time.interval = 1
|
||||
appender.rolling_old.policies.time.modulate = true
|
||||
appender.rolling_old.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.rolling_old.policies.size.size = 128MB
|
||||
appender.rolling_old.strategy.type = DefaultRolloverStrategy
|
||||
appender.rolling_old.strategy.fileIndex = nomax
|
||||
appender.rolling_old.strategy.action.type = Delete
|
||||
appender.rolling_old.strategy.action.basepath = ${sys:es.logs.base_path}
|
||||
appender.rolling_old.strategy.action.condition.type = IfFileName
|
||||
appender.rolling_old.strategy.action.condition.glob = ${sys:es.logs.cluster_name}-*
|
||||
appender.rolling_old.strategy.action.condition.nested_condition.type = IfAccumulatedFileSize
|
||||
appender.rolling_old.strategy.action.condition.nested_condition.exceeds = 2GB
|
||||
################################################
|
||||
|
||||
rootLogger.level = info
|
||||
rootLogger.appenderRef.console.ref = console
|
||||
rootLogger.appenderRef.rolling.ref = rolling
|
||||
rootLogger.appenderRef.rolling_old.ref = rolling_old
|
||||
|
||||
######## Deprecation JSON #######################
|
||||
appender.deprecation_rolling.type = RollingFile
|
||||
appender.deprecation_rolling.name = deprecation_rolling
|
||||
appender.deprecation_rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_deprecation.json
|
||||
appender.deprecation_rolling.layout.type = ESJsonLayout
|
||||
appender.deprecation_rolling.layout.type_name = deprecation
|
||||
appender.deprecation_rolling.layout.esmessagefields=x-opaque-id
|
||||
|
||||
appender.deprecation_rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_deprecation-%i.json.gz
|
||||
appender.deprecation_rolling.policies.type = Policies
|
||||
appender.deprecation_rolling.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.deprecation_rolling.policies.size.size = 1GB
|
||||
appender.deprecation_rolling.strategy.type = DefaultRolloverStrategy
|
||||
appender.deprecation_rolling.strategy.max = 4
|
||||
#################################################
|
||||
######## Deprecation - old style pattern #######
|
||||
appender.deprecation_rolling_old.type = RollingFile
|
||||
appender.deprecation_rolling_old.name = deprecation_rolling_old
|
||||
appender.deprecation_rolling_old.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_deprecation.log
|
||||
appender.deprecation_rolling_old.layout.type = PatternLayout
|
||||
appender.deprecation_rolling_old.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] [%node_name]%marker %m%n
|
||||
|
||||
appender.deprecation_rolling_old.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}\
|
||||
_deprecation-%i.log.gz
|
||||
appender.deprecation_rolling_old.policies.type = Policies
|
||||
appender.deprecation_rolling_old.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.deprecation_rolling_old.policies.size.size = 1GB
|
||||
appender.deprecation_rolling_old.strategy.type = DefaultRolloverStrategy
|
||||
appender.deprecation_rolling_old.strategy.max = 4
|
||||
#################################################
|
||||
logger.deprecation.name = org.elasticsearch.deprecation
|
||||
logger.deprecation.level = warn
|
||||
logger.deprecation.appenderRef.deprecation_rolling.ref = deprecation_rolling
|
||||
logger.deprecation.appenderRef.deprecation_rolling_old.ref = deprecation_rolling_old
|
||||
logger.deprecation.additivity = false
|
||||
|
||||
######## Search slowlog JSON ####################
|
||||
appender.index_search_slowlog_rolling.type = RollingFile
|
||||
appender.index_search_slowlog_rolling.name = index_search_slowlog_rolling
|
||||
appender.index_search_slowlog_rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs\
|
||||
.cluster_name}_index_search_slowlog.json
|
||||
appender.index_search_slowlog_rolling.layout.type = ESJsonLayout
|
||||
appender.index_search_slowlog_rolling.layout.type_name = index_search_slowlog
|
||||
appender.index_search_slowlog_rolling.layout.esmessagefields=message,took,took_millis,total_hits,types,stats,search_type,total_shards,source,id
|
||||
|
||||
appender.index_search_slowlog_rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs\
|
||||
.cluster_name}_index_search_slowlog-%i.json.gz
|
||||
appender.index_search_slowlog_rolling.policies.type = Policies
|
||||
appender.index_search_slowlog_rolling.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.index_search_slowlog_rolling.policies.size.size = 1GB
|
||||
appender.index_search_slowlog_rolling.strategy.type = DefaultRolloverStrategy
|
||||
appender.index_search_slowlog_rolling.strategy.max = 4
|
||||
#################################################
|
||||
######## Search slowlog - old style pattern ####
|
||||
appender.index_search_slowlog_rolling_old.type = RollingFile
|
||||
appender.index_search_slowlog_rolling_old.name = index_search_slowlog_rolling_old
|
||||
appender.index_search_slowlog_rolling_old.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}\
|
||||
_index_search_slowlog.log
|
||||
appender.index_search_slowlog_rolling_old.layout.type = PatternLayout
|
||||
appender.index_search_slowlog_rolling_old.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] [%node_name]%marker %m%n
|
||||
|
||||
appender.index_search_slowlog_rolling_old.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}\
|
||||
_index_search_slowlog-%i.log.gz
|
||||
appender.index_search_slowlog_rolling_old.policies.type = Policies
|
||||
appender.index_search_slowlog_rolling_old.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.index_search_slowlog_rolling_old.policies.size.size = 1GB
|
||||
appender.index_search_slowlog_rolling_old.strategy.type = DefaultRolloverStrategy
|
||||
appender.index_search_slowlog_rolling_old.strategy.max = 4
|
||||
#################################################
|
||||
logger.index_search_slowlog_rolling.name = index.search.slowlog
|
||||
logger.index_search_slowlog_rolling.level = trace
|
||||
logger.index_search_slowlog_rolling.appenderRef.index_search_slowlog_rolling.ref = index_search_slowlog_rolling
|
||||
logger.index_search_slowlog_rolling.appenderRef.index_search_slowlog_rolling_old.ref = index_search_slowlog_rolling_old
|
||||
logger.index_search_slowlog_rolling.additivity = false
|
||||
|
||||
######## Indexing slowlog JSON ##################
|
||||
appender.index_indexing_slowlog_rolling.type = RollingFile
|
||||
appender.index_indexing_slowlog_rolling.name = index_indexing_slowlog_rolling
|
||||
appender.index_indexing_slowlog_rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}\
|
||||
_index_indexing_slowlog.json
|
||||
appender.index_indexing_slowlog_rolling.layout.type = ESJsonLayout
|
||||
appender.index_indexing_slowlog_rolling.layout.type_name = index_indexing_slowlog
|
||||
appender.index_indexing_slowlog_rolling.layout.esmessagefields=message,took,took_millis,doc_type,id,routing,source
|
||||
|
||||
appender.index_indexing_slowlog_rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}\
|
||||
_index_indexing_slowlog-%i.json.gz
|
||||
appender.index_indexing_slowlog_rolling.policies.type = Policies
|
||||
appender.index_indexing_slowlog_rolling.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.index_indexing_slowlog_rolling.policies.size.size = 1GB
|
||||
appender.index_indexing_slowlog_rolling.strategy.type = DefaultRolloverStrategy
|
||||
appender.index_indexing_slowlog_rolling.strategy.max = 4
|
||||
#################################################
|
||||
######## Indexing slowlog - old style pattern ##
|
||||
appender.index_indexing_slowlog_rolling_old.type = RollingFile
|
||||
appender.index_indexing_slowlog_rolling_old.name = index_indexing_slowlog_rolling_old
|
||||
appender.index_indexing_slowlog_rolling_old.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}\
|
||||
_index_indexing_slowlog.log
|
||||
appender.index_indexing_slowlog_rolling_old.layout.type = PatternLayout
|
||||
appender.index_indexing_slowlog_rolling_old.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] [%node_name]%marker %m%n
|
||||
|
||||
appender.index_indexing_slowlog_rolling_old.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}\
|
||||
_index_indexing_slowlog-%i.log.gz
|
||||
appender.index_indexing_slowlog_rolling_old.policies.type = Policies
|
||||
appender.index_indexing_slowlog_rolling_old.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.index_indexing_slowlog_rolling_old.policies.size.size = 1GB
|
||||
appender.index_indexing_slowlog_rolling_old.strategy.type = DefaultRolloverStrategy
|
||||
appender.index_indexing_slowlog_rolling_old.strategy.max = 4
|
||||
#################################################
|
||||
|
||||
logger.index_indexing_slowlog.name = index.indexing.slowlog.index
|
||||
logger.index_indexing_slowlog.level = trace
|
||||
logger.index_indexing_slowlog.appenderRef.index_indexing_slowlog_rolling.ref = index_indexing_slowlog_rolling
|
||||
logger.index_indexing_slowlog.appenderRef.index_indexing_slowlog_rolling_old.ref = index_indexing_slowlog_rolling_old
|
||||
logger.index_indexing_slowlog.additivity = false
|
|
@ -1,16 +0,0 @@
|
|||
#filebeat.registry_file: /usr/share/filebeat/registry
|
||||
filebeat.inputs:
|
||||
- type: log
|
||||
paths:
|
||||
- /usr/share/filebeat/log_data/dmp/openDMP*.log
|
||||
tags: ["audit"]
|
||||
enabled: true
|
||||
reload.enabled: true
|
||||
reload.period: 10s
|
||||
multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}'
|
||||
multiline.negate: true
|
||||
multiline.match: after
|
||||
|
||||
output.logstash:
|
||||
hosts: ["logstash:31312"]
|
||||
bulk_max_size: 128
|
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
## Default Kibana configuration from kibana-docker.
|
||||
## from https://github.com/elastic/kibana-docker/blob/master/build/kibana/config/kibana.yml
|
||||
#
|
||||
server.name: kibana
|
||||
server.host: "0"
|
||||
## Custom configuration
|
||||
#
|
||||
#server.basePath: "/eformslogs"
|
||||
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
|
||||
#elasticsearch.ssl.certificateAuthorities: [ "/usr/share/kibana/certificate_authorities/ca.crt" ]
|
||||
|
||||
elasticsearch.username: "kibana"
|
||||
elasticsearch.password: ""
|
||||
server.ssl.enabled: false
|
||||
#server.ssl.key: "/usr/share/kibana/certificates/kibana.key"
|
||||
#server.ssl.certificate: "/usr/share/kibana/certificates/kibana.crt"
|
|
@ -1,103 +0,0 @@
|
|||
#https://github.com/elastic/logstash/blob/7.4/config/log4j2.properties
|
||||
|
||||
status = error
|
||||
name = LogstashPropertiesConfig
|
||||
|
||||
appender.console.type = Console
|
||||
appender.console.name = plain_console
|
||||
appender.console.layout.type = PatternLayout
|
||||
appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c]%notEmpty{[%X{pipeline.id}]} %m%n
|
||||
|
||||
appender.json_console.type = Console
|
||||
appender.json_console.name = json_console
|
||||
appender.json_console.layout.type = JSONLayout
|
||||
appender.json_console.layout.compact = true
|
||||
appender.json_console.layout.eventEol = true
|
||||
|
||||
appender.rolling.type = RollingFile
|
||||
appender.rolling.name = plain_rolling
|
||||
appender.rolling.fileName = ${sys:ls.logs}/logstash-${sys:ls.log.format}.log
|
||||
appender.rolling.filePattern = ${sys:ls.logs}/logstash-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
|
||||
appender.rolling.policies.type = Policies
|
||||
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
|
||||
appender.rolling.policies.time.interval = 1
|
||||
appender.rolling.policies.time.modulate = true
|
||||
appender.rolling.layout.type = PatternLayout
|
||||
appender.rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c]%notEmpty{[%X{pipeline.id}]} %m%n
|
||||
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.rolling.policies.size.size = 100MB
|
||||
appender.rolling.strategy.type = DefaultRolloverStrategy
|
||||
appender.rolling.strategy.max = 30
|
||||
|
||||
appender.json_rolling.type = RollingFile
|
||||
appender.json_rolling.name = json_rolling
|
||||
appender.json_rolling.fileName = ${sys:ls.logs}/logstash-${sys:ls.log.format}.log
|
||||
appender.json_rolling.filePattern = ${sys:ls.logs}/logstash-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
|
||||
appender.json_rolling.policies.type = Policies
|
||||
appender.json_rolling.policies.time.type = TimeBasedTriggeringPolicy
|
||||
appender.json_rolling.policies.time.interval = 1
|
||||
appender.json_rolling.policies.time.modulate = true
|
||||
appender.json_rolling.layout.type = JSONLayout
|
||||
appender.json_rolling.layout.compact = true
|
||||
appender.json_rolling.layout.eventEol = true
|
||||
appender.json_rolling.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.json_rolling.policies.size.size = 100MB
|
||||
appender.json_rolling.strategy.type = DefaultRolloverStrategy
|
||||
appender.json_rolling.strategy.max = 30
|
||||
|
||||
rootLogger.level = ${sys:ls.log.level}
|
||||
rootLogger.appenderRef.console.ref = ${sys:ls.log.format}_console
|
||||
rootLogger.appenderRef.rolling.ref = ${sys:ls.log.format}_rolling
|
||||
|
||||
# Slowlog
|
||||
|
||||
appender.console_slowlog.type = Console
|
||||
appender.console_slowlog.name = plain_console_slowlog
|
||||
appender.console_slowlog.layout.type = PatternLayout
|
||||
appender.console_slowlog.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %m%n
|
||||
|
||||
appender.json_console_slowlog.type = Console
|
||||
appender.json_console_slowlog.name = json_console_slowlog
|
||||
appender.json_console_slowlog.layout.type = JSONLayout
|
||||
appender.json_console_slowlog.layout.compact = true
|
||||
appender.json_console_slowlog.layout.eventEol = true
|
||||
|
||||
appender.rolling_slowlog.type = RollingFile
|
||||
appender.rolling_slowlog.name = plain_rolling_slowlog
|
||||
appender.rolling_slowlog.fileName = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}.log
|
||||
appender.rolling_slowlog.filePattern = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
|
||||
appender.rolling_slowlog.policies.type = Policies
|
||||
appender.rolling_slowlog.policies.time.type = TimeBasedTriggeringPolicy
|
||||
appender.rolling_slowlog.policies.time.interval = 1
|
||||
appender.rolling_slowlog.policies.time.modulate = true
|
||||
appender.rolling_slowlog.layout.type = PatternLayout
|
||||
appender.rolling_slowlog.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %m%n
|
||||
appender.rolling_slowlog.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.rolling_slowlog.policies.size.size = 100MB
|
||||
appender.rolling_slowlog.strategy.type = DefaultRolloverStrategy
|
||||
appender.rolling_slowlog.strategy.max = 30
|
||||
|
||||
appender.json_rolling_slowlog.type = RollingFile
|
||||
appender.json_rolling_slowlog.name = json_rolling_slowlog
|
||||
appender.json_rolling_slowlog.fileName = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}.log
|
||||
appender.json_rolling_slowlog.filePattern = ${sys:ls.logs}/logstash-slowlog-${sys:ls.log.format}-%d{yyyy-MM-dd}-%i.log.gz
|
||||
appender.json_rolling_slowlog.policies.type = Policies
|
||||
appender.json_rolling_slowlog.policies.time.type = TimeBasedTriggeringPolicy
|
||||
appender.json_rolling_slowlog.policies.time.interval = 1
|
||||
appender.json_rolling_slowlog.policies.time.modulate = true
|
||||
appender.json_rolling_slowlog.layout.type = JSONLayout
|
||||
appender.json_rolling_slowlog.layout.compact = true
|
||||
appender.json_rolling_slowlog.layout.eventEol = true
|
||||
appender.json_rolling_slowlog.policies.size.type = SizeBasedTriggeringPolicy
|
||||
appender.json_rolling_slowlog.policies.size.size = 100MB
|
||||
appender.json_rolling_slowlog.strategy.type = DefaultRolloverStrategy
|
||||
appender.json_rolling_slowlog.strategy.max = 30
|
||||
|
||||
logger.slowlog.name = slowlog
|
||||
logger.slowlog.level = trace
|
||||
logger.slowlog.appenderRef.console_slowlog.ref = ${sys:ls.log.format}_console_slowlog
|
||||
logger.slowlog.appenderRef.rolling_slowlog.ref = ${sys:ls.log.format}_rolling_slowlog
|
||||
logger.slowlog.additivity = false
|
||||
|
||||
logger.licensereader.name = logstash.licensechecker.licensereader
|
||||
logger.licensereader.level = error
|
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
## Default Logstash configuration from logstash-docker.
|
||||
## from https://github.com/elastic/logstash-docker/blob/master/build/logstash/config/logstash-oss.yml
|
||||
#
|
||||
http.host: "0.0.0.0"
|
||||
config.reload.automatic: true
|
||||
config.reload.interval: 300s
|
||||
path.queue: /usr/share/logstash/queue
|
||||
path.dead_letter_queue: /usr/share/logstash/dead_letter_queue
|
||||
xpack.monitoring.elasticsearch.password:
|
|
@ -1,18 +0,0 @@
|
|||
- pipeline.id: open_dmp_beats
|
||||
queue.type: persisted
|
||||
queue.max_bytes: 50mb
|
||||
dead_letter_queue.enable: true
|
||||
path.config: "/usr/share/logstash/pipeline/open_dmp_beats.conf"
|
||||
queue.checkpoint.writes: 32
|
||||
- pipeline.id: open_dmp_main
|
||||
queue.type: persisted
|
||||
queue.max_bytes: 50mb
|
||||
dead_letter_queue.enable: true
|
||||
path.config: "/usr/share/logstash/pipeline/open_dmp_main.conf"
|
||||
queue.checkpoint.writes: 32
|
||||
- pipeline.id: open_dmp_send_to_elastic
|
||||
queue.type: persisted
|
||||
queue.max_bytes: 50mb
|
||||
dead_letter_queue.enable: true
|
||||
path.config: "/usr/share/logstash/pipeline/open_dmp_send_to_elastic.conf"
|
||||
queue.checkpoint.writes: 32
|
|
@ -1,14 +0,0 @@
|
|||
input {
|
||||
beats {
|
||||
port => 31312
|
||||
ssl => false
|
||||
client_inactivity_timeout => 3000
|
||||
}
|
||||
}
|
||||
|
||||
filter {
|
||||
}
|
||||
|
||||
output {
|
||||
pipeline { send_to => open_dmp_main }
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
input {
|
||||
pipeline { address => open_dmp_main }
|
||||
}
|
||||
|
||||
filter {
|
||||
grok {
|
||||
match => { "message" => "(?<timestamp>%{DATE} %{TIME})%{SPACE}%{LOGLEVEL:level} %{NUMBER:pid} --- \[%{DATA:thread}\] %{DATA:class}%{SPACE}: %{GREEDYDATA:logmessage}" }
|
||||
}
|
||||
if "_grokparsefailure" not in [tags] {
|
||||
mutate
|
||||
{
|
||||
remove_field => [ "message" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output {
|
||||
pipeline { send_to => open_dmp_send_to_elastic }
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
input {
|
||||
pipeline { address => open_dmp_send_to_elastic }
|
||||
}
|
||||
|
||||
filter {
|
||||
}
|
||||
|
||||
output {
|
||||
elasticsearch {
|
||||
hosts => "elasticsearch:9200"
|
||||
user => elastic
|
||||
password =>
|
||||
index =>"opendmp.logs"
|
||||
#manage_template => true
|
||||
#template => "/usr/share/logstash/templates/audit/openDMP.json"
|
||||
#template_name => "cite.elas.openDMP-audit*"
|
||||
#template_overwrite => true
|
||||
}
|
||||
}
|
|
@ -466,21 +466,6 @@ public class DmpServiceImpl implements DmpService {
|
|||
this.entityManager.persist(newReference);
|
||||
}
|
||||
|
||||
Map<UUID, UUID> dmpDescriptionTemplateRemap = new HashMap<>();
|
||||
for (DmpDescriptionTemplateEntity dmpDescriptionTemplate : dmpDescriptionTemplates) {
|
||||
DmpDescriptionTemplateEntity newTemplate = new DmpDescriptionTemplateEntity();
|
||||
newTemplate.setId(UUID.randomUUID());
|
||||
newTemplate.setDmpId(newDmp.getId());
|
||||
newTemplate.setDescriptionTemplateGroupId(dmpDescriptionTemplate.getDescriptionTemplateGroupId());
|
||||
newTemplate.setSectionId(dmpDescriptionTemplate.getSectionId());
|
||||
newTemplate.setCreatedAt(Instant.now());
|
||||
newTemplate.setUpdatedAt(Instant.now());
|
||||
newTemplate.setIsActive(IsActive.Active);
|
||||
dmpDescriptionTemplateRemap.put(dmpDescriptionTemplate.getId(), newTemplate.getId());
|
||||
|
||||
this.entityManager.persist(newTemplate);
|
||||
}
|
||||
|
||||
this.entityManager.flush();
|
||||
|
||||
if (model.getDescriptions() != null){
|
||||
|
@ -489,21 +474,47 @@ public class DmpServiceImpl implements DmpService {
|
|||
|
||||
org.opencdmp.commons.types.dmpblueprint.DefinitionEntity definition = this.xmlHandlingService.fromXmlSafe(org.opencdmp.commons.types.dmpblueprint.DefinitionEntity.class, blueprintEntity.getDefinition());
|
||||
|
||||
List<DmpDescriptionTemplateEntity> dmpDescriptionTemplateEntities = this.queryFactory.query(DmpDescriptionTemplateQuery.class).disableTracking().dmpIds(newDmp.getId()).isActive(IsActive.Active).collect();
|
||||
List<DescriptionEntity> descriptionEntities = this.queryFactory.query(DescriptionQuery.class).disableTracking().ids(model.getDescriptions().stream().map(NewVersionDmpDescriptionPersist::getDescriptionId).distinct().collect(Collectors.toList())).isActive(IsActive.Active).collect();
|
||||
|
||||
FieldSet fieldSet = new BaseFieldSet(Description._id, BaseFieldSet.asIndexer(Description._descriptionTemplate, DescriptionTemplate._groupId));
|
||||
List<Description> models = this.builderFactory.builder(DescriptionBuilder.class).authorize(AuthorizationFlags.AllExceptPublic).build(fieldSet, descriptionEntities);
|
||||
|
||||
|
||||
if (!this.conventionService.isListNullOrEmpty(models)){
|
||||
for (NewVersionDmpDescriptionPersist newVersionDmpDescriptionPersist : model.getDescriptions()) {
|
||||
Description description = models.stream().filter(x -> x.getId().equals(newVersionDmpDescriptionPersist.getDescriptionId())).findFirst().orElse(null);
|
||||
if (description != null){
|
||||
DmpDescriptionTemplateEntity existingDmpDescriptionTemplateEntity = this.queryFactory.query(DmpDescriptionTemplateQuery.class).disableTracking().dmpIds(newDmp.getId()).isActive(IsActive.Active).sectionIds(newVersionDmpDescriptionPersist.getBlueprintSectionId()).descriptionTemplateGroupIds(description.getDescriptionTemplate().getGroupId()).first();
|
||||
if (existingDmpDescriptionTemplateEntity == null){
|
||||
DmpDescriptionTemplateEntity newTemplate = new DmpDescriptionTemplateEntity();
|
||||
newTemplate.setId(UUID.randomUUID());
|
||||
newTemplate.setDmpId(newDmp.getId());
|
||||
newTemplate.setDescriptionTemplateGroupId(description.getDescriptionTemplate().getGroupId());
|
||||
newTemplate.setSectionId(newVersionDmpDescriptionPersist.getBlueprintSectionId());
|
||||
newTemplate.setCreatedAt(Instant.now());
|
||||
newTemplate.setUpdatedAt(Instant.now());
|
||||
newTemplate.setIsActive(IsActive.Active);
|
||||
this.entityManager.persist(newTemplate);
|
||||
this.entityManager.flush();
|
||||
this.cloneDescription(newDmp.getId(), null, newVersionDmpDescriptionPersist.getDescriptionId(), newTemplate.getId());
|
||||
} else{
|
||||
this.cloneDescription(newDmp.getId(), null, newVersionDmpDescriptionPersist.getDescriptionId(), existingDmpDescriptionTemplateEntity.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<DmpDescriptionTemplateEntity> newDmpDescriptionTemplateEntities = this.queryFactory.query(DmpDescriptionTemplateQuery.class).disableTracking().dmpIds(newDmp.getId()).isActive(IsActive.Active).collect();
|
||||
|
||||
if (!oldDmpEntity.getBlueprintId().equals(blueprintEntity.getId())){
|
||||
// add description templates if exists in new blueprint
|
||||
List<SectionEntity> sections = definition.getSections().stream().filter(SectionEntity::getHasTemplates).collect(Collectors.toList());
|
||||
if (!this.conventionService.isListNullOrEmpty(sections) && !this.conventionService.isListNullOrEmpty(dmpDescriptionTemplateEntities)){
|
||||
if (!this.conventionService.isListNullOrEmpty(sections) && !this.conventionService.isListNullOrEmpty(newDmpDescriptionTemplateEntities)){
|
||||
for (SectionEntity section: sections) {
|
||||
if (!this.conventionService.isListNullOrEmpty(section.getDescriptionTemplates())){
|
||||
for (DescriptionTemplateEntity blueprintDescriptionTemplate: section.getDescriptionTemplates()) {
|
||||
if (model.getDescriptions().stream().map(NewVersionDmpDescriptionPersist::getBlueprintSectionId).toList().contains(section.getId())){
|
||||
DmpDescriptionTemplateEntity existingBlueprintDescriptionTemplateEntity = dmpDescriptionTemplateEntities.stream().filter(x -> x.getSectionId().equals(section.getId()) && x.getDescriptionTemplateGroupId().equals(blueprintDescriptionTemplate.getDescriptionTemplateGroupId())).findFirst().orElse(null);
|
||||
DmpDescriptionTemplateEntity existingBlueprintDescriptionTemplateEntity = newDmpDescriptionTemplateEntities.stream().filter(x -> x.getSectionId().equals(section.getId()) && x.getDescriptionTemplateGroupId().equals(blueprintDescriptionTemplate.getDescriptionTemplateGroupId())).findFirst().orElse(null);
|
||||
if (existingBlueprintDescriptionTemplateEntity == null){
|
||||
DmpDescriptionTemplateEntity newTemplate = new DmpDescriptionTemplateEntity();
|
||||
newTemplate.setId(UUID.randomUUID());
|
||||
|
@ -521,28 +532,19 @@ public class DmpServiceImpl implements DmpService {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if (!this.conventionService.isListNullOrEmpty(dmpDescriptionTemplateEntities) && !this.conventionService.isListNullOrEmpty(models)){
|
||||
for (NewVersionDmpDescriptionPersist newVersionDmpDescriptionPersist : model.getDescriptions()) {
|
||||
Description description = models.stream().filter(x -> x.getId().equals(newVersionDmpDescriptionPersist.getDescriptionId())).findFirst().orElse(null);
|
||||
if (description != null){
|
||||
DmpDescriptionTemplateEntity existingDmpDescriptionTemplateEntity = dmpDescriptionTemplateEntities.stream().filter(x -> x.getSectionId().equals(newVersionDmpDescriptionPersist.getBlueprintSectionId()) && x.getDescriptionTemplateGroupId().equals(description.getDescriptionTemplate().getGroupId())).findFirst().orElse(null);
|
||||
if (existingDmpDescriptionTemplateEntity == null){
|
||||
DmpDescriptionTemplateEntity newTemplate = new DmpDescriptionTemplateEntity();
|
||||
newTemplate.setId(UUID.randomUUID());
|
||||
newTemplate.setDmpId(newDmp.getId());
|
||||
newTemplate.setDescriptionTemplateGroupId(description.getDescriptionTemplate().getGroupId());
|
||||
newTemplate.setSectionId(newVersionDmpDescriptionPersist.getBlueprintSectionId());
|
||||
newTemplate.setCreatedAt(Instant.now());
|
||||
newTemplate.setUpdatedAt(Instant.now());
|
||||
newTemplate.setIsActive(IsActive.Active);
|
||||
this.entityManager.persist(newTemplate);
|
||||
this.entityManager.flush();
|
||||
this.cloneDescription(newDmp.getId(), dmpDescriptionTemplateRemap, newVersionDmpDescriptionPersist.getDescriptionId(), newTemplate.getId());
|
||||
} else{
|
||||
this.cloneDescription(newDmp.getId(), dmpDescriptionTemplateRemap, newVersionDmpDescriptionPersist.getDescriptionId(), null);
|
||||
}
|
||||
for (DmpDescriptionTemplateEntity oldDmpDescriptionTemplate : dmpDescriptionTemplates) {
|
||||
if (newDmpDescriptionTemplateEntities.stream().filter(x -> x.getSectionId().equals(oldDmpDescriptionTemplate.getSectionId()) && x.getDescriptionTemplateGroupId().equals(oldDmpDescriptionTemplate.getDescriptionTemplateGroupId())).findFirst().orElse(null) == null){
|
||||
DmpDescriptionTemplateEntity newTemplate = new DmpDescriptionTemplateEntity();
|
||||
newTemplate.setId(UUID.randomUUID());
|
||||
newTemplate.setDmpId(newDmp.getId());
|
||||
newTemplate.setDescriptionTemplateGroupId(oldDmpDescriptionTemplate.getDescriptionTemplateGroupId());
|
||||
newTemplate.setSectionId(oldDmpDescriptionTemplate.getSectionId());
|
||||
newTemplate.setCreatedAt(Instant.now());
|
||||
newTemplate.setUpdatedAt(Instant.now());
|
||||
newTemplate.setIsActive(IsActive.Active);
|
||||
this.entityManager.persist(newTemplate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -577,7 +579,7 @@ public class DmpServiceImpl implements DmpService {
|
|||
newDescription.setStatus(DescriptionStatus.Draft);
|
||||
newDescription.setProperties(existing.getProperties());
|
||||
newDescription.setDmpId(dmpId);
|
||||
if (newDmpDescriptionTemplateId == null) newDescription.setDmpDescriptionTemplateId(dmpDescriptionTemplateRemap.get(existing.getDmpDescriptionTemplateId()));
|
||||
if (newDmpDescriptionTemplateId == null && dmpDescriptionTemplateRemap != null) newDescription.setDmpDescriptionTemplateId(dmpDescriptionTemplateRemap.get(existing.getDmpDescriptionTemplateId()));
|
||||
else newDescription.setDmpDescriptionTemplateId(newDmpDescriptionTemplateId);
|
||||
newDescription.setDescriptionTemplateId(existing.getDescriptionTemplateId());
|
||||
newDescription.setCreatedById(this.userScope.getUserId());
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="wrapper" *ngIf="!onlySplash && !showOnlyRouterOutlet">
|
||||
<div class="wrapper" *ngIf="!showOnlyRouterOutlet">
|
||||
<app-navbar (sidebarToggled)="sidenav.toggle(); toggleNavbar($event);"></app-navbar>
|
||||
<mat-sidenav-container fullscreen class="main-container">
|
||||
<mat-sidenav #sidenav mode="side" opened class="sidenav" [fixedInViewport]="true" [fixedTopGap]="80">
|
||||
|
@ -22,8 +22,8 @@
|
|||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<app-notification *ngIf="!onlySplash && !showOnlyRouterOutlet"></app-notification>
|
||||
<router-outlet *ngIf="onlySplash || showOnlyRouterOutlet"></router-outlet>
|
||||
<app-notification *ngIf="!showOnlyRouterOutlet"></app-notification>
|
||||
<router-outlet *ngIf="showOnlyRouterOutlet"></router-outlet>
|
||||
|
||||
<ngx-guided-tour *ngIf="!showOnlyRouterOutlet"
|
||||
[skipText]="'DASHBOARD.TOUR-GUIDE.LEAVE-TOUR'| translate"
|
||||
|
|
|
@ -1,31 +1,28 @@
|
|||
|
||||
import { of as observableOf, Subscription } from 'rxjs';
|
||||
|
||||
import { switchMap, filter, map, takeUntil } from 'rxjs/operators';
|
||||
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute, NavigationEnd, NavigationStart, Router } from '@angular/router';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { filter, map, switchMap } from 'rxjs/operators';
|
||||
import { AuthService, LoginStatus } from './core/services/auth/auth.service';
|
||||
import { CultureService } from './core/services/culture/culture-service';
|
||||
// import { BreadCrumbResolverService } from './ui/misc/breadcrumb/service/breadcrumb.service';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { NgcCookieConsentService, NgcStatusChangeEvent } from "ngx-cookieconsent";
|
||||
import { CookieService } from "ngx-cookie-service";
|
||||
import { LanguageService } from './core/services/language/language.service';
|
||||
import { NgcCookieConsentService, NgcStatusChangeEvent } from "ngx-cookieconsent";
|
||||
import { ConfigurationService } from './core/services/configuration/configuration.service';
|
||||
import { LanguageService } from './core/services/language/language.service';
|
||||
|
||||
import { Location } from '@angular/common';
|
||||
import { MatomoService } from './core/services/matomo/matomo-service';
|
||||
import { SideNavService } from './core/services/sidenav/side-nav.sevice';
|
||||
import { MatSidenav } from '@angular/material/sidenav';
|
||||
import { TimezoneService } from './core/services/timezone/timezone-service';
|
||||
import { TenantConfigurationService } from './core/services/tenant-configuration/tenant-configuration.service';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
import { TenantConfigurationType } from './core/common/enum/tenant-configuration-type';
|
||||
import { CssColorsTenantConfiguration, TenantConfiguration } from './core/model/tenant-configuaration/tenant-configuration';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
import { TenantHandlingService } from './core/services/tenant/tenant-handling.service';
|
||||
import { MatomoService } from './core/services/matomo/matomo-service';
|
||||
import { SideNavService } from './core/services/sidenav/side-nav.sevice';
|
||||
import { TenantConfigurationService } from './core/services/tenant-configuration/tenant-configuration.service';
|
||||
import { TimezoneService } from './core/services/timezone/timezone-service';
|
||||
import { BreadcrumbService } from './ui/misc/breadcrumb/breadcrumb.service';
|
||||
import { RouterUtilsService } from './core/services/router/router-utils.service';
|
||||
|
||||
|
||||
declare const gapi: any;
|
||||
|
@ -43,14 +40,12 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||
private sideNavSubscription: Subscription;
|
||||
helpContentEnabled: boolean;
|
||||
private statusChangeSubscription: Subscription;
|
||||
onlySplash = true;
|
||||
showOnlyRouterOutlet = false;
|
||||
|
||||
@ViewChild('sidenav') sidenav: MatSidenav;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private routerUtils: RouterUtilsService,
|
||||
private route: ActivatedRoute,
|
||||
private authentication: AuthService,
|
||||
private translate: TranslateService,
|
||||
|
@ -62,11 +57,9 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||
private ccService: NgcCookieConsentService,
|
||||
private language: LanguageService,
|
||||
private configurationService: ConfigurationService,
|
||||
private location: Location,
|
||||
private matomoService: MatomoService,
|
||||
private tenantConfigurationService: TenantConfigurationService,
|
||||
private sidenavService: SideNavService,
|
||||
private tenantHandlingService: TenantHandlingService,
|
||||
private breadcrumbService: BreadcrumbService
|
||||
) {
|
||||
this.initializeServices();
|
||||
|
@ -117,19 +110,6 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.location.path() === '') {
|
||||
if (!this.configurationService.useSplash) {
|
||||
this.onlySplash = false;
|
||||
this.router.navigate([this.routerUtils.generateUrl('/home')]);
|
||||
} else {
|
||||
this.onlySplash = true;
|
||||
this.router.navigate(['/reload']).then(() => this.router.navigate(['/splash']));
|
||||
}
|
||||
} else if (this.location.path() === '/splash') {
|
||||
this.onlySplash = true;
|
||||
} else {
|
||||
this.onlySplash = false;
|
||||
}
|
||||
if (!this.cookieService.check("cookiesConsent")) {
|
||||
// this.cookieService.set("cookiesConsent", "false", 356);
|
||||
this.cookieService.set("cookiesConsent", "false", 356, null, null, false, 'Lax');
|
||||
|
@ -190,12 +170,12 @@ export class AppComponent implements OnInit, AfterViewInit {
|
|||
filter(event => event instanceof NavigationEnd)
|
||||
)
|
||||
.subscribe((event: NavigationStart) => {
|
||||
|
||||
|
||||
this.breadcrumbService.addExcludedParam('t', true);
|
||||
|
||||
if (this.authentication.getSelectedTenantName() && this.authentication.getSelectedTenantName() !== '')
|
||||
this.breadcrumbService.addIdResolvedValue(this.authentication.selectedTenant(), this.authentication.getSelectedTenantName());
|
||||
|
||||
this.breadcrumbService.addIdResolvedValue(this.authentication.selectedTenant(), this.authentication.getSelectedTenantName());
|
||||
|
||||
// const enrichedUrl = this.tenantHandlingService.getUrlEnrichedWithTenantCode(event.url, this.authentication.selectedTenant() ?? 'default');
|
||||
// if (event.url != enrichedUrl) {
|
||||
// this.router.navigateByUrl(enrichedUrl);
|
||||
|
|
|
@ -69,11 +69,6 @@ export class ConfigurationService extends BaseComponent {
|
|||
return this._allowOrganizationCreator;
|
||||
}
|
||||
|
||||
private _useSplash: string;
|
||||
get useSplash(): string {
|
||||
return this._useSplash;
|
||||
}
|
||||
|
||||
private _orcidPath: string;
|
||||
get orcidPath(): string {
|
||||
return this._orcidPath;
|
||||
|
@ -228,7 +223,6 @@ export class ConfigurationService extends BaseComponent {
|
|||
this._lockInterval = config.lockInterval;
|
||||
this._guideAssets = config.guideAssets;
|
||||
this._allowOrganizationCreator = config.allowOrganizationCreator;
|
||||
this._useSplash = config.useSplash;
|
||||
this._orcidPath = config.orcidPath;
|
||||
if (config.matomo) {
|
||||
this._matomoEnabled = config.matomo.enabled;
|
||||
|
|
|
@ -8,7 +8,7 @@ import { LoggingService } from '@app/core/services/logging/logging-service';
|
|||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { ProgressIndicationService } from '@app/core/services/progress-indication/progress-indication-service';
|
||||
import { DescriptionEditorModel } from '@app/ui/description/editor/description-editor.model';
|
||||
import { DescriptionEditorResolver } from '@app/ui/description/editor/description-editor.resolver';
|
||||
import { DescriptionEditorEntityResolver } from '@app/ui/description/editor/resolvers/description-editor-entity.resolver';
|
||||
import { DescriptionFormService } from '@app/ui/description/editor/description-form/components/services/description-form.service';
|
||||
import { VisibilityRulesService } from '@app/ui/description/editor/description-form/visibility-rules/visibility-rules.service';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
|
@ -52,7 +52,7 @@ export class DescriptionTemplatePreviewDialogComponent extends BaseComponent imp
|
|||
|
||||
if (this.data && this.data.descriptionTemplateId) {
|
||||
|
||||
this.descriptionTemplateService.getSingle(this.data.descriptionTemplateId, DescriptionEditorResolver.descriptionTemplateLookupFields())
|
||||
this.descriptionTemplateService.getSingle(this.data.descriptionTemplateId, DescriptionEditorEntityResolver.descriptionTemplateLookupFields())
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(item => {
|
||||
this.descriptionTemplate = item;
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
</div>
|
||||
|
||||
|
||||
<mat-divider *ngIf="formGroup.get('id').value && (!viewOnly || (!isLocked && !viewOnly) || isLocked || (hasReversableStatus() && !isLocked))" [vertical]="true" class="ml-2 mr-2"></mat-divider>
|
||||
<mat-divider *ngIf="formGroup.get('id').value && canEdit && (!viewOnly || (!isLocked && canEdit && !viewOnly) || isLocked || (hasReversableStatus() && !isLocked))" [vertical]="true" class="ml-2 mr-2"></mat-divider>
|
||||
|
||||
<div *ngIf="!isPristine() && !viewOnly" class="col-auto d-flex align-items-center pr-0">
|
||||
<button [disabled]="saving" type="button" mat-raised-button class="description-discard-btn" (click)="discardChanges()">
|
||||
|
@ -50,7 +50,7 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="col-auto d-flex align-items-center">
|
||||
<button [disabled]="saving" *ngIf="!isLocked && !viewOnly && hasReversableStatus() == false" mat-raised-button class="description-save-btn mr-2" type="button">
|
||||
<button [disabled]="saving" *ngIf="canEdit && !isLocked && !viewOnly && hasReversableStatus() == false" mat-raised-button class="description-save-btn mr-2" type="button">
|
||||
<span class="d-flex flex-row row">
|
||||
<span (click)="!saving?formSubmit():null" class="col">{{ 'DESCRIPTION-EDITOR.ACTIONS.SAVE' | translate }}</span>
|
||||
<mat-divider [vertical]="true"></mat-divider>
|
||||
|
@ -66,7 +66,7 @@
|
|||
<button [disabled]="saving" mat-menu-item (click)="saveAndClose()" type="button">{{ 'DESCRIPTION-EDITOR.ACTIONS.SAVE-AND-CLOSE' | translate }}</button>
|
||||
<button [disabled]="saving" mat-menu-item (click)="saveAndContinue()" type="button">{{ 'DESCRIPTION-EDITOR.ACTIONS.SAVE-AND-CONTINUE' | translate }}</button>
|
||||
</mat-menu>
|
||||
<button [disabled]="saving" *ngIf="!isLocked && !viewOnly && hasReversableStatus() == false && canEdit" mat-raised-button class="description-save-btn mr-2" type="button" (click)="finalize()">{{ 'DESCRIPTION-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
|
||||
<button [disabled]="saving" *ngIf="canEdit && !isLocked && !viewOnly && hasReversableStatus() == false && canEdit" mat-raised-button class="description-save-btn mr-2" type="button" (click)="finalize()">{{ 'DESCRIPTION-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
|
||||
<button [disabled]="saving" *ngIf="isLocked" mat-raised-button disabled class="description-save-btn cursor-default" type="button">{{ 'DMP-OVERVIEW.LOCKED' | translate}}</button>
|
||||
<button [disabled]="saving" *ngIf="hasReversableStatus() && !isLocked && canEdit" mat-raised-button class="description-save-btn mr-2" (click)="reverse()" type="button">{{ 'DESCRIPTION-EDITOR.ACTIONS.REVERSE' | translate }}</button>
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@ import { IsActive } from '@app/core/common/enum/is-active.enum';
|
|||
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { DescriptionTemplate, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplatePage, DescriptionTemplateSection } from '@app/core/model/description-template/description-template';
|
||||
import { Description, DescriptionPersist, DescriptionSectionPermissionResolver, DescriptionStatusPersist } from '@app/core/model/description/description';
|
||||
import { Description, DescriptionPersist, DescriptionStatusPersist } from '@app/core/model/description/description';
|
||||
import { DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||
import { DmpDescriptionTemplate } from '@app/core/model/dmp/dmp';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
|
@ -21,10 +21,7 @@ import { FileTransformerService } from '@app/core/services/file-transformer/file
|
|||
import { LockService } from '@app/core/services/lock/lock.service';
|
||||
import { LoggingService } from '@app/core/services/logging/logging-service';
|
||||
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
|
||||
import {
|
||||
SnackBarNotificationLevel,
|
||||
UiNotificationService
|
||||
} from '@app/core/services/notification/ui-notification-service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
||||
import { VisibilityRulesService } from '@app/ui/description/editor/description-form/visibility-rules/visibility-rules.service';
|
||||
|
@ -39,7 +36,7 @@ import { TranslateService } from '@ngx-translate/core';
|
|||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { nameof } from 'ts-simple-nameof';
|
||||
import { DescriptionEditorModel, DescriptionFieldIndicator, DescriptionPropertyDefinitionEditorModel } from './description-editor.model';
|
||||
import { DescriptionEditorResolver } from './description-editor.resolver';
|
||||
import { DescriptionEditorEntityResolver } from './resolvers/description-editor-entity.resolver';
|
||||
import { DescriptionEditorService } from './description-editor.service';
|
||||
import { PrefillDescriptionDialogComponent } from './prefill-description/prefill-description.component';
|
||||
import { ToCEntry } from './table-of-contents/models/toc-entry';
|
||||
|
@ -78,6 +75,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
pageToFieldSetMap: Map<string, DescriptionFieldIndicator[]> = new Map<string, DescriptionFieldIndicator[]>();
|
||||
|
||||
private initialTemplateId: string = Guid.EMPTY;
|
||||
private permissionPerSection: Map<Guid, string[]>;
|
||||
|
||||
constructor(
|
||||
// BaseFormEditor injected dependencies
|
||||
|
@ -119,6 +117,10 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
|
||||
ngOnInit(): void {
|
||||
this.analyticsService.trackPageView(AnalyticsService.DescriptionEditor);
|
||||
|
||||
this.permissionPerSection = this.route.snapshot.data['permissions'] as Map<Guid, string[]> ?? new Map<Guid, string[]>();
|
||||
this.permissionPerSection = this.route.snapshot.data['permissions'] as Map<Guid, string[]> ?? new Map<Guid, string[]>();
|
||||
|
||||
super.ngOnInit();
|
||||
|
||||
|
||||
|
@ -177,11 +179,10 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
}, 0);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
getItem(itemId: Guid, successFunction: (item: Description) => void) {
|
||||
this.descriptionService.getSingle(itemId, DescriptionEditorResolver.lookupFields())
|
||||
this.descriptionService.getSingle(itemId, DescriptionEditorEntityResolver.lookupFields())
|
||||
.pipe(map(data => data as Description), takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
data => successFunction(data),
|
||||
|
@ -205,6 +206,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
this.buildForm();
|
||||
if (this.formGroup && this.editorModel.belongsToCurrentTenant == false) {
|
||||
this.formGroup.disable();
|
||||
this.canEdit = false;
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error('Could not parse Description item: ' + data + error);
|
||||
|
@ -213,34 +215,23 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
}
|
||||
|
||||
buildForm() {
|
||||
const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
|
||||
dmpId: this.item.dmp.id,
|
||||
sectionIds: [this.item.dmpDescriptionTemplate.sectionId],
|
||||
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.ReviewDescription]
|
||||
this.canEdit = this.permissionPerSection && this.permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && this.permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.EditDescription);
|
||||
this.canReview = this.permissionPerSection && this.permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && this.permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.ReviewDescription);
|
||||
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.canEdit, this.visibilityRulesService);
|
||||
if (this.item.descriptionTemplate?.definition) this.visibilityRulesService.setContext(this.item.descriptionTemplate.definition, this.formGroup.get('properties'));
|
||||
if (this.item.descriptionTemplate?.definition) this.pageToFieldSetMap = this.mapPageToFieldSet(this.item.descriptionTemplate);;
|
||||
|
||||
// this.selectedSystemFields = this.selectedSystemFieldDisabled();
|
||||
this.descriptionEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
|
||||
if (this.editorModel.status == DescriptionStatus.Finalized || this.isDeleted || !this.canEdit) {
|
||||
this.viewOnly = true;
|
||||
this.isFinalized = true;
|
||||
this.formGroup.disable();
|
||||
} else {
|
||||
this.viewOnly = false;
|
||||
}
|
||||
this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel)
|
||||
.pipe(takeUntil(this._destroyed)).subscribe(
|
||||
permissionPerSection => {
|
||||
this.canEdit = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.EditDescription);
|
||||
this.canReview = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.ReviewDescription);
|
||||
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.canEdit, this.visibilityRulesService);
|
||||
if (this.item.descriptionTemplate?.definition) this.visibilityRulesService.setContext(this.item.descriptionTemplate.definition, this.formGroup.get('properties'));
|
||||
if (this.item.descriptionTemplate?.definition) this.pageToFieldSetMap = this.mapPageToFieldSet(this.item.descriptionTemplate);;
|
||||
|
||||
// this.selectedSystemFields = this.selectedSystemFieldDisabled();
|
||||
this.descriptionEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
|
||||
if (this.editorModel.status == DescriptionStatus.Finalized || this.isDeleted || !this.canEdit) {
|
||||
this.viewOnly = true;
|
||||
this.isFinalized = true;
|
||||
this.formGroup.disable();
|
||||
} else {
|
||||
this.viewOnly = false;
|
||||
}
|
||||
|
||||
this.registerFormListeners();
|
||||
},
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
this.registerFormListeners();
|
||||
}
|
||||
|
||||
calculateMultiplicityRejectedDmpDescriptionTemplates(section: DmpBlueprintDefinitionSection, descriptions: Description[]): DmpDescriptionTemplate[] {
|
||||
|
@ -624,7 +615,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
descriptionTemplateValueChanged(descriptionTemplateId: Guid) {
|
||||
if (descriptionTemplateId != null) {
|
||||
|
||||
this.descriptionTemplateService.getSingle(descriptionTemplateId, DescriptionEditorResolver.descriptionTemplateLookupFields()).pipe(takeUntil(this._destroyed))
|
||||
this.descriptionTemplateService.getSingle(descriptionTemplateId, DescriptionEditorEntityResolver.descriptionTemplateLookupFields()).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(descriptionTemplate => {
|
||||
|
||||
this.initialTemplateId = descriptionTemplateId.toString();
|
||||
|
@ -752,7 +743,7 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
status: DescriptionStatus.Draft,
|
||||
hash: this.formGroup.get('hash').value
|
||||
};
|
||||
this.descriptionService.persistStatus(dmpUserRemovePersist, DescriptionEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed))
|
||||
this.descriptionService.persistStatus(dmpUserRemovePersist, DescriptionEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(data => {
|
||||
this.isFinalized = false;
|
||||
this.refreshData();
|
||||
|
|
|
@ -4,7 +4,8 @@ import { AuthGuard } from '@app/core/auth-guard.service';
|
|||
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
|
||||
import { PendingChangesGuard } from '@common/forms/pending-form-changes/pending-form-changes-guard.service';
|
||||
import { DescriptionEditorComponent } from './description-editor.component';
|
||||
import { DescriptionEditorResolver } from './description-editor.resolver';
|
||||
import { DescriptionEditorEntityResolver } from './resolvers/description-editor-entity.resolver';
|
||||
import { DescriptionEditorPermissionsResolver } from './resolvers/description-editor-permissions.resolver';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
|
@ -13,7 +14,8 @@ const routes: Routes = [
|
|||
component: DescriptionEditorComponent,
|
||||
canDeactivate: [PendingChangesGuard],
|
||||
resolve: {
|
||||
'entity': DescriptionEditorResolver
|
||||
'entity': DescriptionEditorEntityResolver,
|
||||
'permissions': DescriptionEditorPermissionsResolver,
|
||||
},
|
||||
data: {
|
||||
breadcrumbs: true,
|
||||
|
@ -28,7 +30,8 @@ const routes: Routes = [
|
|||
component: DescriptionEditorComponent,
|
||||
canDeactivate: [PendingChangesGuard],
|
||||
resolve: {
|
||||
'entity': DescriptionEditorResolver
|
||||
'entity': DescriptionEditorEntityResolver,
|
||||
'permissions': DescriptionEditorPermissionsResolver,
|
||||
},
|
||||
data: {
|
||||
breadcrumbs: true,
|
||||
|
@ -44,7 +47,8 @@ const routes: Routes = [
|
|||
component: DescriptionEditorComponent,
|
||||
canDeactivate: [PendingChangesGuard],
|
||||
resolve: {
|
||||
'entity': DescriptionEditorResolver
|
||||
'entity': DescriptionEditorEntityResolver,
|
||||
'permissions': DescriptionEditorPermissionsResolver,
|
||||
},
|
||||
data: {
|
||||
breadcrumbs: true,
|
||||
|
@ -59,7 +63,8 @@ const routes: Routes = [
|
|||
component: DescriptionEditorComponent,
|
||||
canDeactivate: [PendingChangesGuard],
|
||||
resolve: {
|
||||
'entity': DescriptionEditorResolver
|
||||
'entity': DescriptionEditorEntityResolver,
|
||||
'permissions': DescriptionEditorPermissionsResolver,
|
||||
},
|
||||
data: {
|
||||
breadcrumbs: true,
|
||||
|
@ -76,6 +81,6 @@ const routes: Routes = [
|
|||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
providers: [DescriptionEditorResolver]
|
||||
providers: [DescriptionEditorEntityResolver, DescriptionEditorPermissionsResolver]
|
||||
})
|
||||
export class DescriptionEditorRoutingModule { }
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
<!-- comment only on top level fieldset -->
|
||||
<div class="row">
|
||||
<div *ngIf="fieldSet.hasCommentField && propertiesFormGroup?.get('items')?.at(0)?.get('comment')" class="col-12">
|
||||
<rich-text-editor-component [form]="propertiesFormGroup?.get('items')?.at(0)?.get('comment')" [id]="'editor1'" [placeholder]="'DESCRIPTION-EDITOR.FIELDS.COMMENT-PLACEHOLDER' | translate" [wrapperClasses]="'mb-2'" [editable]="!propertiesFormGroup?.get('items')?.at(0)?.get('comment').disabled"></rich-text-editor-component>
|
||||
<rich-text-editor-component [form]="propertiesFormGroup?.get('items')?.at(0)?.get('comment')" [id]="'editor1'" [placeholder]="'DESCRIPTION-EDITOR.FIELDS.COMMENT-PLACEHOLDER' | translate" [wrapperClasses]="'mb-2'" [editable]="!propertiesFormGroup?.get('items')?.at(0)?.get('comment').disabled" [required]="isRequired"></rich-text-editor-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
|
||||
<div class="col-12">
|
||||
<mat-form-field *ngSwitchCase="descriptionTemplateFieldTypeEnum.TEXT_AREA" class="w-100">
|
||||
<mat-label>{{ field.data.label }}</mat-label>
|
||||
<mat-label>{{ field.data.label }}{{ isRequired ? '*' : ''}}</mat-label>
|
||||
<textarea matInput class="text-area" [formControl]="propertiesFormGroup?.get(field.id).get('textValue')" matTextareaAutosize matAutosizeMinRows="3" matAutosizeMaxRows="15"></textarea>
|
||||
<button mat-icon-button type="button" *ngIf="!propertiesFormGroup?.get(field.id).get('textValue').disabled && propertiesFormGroup?.get(field.id).get('textValue').value" matSuffix aria-label="Clear" (click)="this.propertiesFormGroup?.get(field.id).get('textValue').patchValue('')">
|
||||
<mat-icon>close</mat-icon>
|
||||
|
@ -120,7 +120,7 @@
|
|||
|
||||
<ng-container *ngSwitchCase="descriptionTemplateFieldTypeEnum.RICH_TEXT_AREA">
|
||||
<div class="col-12">
|
||||
<rich-text-editor-component [form]="propertiesFormGroup?.get(field.id).get('textValue')" [placeholder]="field.data.label" [wrapperClasses]="'full-width editor ' +
|
||||
<rich-text-editor-component [form]="propertiesFormGroup?.get(field.id).get('textValue')" [placeholder]="field.data.label" [required]="isRequired" [wrapperClasses]="'full-width editor ' +
|
||||
((isRequired && propertiesFormGroup?.get(field.id).get('textValue').touched && propertiesFormGroup?.get(field.id).get('textValue').hasError('required')) ? 'required' : '')" [editable]="!propertiesFormGroup?.get(field.id).get('textValue').disabled">
|
||||
</rich-text-editor-component>
|
||||
</div>
|
||||
|
@ -133,7 +133,7 @@
|
|||
</ng-container>
|
||||
<ng-container *ngSwitchCase="descriptionTemplateFieldTypeEnum.UPLOAD">
|
||||
<div class="col-12 d-flex justify-content-center">
|
||||
<ngx-dropzone #drop class="drop-file col-12" (change)="fileChangeEvent($event, true)" [multiple]="false" [accept]="typesToString()" [disabled]="propertiesFormGroup?.get(field.id).get('textValue').disabled">
|
||||
<ngx-dropzone #drop class="drop-file col-12" (change)="fileChangeEvent($event, true)" [multiple]="false" [accept]="typesToString()" [disabled]="propertiesFormGroup?.get(field.id).get('textValue').disabled" [class.drop-file-error]="propertiesFormGroup?.get(field.id).get('textValue').touched && propertiesFormGroup?.get(field.id).get('textValue').hasError('required')">
|
||||
<ngx-dropzone-preview *ngIf="propertiesFormGroup?.get(field.id).get('textValue').value" class="file-preview" [removable]="true" (removed)="onRemove()">
|
||||
<ngx-dropzone-label class="file-label">{{ fileNameDisplay }}</ngx-dropzone-label>
|
||||
</ngx-dropzone-preview>
|
||||
|
|
|
@ -66,6 +66,10 @@
|
|||
//max-width: 480px;
|
||||
height: 98px;
|
||||
margin-top: 0.5rem;
|
||||
|
||||
&.drop-file-error {
|
||||
border: 1px dashed #f44336;
|
||||
}
|
||||
}
|
||||
|
||||
.file-preview {
|
||||
|
|
|
@ -13,7 +13,7 @@ import { FormService } from "@common/forms/form-service";
|
|||
import { Guid } from "@common/types/guid";
|
||||
import { Observable } from "rxjs";
|
||||
import { takeUntil } from "rxjs/operators";
|
||||
import { DescriptionEditorResolver } from "../description-editor.resolver";
|
||||
import { DescriptionEditorEntityResolver } from "../resolvers/description-editor-entity.resolver";
|
||||
import { IsActive } from "@app/core/common/enum/is-active.enum";
|
||||
import { DescriptionPrefillingRequestEditorModel } from "./prefill-description-editor.model";
|
||||
import { HttpErrorHandlingService } from "@common/modules/errors/error-handling/http-error-handling.service";
|
||||
|
@ -89,7 +89,7 @@ export class PrefillDescriptionDialogComponent extends BaseComponent implements
|
|||
next() {
|
||||
const formData = this.formService.getValue(this.prefillForm.value) as DescriptionPrefillingRequest;
|
||||
|
||||
this.prefillingSourceService.generate(formData, DescriptionEditorResolver.descriptionTemplateLookupFieldsForDescrption())
|
||||
this.prefillingSourceService.generate(formData, DescriptionEditorEntityResolver.descriptionTemplateLookupFieldsForDescrption())
|
||||
.pipe(takeUntil(this._destroyed)).subscribe(description => {
|
||||
if (description) {
|
||||
this.closeDialog(description);
|
||||
|
|
|
@ -20,7 +20,7 @@ import { concatMap, map, takeUntil, tap } from 'rxjs/operators';
|
|||
import { nameof } from 'ts-simple-nameof';
|
||||
|
||||
@Injectable()
|
||||
export class DescriptionEditorResolver extends BaseEditorResolver {
|
||||
export class DescriptionEditorEntityResolver extends BaseEditorResolver {
|
||||
|
||||
constructor(
|
||||
private descriptionService: DescriptionService,
|
||||
|
@ -33,16 +33,16 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
|
|||
|
||||
public static lookupFields(): string[] {
|
||||
return [
|
||||
...DescriptionEditorResolver.descriptionLookupFields(),
|
||||
...DescriptionEditorResolver.dmpLookupFields(nameof<Description>(x => x.dmp)),
|
||||
...DescriptionEditorResolver.descriptionTemplateLookupFieldsForDescrption(),
|
||||
...DescriptionEditorEntityResolver.descriptionLookupFields(),
|
||||
...DescriptionEditorEntityResolver.dmpLookupFields(nameof<Description>(x => x.dmp)),
|
||||
...DescriptionEditorEntityResolver.descriptionTemplateLookupFieldsForDescrption(),
|
||||
]
|
||||
}
|
||||
|
||||
public static cloneLookupFields(): string[] {
|
||||
return [
|
||||
...DescriptionEditorResolver.descriptionLookupFields(),
|
||||
...DescriptionEditorResolver.descriptionTemplateLookupFieldsForDescrption(),
|
||||
...DescriptionEditorEntityResolver.descriptionLookupFields(),
|
||||
...DescriptionEditorEntityResolver.descriptionTemplateLookupFieldsForDescrption(),
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
|
|||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
|
||||
const fields = [
|
||||
...DescriptionEditorResolver.lookupFields()
|
||||
...DescriptionEditorEntityResolver.lookupFields()
|
||||
];
|
||||
const id = route.paramMap.get('id');
|
||||
const dmpId = route.paramMap.get('dmpId');
|
||||
|
@ -165,7 +165,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
|
|||
if (id != null && copyDmpId == null && dmpSectionId == null) {
|
||||
return this.descriptionService.getSingle(Guid.parse(id), fields).pipe(tap(d => this.breadcrumbService.addIdResolvedValue(d.id.toString(), d.label)));
|
||||
} else if (dmpId != null && dmpSectionId != null && copyDmpId == null) {
|
||||
return this.dmpService.getSingle(Guid.parse(dmpId), DescriptionEditorResolver.dmpLookupFields())
|
||||
return this.dmpService.getSingle(Guid.parse(dmpId), DescriptionEditorEntityResolver.dmpLookupFields())
|
||||
.pipe(tap(x => {
|
||||
this.breadcrumbService.addExcludedParam(dmpId, true);
|
||||
this.breadcrumbService.addIdResolvedValue(dmpSectionId, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW"));
|
||||
|
@ -178,8 +178,8 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
|
|||
return description;
|
||||
}));
|
||||
} else if (copyDmpId != null && id != null && dmpSectionId != null) {
|
||||
return this.dmpService.getSingle(Guid.parse(copyDmpId), DescriptionEditorResolver.dmpLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(dmp => {
|
||||
return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorResolver.cloneLookupFields())
|
||||
return this.dmpService.getSingle(Guid.parse(copyDmpId), DescriptionEditorEntityResolver.dmpLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(dmp => {
|
||||
return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorEntityResolver.cloneLookupFields())
|
||||
.pipe(tap(x => {
|
||||
this.breadcrumbService.addExcludedParam(copyDmpId, true)
|
||||
this.breadcrumbService.addExcludedParam(dmpSectionId, true)
|
|
@ -0,0 +1,99 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||
import { Description, DescriptionSectionPermissionResolver } from '@app/core/model/description/description';
|
||||
import { DescriptionService } from '@app/core/services/description/description.service';
|
||||
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
|
||||
import { BaseEditorResolver } from '@common/base/base-editor.resolver';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { concatMap, map, mergeMap, takeUntil, tap } from 'rxjs/operators';
|
||||
import { DescriptionEditorEntityResolver } from './description-editor-entity.resolver';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
|
||||
@Injectable()
|
||||
export class DescriptionEditorPermissionsResolver extends BaseEditorResolver {
|
||||
|
||||
constructor(
|
||||
private descriptionService: DescriptionService,
|
||||
private breadcrumbService: BreadcrumbService,
|
||||
private language: TranslateService,
|
||||
private dmpService: DmpService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
|
||||
const fields = [
|
||||
...DescriptionEditorEntityResolver.lookupFields()
|
||||
];
|
||||
const id = route.paramMap.get('id');
|
||||
const dmpId = route.paramMap.get('dmpId');
|
||||
const dmpSectionId = route.paramMap.get('dmpSectionId');
|
||||
const copyDmpId = route.paramMap.get('copyDmpId');
|
||||
// const cloneid = route.paramMap.get('cloneid');
|
||||
if (id != null && copyDmpId == null && dmpSectionId == null) {
|
||||
return this.descriptionService.getSingle(Guid.parse(id), fields).pipe(tap(d => this.breadcrumbService.addIdResolvedValue(d.id.toString(), d.label)))
|
||||
.pipe(mergeMap( description => {
|
||||
const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
|
||||
dmpId: description.dmp.id,
|
||||
sectionIds: [description.dmpDescriptionTemplate.sectionId],
|
||||
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.ReviewDescription]
|
||||
}
|
||||
return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed));
|
||||
}));
|
||||
|
||||
} else if (dmpId != null && dmpSectionId != null && copyDmpId == null) {
|
||||
return this.dmpService.getSingle(Guid.parse(dmpId), DescriptionEditorEntityResolver.dmpLookupFields())
|
||||
.pipe(tap(x => {
|
||||
this.breadcrumbService.addExcludedParam(dmpId, true);
|
||||
this.breadcrumbService.addIdResolvedValue(dmpSectionId, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW"));
|
||||
}), takeUntil(this._destroyed), map(dmp => {
|
||||
const description: Description = {};
|
||||
description.dmp = dmp;
|
||||
description.dmpDescriptionTemplate = {
|
||||
sectionId: Guid.parse(dmpSectionId)
|
||||
}
|
||||
return description;
|
||||
}))
|
||||
.pipe(mergeMap( description => {
|
||||
const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
|
||||
dmpId: description.dmp.id,
|
||||
sectionIds: [description.dmpDescriptionTemplate.sectionId],
|
||||
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.ReviewDescription]
|
||||
}
|
||||
return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed));
|
||||
}));
|
||||
} else if (copyDmpId != null && id != null && dmpSectionId != null) {
|
||||
return this.dmpService.getSingle(Guid.parse(copyDmpId), DescriptionEditorEntityResolver.dmpLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(dmp => {
|
||||
//TODO
|
||||
return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorEntityResolver.cloneLookupFields())
|
||||
.pipe(tap(x => {
|
||||
this.breadcrumbService.addExcludedParam(copyDmpId, true)
|
||||
this.breadcrumbService.addExcludedParam(dmpSectionId, true)
|
||||
this.breadcrumbService.addIdResolvedValue(id, x.label)
|
||||
}), takeUntil(this._destroyed), map(description => {
|
||||
|
||||
description.id = null;
|
||||
description.hash = null;
|
||||
description.status = DescriptionStatus.Draft;
|
||||
description.dmp = dmp;
|
||||
description.dmpDescriptionTemplate = {
|
||||
id: dmp.dmpDescriptionTemplates.filter(x => x.sectionId == Guid.parse(dmpSectionId) && x.descriptionTemplateGroupId == description.descriptionTemplate.groupId)[0].id,
|
||||
sectionId: Guid.parse(dmpSectionId)
|
||||
}
|
||||
return description;
|
||||
}));
|
||||
})).pipe(mergeMap( description => {
|
||||
const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
|
||||
dmpId: description.dmp.id,
|
||||
sectionIds: [description.dmpDescriptionTemplate.sectionId],
|
||||
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription, AppPermission.FinalizeDescription, AppPermission.ReviewDescription]
|
||||
}
|
||||
return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed));
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -299,7 +299,7 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit
|
|||
updateDataFn(filterForm: UntypedFormGroup): void {
|
||||
let testLookup = this.lookup;
|
||||
testLookup.from(filterForm);
|
||||
console.log('testLookup: ', testLookup);
|
||||
// console.log('testLookup: ', testLookup);
|
||||
// this.lookup.from(filterForm);
|
||||
// this.refresh(this.lookup);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import { BaseComponent } from '@common/base/base.component';
|
|||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { DmpCloneDialogEditorModel } from './dmp-clone-dialog.editor.model';
|
||||
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
|
||||
import { DmpEditorEntityResolver } from '../dmp-editor-blueprint/resolvers/dmp-editor-enitity.resolver';
|
||||
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
|
||||
|
@ -72,7 +72,7 @@ export class CloneDmpDialogComponent extends BaseComponent {
|
|||
confirm() {
|
||||
if (!this.formGroup.valid) { return; }
|
||||
const value: CloneDmpPersist = this.formGroup.value;
|
||||
this.dmpService.clone(value, DmpEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
|
||||
this.dmpService.clone(value, DmpEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
|
||||
dmp => this.dialogRef.close(dmp),
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
|
|
|
@ -10,19 +10,55 @@
|
|||
<div class="subtitle">{{ formGroup.get('label').value }} <span *ngIf="isDirty()" class="changes">({{'DMP-EDITOR.UNSAVED-CHANGES' | translate}})</span></div>
|
||||
</div>
|
||||
<div class="ml-auto d-flex flex-row">
|
||||
<div class="col-auto d-flex align-items-center">
|
||||
<button [disabled]="saving" *ngIf="isDirty()" type="button" mat-raised-button class="discard-btn mr-3" (click)="discardChanges()">
|
||||
|
||||
<div *ngIf="formGroup.get('id').value" class="col-auto d-flex align-items-center">
|
||||
<button [disabled]="isDirty()" [matTooltipDisabled]="!isDirty()" mat-raised-button class="dmp-export-btn" type="button" [matMenuTriggerFor]="exportMenu" (click)="$event.stopPropagation();" [matTooltip]="'DATASET-EDITOR.ACTIONS.DISABLED-EXPORT' | translate">
|
||||
{{ 'DMP-EDITOR.ACTIONS.EXPORT' | translate }}
|
||||
<mat-icon [disabled]="isDirty()" style="width: 14px;">expand_more</mat-icon>
|
||||
</button>
|
||||
<mat-menu #exportMenu="matMenu" xPosition="before">
|
||||
<button mat-menu-item *ngFor='let fileTransformer of fileTransformerService.availableFormatsFor(fileTransformerEntityTypeEnum.Dmp)' (click)="fileTransformerService.exportDmp(formGroup.get('id').value, fileTransformer.repositoryId, fileTransformer.format)">
|
||||
<i class="fa pr-2" [ngClass]="fileTransformer.icon ? fileTransformer.icon : 'fa-file-o'"></i>
|
||||
<span>{{'GENERAL.FILE-TRANSFORMER.' + fileTransformer?.format?.toUpperCase() | translate}}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<mat-divider *ngIf="formGroup.get('id').value && canEdit && ((!isLockedByUser && canEdit) || isLockedByUser || (hasReversableStatus() && !isLockedByUser))" [vertical]="true" class="ml-2 mr-2"></mat-divider>
|
||||
|
||||
<div *ngIf="isDirty()" class="col-auto d-flex align-items-center">
|
||||
<button [disabled]="saving" type="button" mat-raised-button class="discard-btn mr-3" (click)="discardChanges()">
|
||||
{{'DMP-EDITOR.ACTIONS.DISCARD.DISCARD' | translate}}
|
||||
</button>
|
||||
<button [disabled]="saving" *ngIf="isNew" mat-raised-button type="button" (click)="formSubmit()" class="save-btn">
|
||||
{{'DMP-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
<div *ngIf="!isNew && formGroup.enabled && !lockStatus && canSave">
|
||||
</div>
|
||||
|
||||
<div class="col-auto d-flex align-items-center">
|
||||
<!-- <ng-container *ngIf="formGroup.enabled && !lockStatus && canSave">
|
||||
<button [disabled]="saving" *ngIf="!isFinalized" mat-raised-button (click)="formSubmit()" class="save-btn">
|
||||
{{'DMP-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
<button *ngIf="lockStatus" mat-raised-button disabled class="description-save-btn cursor-default" type="button">{{ 'DMP-EDITOR.LOCKED' | translate}}</button>
|
||||
</ng-container> -->
|
||||
<button [disabled]="saving" *ngIf="isNew" mat-raised-button type="button" (click)="formSubmit()" class="save-btn">
|
||||
{{'DMP-EDITOR.ACTIONS.SAVE' | translate}}
|
||||
</button>
|
||||
<button [disabled]="saving" *ngIf="!isNew && formGroup.enabled && !lockStatus && canSave" mat-raised-button class="save-btn mr-2" type="button">
|
||||
<span class="d-flex flex-row row">
|
||||
<span (click)="!saving?formSubmit():null" class="col">{{ 'DMP-EDITOR.ACTIONS.SAVE' | translate }}</span>
|
||||
<mat-divider [vertical]="true"></mat-divider>
|
||||
<span *ngIf="!saving" class="align-items-center justify-content-center col d-flex" (click)="$event.stopPropagation();" [matMenuTriggerFor]="menu">
|
||||
<mat-icon>expand_more</mat-icon>
|
||||
</span>
|
||||
<span *ngIf="saving" class="align-items-center justify-content-center col d-flex">
|
||||
<mat-icon>expand_more</mat-icon>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button [disabled]="saving" mat-menu-item (click)="saveAndClose()" type="button">{{ 'DMP-EDITOR.ACTIONS.SAVE-AND-CLOSE' | translate }}</button>
|
||||
<button [disabled]="saving" mat-menu-item (click)="formSubmit()" type="button">{{ 'DMP-EDITOR.ACTIONS.SAVE-AND-CONTINUE' | translate }}</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<div *ngIf="formGroup.pristine && canFinalize" class="col-auto d-flex align-items-center">
|
||||
<button [disabled]="saving" mat-raised-button class="save-btn mr-2" type="button" (click)="finalize()">{{ 'DMP-EDITOR.ACTIONS.FINALIZE' | translate }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -65,12 +65,12 @@
|
|||
background: #ffffff 0% 0% no-repeat padding-box !important;
|
||||
border-radius: 30px;
|
||||
opacity: 1;
|
||||
width: 110px;
|
||||
width: auto;
|
||||
min-width: 110px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-weight: 700;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,9 +50,12 @@ import { TranslateService } from '@ngx-translate/core';
|
|||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { DmpContactPrefillDialogComponent } from '../dmp-contact-prefill-dialog/dmp-contact-prefill-dialog.component';
|
||||
import { DmpEditorModel, DmpFieldIndicator } from './dmp-editor.model';
|
||||
import { DmpEditorResolver } from './dmp-editor.resolver';
|
||||
import { DmpEditorEntityResolver } from './resolvers/dmp-editor-enitity.resolver';
|
||||
import { DmpEditorService } from './dmp-editor.service';
|
||||
import { RouterUtilsService } from '@app/core/services/router/router-utils.service';
|
||||
import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service';
|
||||
import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type';
|
||||
import { DmpFinalizeDialogComponent, DmpFinalizeDialogOutput } from '../dmp-finalize-dialog/dmp-finalize-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dmp-editor',
|
||||
|
@ -79,6 +82,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
dmpUserTypeEnum = DmpUserType;
|
||||
dmpUserTypeEnumValues = this.enumUtils.getEnumValues<DmpUserType>(DmpUserType);
|
||||
dmpUserRoleEnumValues = this.enumUtils.getEnumValues<DmpUserRole>(DmpUserRole);
|
||||
fileTransformerEntityTypeEnum = FileTransformerEntityType;
|
||||
|
||||
permissionPerSection: Map<Guid, string[]>;
|
||||
|
||||
|
@ -119,7 +123,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
}
|
||||
|
||||
protected get canFinalize(): boolean {
|
||||
return !this.isDeleted && !this.isFinalized && (this.hasPermission(this.authService.permissionEnum.EditDmp) || this.item?.authorizationFlags?.some(x => x === AppPermission.EditDmp));
|
||||
return !this.isDeleted && !this.isNew && this.canEdit && this.isLockedByUser && !this.isFinalized && this.item.status == DmpStatus.Draft && (this.hasPermission(this.authService.permissionEnum.EditDmp) || this.item?.authorizationFlags?.some(x => x === AppPermission.EditDmp));
|
||||
}
|
||||
|
||||
protected canEditSection(id: Guid): boolean {
|
||||
|
@ -169,7 +173,8 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
public descriptionService: DescriptionService,
|
||||
public titleService: Title,
|
||||
private analyticsService: AnalyticsService,
|
||||
private breadcrumbService: BreadcrumbService
|
||||
private breadcrumbService: BreadcrumbService,
|
||||
public fileTransformerService: FileTransformerService,
|
||||
) {
|
||||
const descriptionLabel: string = route.snapshot.data['entity']?.label;
|
||||
if (descriptionLabel) {
|
||||
|
@ -183,13 +188,13 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
ngOnInit(): void {
|
||||
this.analyticsService.trackPageView(AnalyticsService.DmpEditor);
|
||||
|
||||
this.permissionPerSection = this.route.snapshot.data['permissions'] as Map<Guid, string[]> ?? new Map<Guid, string[]>();
|
||||
super.ngOnInit();
|
||||
|
||||
if (this.isNew === false && this.step === 0) this.nextStep();
|
||||
}
|
||||
|
||||
getItem(itemId: Guid, successFunction: (item: Dmp) => void) {
|
||||
this.dmpService.getSingle(itemId, DmpEditorResolver.lookupFields())
|
||||
this.dmpService.getSingle(itemId, DmpEditorEntityResolver.lookupFields())
|
||||
.pipe(map(data => data as Dmp), takeUntil(this._destroyed))
|
||||
.subscribe(
|
||||
data => successFunction(data),
|
||||
|
@ -231,14 +236,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
sectionIds: data?.blueprint?.definition?.sections?.map(x => x.id),
|
||||
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription]
|
||||
}
|
||||
this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel)
|
||||
.pipe(takeUntil(this._destroyed)).subscribe(
|
||||
complete => {
|
||||
this.permissionPerSection = complete,
|
||||
this.buildForm();
|
||||
},
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
this.buildForm();
|
||||
} else {
|
||||
this.buildForm();
|
||||
}
|
||||
|
@ -315,9 +313,9 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
);
|
||||
}
|
||||
|
||||
formSubmit(): void {
|
||||
formSubmit(onSuccess?: (response) => void): void {
|
||||
this.formService.removeAllBackEndErrors(this.formGroup);
|
||||
this.persistEntity();
|
||||
this.persistEntity(onSuccess);
|
||||
}
|
||||
|
||||
discardChanges() {
|
||||
|
@ -355,7 +353,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
setTimeout(x => {
|
||||
if (this.isNew) this.step = 0;
|
||||
else this.step = this.step > 0 ? this.step - 1 : 0;
|
||||
this.ngOnInit();
|
||||
this.refreshOnNavigateToData();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -385,6 +383,39 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
}
|
||||
}
|
||||
|
||||
public saveAndClose(): void {
|
||||
this.formSubmit((data) => {
|
||||
this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
|
||||
this.formGroup = null;
|
||||
this.router.navigate([this.routerUtils.generateUrl('/plans/')]);
|
||||
});
|
||||
}
|
||||
|
||||
finalize() {
|
||||
const dialogRef = this.dialog.open(DmpFinalizeDialogComponent, {
|
||||
maxWidth: '500px',
|
||||
restoreFocus: false,
|
||||
autoFocus: false,
|
||||
data: {
|
||||
dmp: this.item
|
||||
}
|
||||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: DmpFinalizeDialogOutput) => {
|
||||
if (result && !result.cancelled) {
|
||||
|
||||
this.dmpService.finalize(this.item.id, result.descriptionsToBeFinalized)
|
||||
.pipe(takeUntil(this._destroyed))
|
||||
.subscribe(data => {
|
||||
this.onCallbackDeleteSuccess()
|
||||
this.router.navigate([this.routerUtils.generateUrl(['/plans/overview', this.item.id.toString()], '/')])
|
||||
}, (error: any) => {
|
||||
this.onCallbackError(error)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
clearErrorModel() {
|
||||
this.editorModel.validationErrorModel.clear();
|
||||
this.formService.validateAllFormFields(this.formGroup);
|
||||
|
@ -445,7 +476,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
//
|
||||
//
|
||||
selectBlueprint() {
|
||||
this.dmpBlueprintService.getSingle(this.formGroup.get('blueprint').value, DmpEditorResolver.blueprintLookupFields()).pipe(takeUntil(this._destroyed))
|
||||
this.dmpBlueprintService.getSingle(this.formGroup.get('blueprint').value, DmpEditorEntityResolver.blueprintLookupFields()).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(data => {
|
||||
this.selectedBlueprint = data;
|
||||
this.buildFormAfterBlueprintSelection();
|
||||
|
@ -455,7 +486,7 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
}
|
||||
|
||||
selectDefaultBlueprint(): void {
|
||||
this.dmpBlueprintService.getSingle(this.configurationService.defaultBlueprintId, DmpEditorResolver.blueprintLookupFields()).pipe(takeUntil(this._destroyed))
|
||||
this.dmpBlueprintService.getSingle(this.configurationService.defaultBlueprintId, DmpEditorEntityResolver.blueprintLookupFields()).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(data => {
|
||||
this.selectedBlueprint = data;
|
||||
this.formGroup.get('blueprint').setValue(this.selectedBlueprint.id);
|
||||
|
|
|
@ -5,9 +5,9 @@ import { AppPermission } from '@app/core/common/enum/permission.enum';
|
|||
import { PendingChangesGuard } from '@common/forms/pending-form-changes/pending-form-changes-guard.service';
|
||||
// import { DmpOverviewComponent } from './overview/description-overview.component';
|
||||
import { AuthGuard } from '@app/core/auth-guard.service';
|
||||
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
|
||||
import { DmpEditorComponent } from './dmp-editor.component';
|
||||
import { DmpEditorResolver } from './dmp-editor.resolver';
|
||||
import { DmpEditorEntityResolver } from './resolvers/dmp-editor-enitity.resolver';
|
||||
import { DmpEditorPermissionsResolver } from './resolvers/dmp-editor-permissions.resolver';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
|
@ -28,7 +28,8 @@ const routes: Routes = [
|
|||
component: DmpEditorComponent,
|
||||
canDeactivate: [PendingChangesGuard],
|
||||
resolve: {
|
||||
'entity': DmpEditorResolver
|
||||
'entity': DmpEditorEntityResolver,
|
||||
'permissions': DmpEditorPermissionsResolver
|
||||
},
|
||||
data: {
|
||||
breadcrumb: true,
|
||||
|
@ -42,6 +43,6 @@ const routes: Routes = [
|
|||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
providers: [DmpEditorResolver]
|
||||
providers: [DmpEditorEntityResolver, DmpEditorPermissionsResolver]
|
||||
})
|
||||
export class DmpEditorRoutingModule { }
|
||||
|
|
|
@ -16,7 +16,7 @@ import { takeUntil, tap } from 'rxjs/operators';
|
|||
import { nameof } from 'ts-simple-nameof';
|
||||
|
||||
@Injectable()
|
||||
export class DmpEditorResolver extends BaseEditorResolver {
|
||||
export class DmpEditorEntityResolver extends BaseEditorResolver {
|
||||
|
||||
constructor(private descriptionService: DmpService, private breadcrumbService: BreadcrumbService) {
|
||||
super();
|
||||
|
@ -85,7 +85,7 @@ export class DmpEditorResolver extends BaseEditorResolver {
|
|||
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
|
||||
|
||||
|
||||
...DmpEditorResolver.blueprintLookupFields(nameof<Dmp>(x => x.blueprint)),
|
||||
...DmpEditorEntityResolver.blueprintLookupFields(nameof<Dmp>(x => x.blueprint)),
|
||||
|
||||
]
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ export class DmpEditorResolver extends BaseEditorResolver {
|
|||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
|
||||
const fields = [
|
||||
...DmpEditorResolver.lookupFields()
|
||||
...DmpEditorEntityResolver.lookupFields()
|
||||
];
|
||||
const id = route.paramMap.get('id');
|
||||
if (id != null) {
|
|
@ -0,0 +1,44 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { DescriptionSectionPermissionResolver } from '@app/core/model/description/description';
|
||||
import { DescriptionService } from '@app/core/services/description/description.service';
|
||||
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
||||
import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service';
|
||||
import { BaseEditorResolver } from '@common/base/base-editor.resolver';
|
||||
import { Guid } from '@common/types/guid';
|
||||
import { mergeMap, takeUntil, tap } from 'rxjs/operators';
|
||||
import { DmpEditorEntityResolver } from './dmp-editor-enitity.resolver';
|
||||
|
||||
@Injectable()
|
||||
export class DmpEditorPermissionsResolver extends BaseEditorResolver {
|
||||
|
||||
constructor(private dmpService: DmpService,
|
||||
private breadcrumbService: BreadcrumbService,
|
||||
private descriptionService: DescriptionService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
|
||||
const fields = [
|
||||
...DmpEditorEntityResolver.lookupFields()
|
||||
];
|
||||
const id = route.paramMap.get('id');
|
||||
if (id != null) {
|
||||
return this.dmpService
|
||||
.getSingle(Guid.parse(id), fields)
|
||||
.pipe(tap(x => this.breadcrumbService.addIdResolvedValue(id, x.label)), takeUntil(this._destroyed))
|
||||
.pipe(mergeMap( data => {
|
||||
let descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
|
||||
dmpId: data.id,
|
||||
sectionIds: data?.blueprint?.definition?.sections?.map(x => x.id),
|
||||
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription]
|
||||
};
|
||||
return this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel).pipe(takeUntil(this._destroyed));
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -90,7 +90,7 @@
|
|||
<button mat-raised-button cdkFocusInitial (click)="close()" class="cancel-btn">{{ 'DMP-FINALISE-DIALOG.ACTIONS.CANCEL' | translate }}</button>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button mat-raised-button [disabled]="getFinalizedDescriptions().length === 0 && descriptionsToBeFinalized.length === 0" class="submit-btn" (click)="onSubmit()">{{ 'DMP-FINALISE-DIALOG.ACTIONS.SUBMIT' | translate }}</button>
|
||||
<button mat-raised-button [disabled]="!isDmpValid || getFinalizedDescriptions().length === 0 && descriptionsToBeFinalized.length === 0" class="submit-btn" (click)="onSubmit()">{{ 'DMP-FINALISE-DIALOG.ACTIONS.SUBMIT' | translate }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -318,7 +318,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit {
|
|||
updateDataFn(filterForm: UntypedFormGroup): void {
|
||||
let testLookup = this.lookup;
|
||||
testLookup.from(filterForm);
|
||||
console.log('testLookup: ', testLookup);
|
||||
// console.log('testLookup: ', testLookup);
|
||||
// this.lookup.from(filterForm);
|
||||
// this.refresh(this.lookup);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import { TranslateService } from '@ngx-translate/core';
|
|||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { DmpNewVersionDialogEditorModel } from './dmp-new-version-dialog.editor.model';
|
||||
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
|
||||
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
|
||||
import { DmpEditorEntityResolver } from '../dmp-editor-blueprint/resolvers/dmp-editor-enitity.resolver';
|
||||
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
||||
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||
import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status';
|
||||
|
@ -186,7 +186,7 @@ export class NewVersionDmpDialogComponent extends BaseComponent {
|
|||
if (formData.descriptions.length > 0){
|
||||
formData.descriptions = formData.descriptions.filter(x => x.blueprintSectionId != null)
|
||||
}
|
||||
this.dmpService.newVersion(formData, DmpEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
|
||||
this.dmpService.newVersion(formData, DmpEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed)).subscribe(
|
||||
dmp => this.dialogRef.close(dmp),
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
|
|
|
@ -28,10 +28,7 @@ import { DmpService } from '@app/core/services/dmp/dmp.service';
|
|||
import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service';
|
||||
import { LockService } from '@app/core/services/lock/lock.service';
|
||||
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
|
||||
import {
|
||||
SnackBarNotificationLevel,
|
||||
UiNotificationService
|
||||
} from '@app/core/services/notification/ui-notification-service';
|
||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
|
||||
import { ReferenceService } from '@app/core/services/reference/reference.service';
|
||||
import { UserService } from '@app/core/services/user/user.service';
|
||||
|
@ -48,7 +45,7 @@ import { map, takeUntil } from 'rxjs/operators';
|
|||
import { nameof } from 'ts-simple-nameof';
|
||||
import { CloneDmpDialogComponent } from '../clone-dialog/dmp-clone-dialog.component';
|
||||
import { DmpDeleteDialogComponent } from '../dmp-delete-dialog/dmp-delete-dialog.component';
|
||||
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
|
||||
import { DmpEditorEntityResolver } from '../dmp-editor-blueprint/resolvers/dmp-editor-enitity.resolver';
|
||||
import { DmpFinalizeDialogComponent, DmpFinalizeDialogOutput } from '../dmp-finalize-dialog/dmp-finalize-dialog.component';
|
||||
import { DmpInvitationDialogComponent } from '../invitation/dialog/dmp-invitation-dialog.component';
|
||||
import { NewVersionDmpDialogComponent } from '../new-version-dialog/dmp-new-version-dialog.component';
|
||||
|
@ -491,7 +488,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
|
|||
});
|
||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||
if (result) {
|
||||
this.dmpService.undoFinalize(this.dmp.id, DmpEditorResolver.lookupFields()).pipe(takeUntil(this._destroyed))
|
||||
this.dmpService.undoFinalize(this.dmp.id, DmpEditorEntityResolver.lookupFields()).pipe(takeUntil(this._destroyed))
|
||||
.subscribe(data => {
|
||||
this.reloadPage();
|
||||
this.onUpdateCallbackSuccess()
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { SplashComponent } from './splash.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: SplashComponent,
|
||||
data: {
|
||||
breadcrumb: true
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class SplashRoutingModule { }
|
|
@ -1,2 +0,0 @@
|
|||
<!-- <div id='splash' [innerHTML]="splashHTML"></div> -->
|
||||
<iframe id='splash' class="splash-wrapper" src="assets/splash/" (load)="resizeFrame()"></iframe>
|
|
@ -1,4 +0,0 @@
|
|||
.splash-wrapper {
|
||||
width: 100%;
|
||||
border: none;
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||
import { BaseComponent } from '@common/base/base.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-splash',
|
||||
templateUrl: './splash.component.html',
|
||||
styleUrls: ['./splash.component.scss']
|
||||
})
|
||||
export class SplashComponent extends BaseComponent implements OnInit {
|
||||
|
||||
splashHTML: any;
|
||||
|
||||
constructor(
|
||||
private httpClient: HttpClient,
|
||||
private configurationService: ConfigurationService,
|
||||
private sanitizer: DomSanitizer
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
}
|
||||
|
||||
resizeFrame() {
|
||||
const frame: HTMLIFrameElement = (document.getElementById('splash') as HTMLIFrameElement);
|
||||
frame.style.height = frame.contentWindow.document.body.scrollHeight + 'px';
|
||||
}
|
||||
|
||||
getSplashUrl() {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SplashComponent } from './splash.component';
|
||||
import { SplashRoutingModule } from './slash.routing';
|
||||
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [SplashComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
SplashRoutingModule
|
||||
]
|
||||
})
|
||||
export class SplashModule { }
|
|
@ -1695,7 +1695,11 @@
|
|||
"OR-CONTINUE-WITH": "or continue with",
|
||||
"REMOVE-CONTACT": "Remove Contact",
|
||||
"SEARCH-CONTACT": "Search Contact",
|
||||
"REMOVE-USER": "Remove User"
|
||||
"REMOVE-USER": "Remove User",
|
||||
"EXPORT": "Export",
|
||||
"SAVE-AND-CLOSE":"Save & Close",
|
||||
"SAVE-AND-CONTINUE": "Save & Continue",
|
||||
"FINALIZE": "Finalize"
|
||||
},
|
||||
"PLACEHOLDER": {
|
||||
"DESCRIPTION": "Fill with description",
|
||||
|
|
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 4.5 KiB |
|
@ -1,213 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Argos</title>
|
||||
<link rel="icon" type="image/x-icon" href="../assets/img/fav-icon.png">
|
||||
<!-- Font Awesome icons (free version)-->
|
||||
<script src="https://use.fontawesome.com/releases/v5.12.1/js/all.js" crossorigin="anonymous"></script>
|
||||
<!-- Google fonts-->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
|
||||
<!-- Core theme CSS -->
|
||||
<link href="../css/styles.css" rel="stylesheet">
|
||||
<link href="../css/navbar.css" rel="stylesheet">
|
||||
<link href="../css/footer.css" rel="stylesheet">
|
||||
<link href="../css/section.css" rel="stylesheet">
|
||||
<!-- Bootstrap -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||
</head>
|
||||
|
||||
<body id="page-top" class="bootstrap-overrides">
|
||||
<!-- Navbar -->
|
||||
<nav class="navbar navbar-expand-lg" id="nav">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="../index.html"><img src="../assets/img/argos-logo.svg"></a>
|
||||
<button class="collapse navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"><i class="fas fa-bars ml-1"></i></button>
|
||||
<div class="navbar-collapse" id="navbarResponsive">
|
||||
<ul class="navbar-nav text-uppercase ml-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link dropbtn active-nav-link" href="#about">ABOUT</a>
|
||||
<div id="aboutDropdown" class="dropdown-content">
|
||||
<div class="dropdown-top"></div>
|
||||
<div class="dropdown-options">
|
||||
<a href="how-it-works.html">How it works</a>
|
||||
<a href="https://trello.com/b/x49lylnK/argos" target="_blank">
|
||||
Roadmap
|
||||
<i class="fas fa-external-link-alt ext-link-icon"></i>
|
||||
</a>
|
||||
<a href="faqs.html">faqs</a>
|
||||
<a href="contributors.html">Contributors</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link dropbtn" href="#resources">RESOURCES</a>
|
||||
<div id="resourcesDropdown" class="dropdown-content">
|
||||
<div class="dropdown-top"></div>
|
||||
<div class="dropdown-options">
|
||||
<a href="../resources/media-kit.html">Media kit</a>
|
||||
<a href="../resources/user-guide.html">User Guide</a>
|
||||
<a href="../resources/co-branding.html">Co-branding</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item"><a class="nav-link" href="../contact.html">CONTACT</a></li>
|
||||
<li class="nav-item"><li class="nav-item"><a class="nav-link" href="/login">LOG IN</a></li></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- Translators -->
|
||||
<section class="page-section how-it-works" id="how-it-works">
|
||||
<div class="container-small">
|
||||
<div class="col">
|
||||
<div class="page-title">About</div>
|
||||
</div>
|
||||
<div class="col pt-5 pb-3">
|
||||
<div class="row title-4">Translators</div>
|
||||
</div>
|
||||
<div class="card mt-3 flex-row">
|
||||
<div class="col-4 d-flex justify-content-center align-items-center">
|
||||
<div class="flag-img-container">
|
||||
<img class="flag" alt="Flag of Greece" src="../assets/img/flag-of-greece.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8 card-body pl-0" class="flex-column align-items-center">
|
||||
<p class="card-text-1">Athena Research & Innovation Center</p>
|
||||
<p class="card-text-2">Dimitra Aglamisi, Elli Papadopoulou</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card flex-row">
|
||||
<div class="col-4 d-flex justify-content-center align-items-center">
|
||||
<div class="flag-img-container">
|
||||
<img class="card-img" alt="Flag of Spain" src="../assets/img/flag-of-spain.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8 card-body pl-0" class="flex-column align-items-center">
|
||||
<p class="card-text-1">Consorcio Madroño</p>
|
||||
<p class="card-text-2">Lanko López, Juan Corrales Correyero, Fernando González Ballesteros</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card flex-row">
|
||||
<div class="col-4 d-flex justify-content-center align-items-center">
|
||||
<div class="flag-img-container">
|
||||
<img class="card-img" alt="Flag of Turkey" src="../assets/img/flag-of-turkey.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8 card-body pl-0" class="flex-column align-items-center">
|
||||
<p class="card-text-1">Turkish Higher Education Council Research Data and Open Data working group</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card flex-row">
|
||||
<div class="col-4 d-flex justify-content-center align-items-center">
|
||||
<div class="flag-img-container">
|
||||
<img class="flag" alt="Flag of Austria" src="../assets/img/flag-of-austria.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8 card-body pl-0" class="flex-column align-items-center">
|
||||
<p class="card-text-1">UNIVERSITY OF VIENNA</p>
|
||||
<p class="card-text-2">Gerda McNeill, Raman Ganguly, Mihaela Hubert</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card flex-row">
|
||||
<div class="col-4 d-flex justify-content-center align-items-center">
|
||||
<div class="flag-img-container">
|
||||
<img class="flag" alt="Flag of Slovakia" src="../assets/img/flag-of-slovakia.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8 card-body pl-0" class="flex-column align-items-center">
|
||||
<p class="card-text-1">SLOVAK CENTRE FOR SCIENTIFIC AND TECHNICAL INFORMATION</p>
|
||||
<p class="card-text-2">Silvia Horáková, Richard Rac, Iryna Kuchma</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card flex-row">
|
||||
<div class="col-4 d-flex justify-content-center align-items-center">
|
||||
<div class="flag-img-container">
|
||||
<img class="flag" alt="Flag of Serbia" src="../assets/img/flag-of-serbia.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8 card-body pl-0" class="flex-column align-items-center">
|
||||
<p class="card-text-1">UNIVERSITY OF BELGRADE - SERBIA.RDM TEAM</p>
|
||||
<p class="card-text-2">Nadica Miljković, Milica Ševkušić, Ljiljana Lazarević, Biljana Kosanović, Vladimir Otašević, Obrad Vučkovac</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card flex-row">
|
||||
<div class="col-4 d-flex justify-content-center align-items-center">
|
||||
<div class="flag-img-container">
|
||||
<img class="flag" alt="Flag of Portugal" src="../assets/img/flag-of-portugal.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8 card-body pl-0" class="flex-column align-items-center">
|
||||
<p class="card-text-1">FCT-FCCN, University of Minho</p>
|
||||
<p class="card-text-2">Filipa Pereira, Carla Patinha, André Vieira, Paula Moura, Pedro Principe</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card flex-row">
|
||||
<div class="col-4 d-flex justify-content-center align-items-center">
|
||||
<div class="flag-img-container">
|
||||
<img class="flag" alt="Flag of Croatia" src="../assets/img/flag-of-croatia.jpg" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8 card-body pl-0" class="flex-column align-items-center">
|
||||
<p class="card-text-1">Centre For Scientific Information of the Ruđer Bošković Institute</p>
|
||||
<p class="card-text-2">Sanja Jurković, Lovorka Čaja and Alen Vodopijevec</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Footer-->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-auto">
|
||||
<img src="../assets/img/argos-logo - Copy.svg" width="98" height="37">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="footer-text">ARGOS receives funding from the European Union's Horizon 2020
|
||||
Research and Innovation programme under Grant Agreement No. 777541.</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<a href="https://www.openaire.eu/">
|
||||
<img src="../assets/img/Logo_Horizontal_white_small.png" width="126" height="30">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center pt-5">
|
||||
<div class="col d-flex justify-content-end">
|
||||
<a class="btn rounded-circle btn-social mx-1" href="https://www.facebook.com/groups/openaire/"><i class="fab fa-lg fa-facebook-f"></i></a>
|
||||
<a class="btn rounded-circle btn-social twitter mx-1" href="https://twitter.com/OpenAIRE_eu"><i class="fab fa-lg fa-twitter"></i></a>
|
||||
<a class="btn rounded-circle btn-social linkedin mx-1" href="https://www.linkedin.com/groups/3893548/"><i class="fab fa-lg fa-linkedin-in"></i></a>
|
||||
<a class="btn rounded-circle btn-social youtube mx-1" href="https://www.youtube.com/channel/UChFYqizc-S6asNjQSoWuwjw"><i class="fab fa-lg fa-youtube"></i></a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a class="btn mx-1" href="https://www.openaire.eu/newsletter/listing"><span class="newsletter">Newsletter</span><i class="fas fa-lg fa-wifi wifi-rotate"></i></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center pt-5">
|
||||
<a class="col-auto conditions-policy" href="/opensource-licences">Οpensource licences</a>
|
||||
<a class="col-auto conditions-policy" href="/terms-and-conditions">Terms and conditions</a>
|
||||
<a class="col-auto conditions-policy" href="/cookies-policy">Cookies policy</a>
|
||||
</div>
|
||||
<div class="row justify-content-center pt-5">
|
||||
<div class="col-auto"><img src="../assets/img/Cc.logo.circle.png" width="24" height="24"></div>
|
||||
<div class="col-auto pl-0"><img src="../assets/img/univ-access.png" width="24" height="24"></div>
|
||||
<div class="licence">Unless otherwise indicated, all materials created by OpenAIRE are licenced under
|
||||
</div>
|
||||
<div><u><a class="licence" href="https://creativecommons.org/licenses/by/4.0/">
|
||||
ATTRIBUTION 4.0 INTERNATIONAL LICENSE.
|
||||
<i class="fas fa-external-link-alt ext-link-icon"></i>
|
||||
</a></u></div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- Core theme JS-->
|
||||
<script src="../js/scripts.js"></script>
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,505 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Argos</title>
|
||||
<link rel="icon" type="image/x-icon" href="../assets/img/fav-icon.png">
|
||||
<!-- Font Awesome icons (free version)-->
|
||||
<script src="https://use.fontawesome.com/releases/v5.12.1/js/all.js" crossorigin="anonymous"></script>
|
||||
<!-- Google fonts-->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
|
||||
<!-- Core theme CSS -->
|
||||
<link href="../css/styles.css" rel="stylesheet">
|
||||
<link href="../css/navbar.css" rel="stylesheet">
|
||||
<link href="../css/footer.css" rel="stylesheet">
|
||||
<link href="../css/section.css" rel="stylesheet">
|
||||
<!-- Bootstrap -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||
</head>
|
||||
|
||||
<body id="page-top" class="bootstrap-overrides">
|
||||
<!-- Navbar -->
|
||||
<nav class="navbar navbar-expand-lg" id="nav">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="../index.html"><img src="../assets/img/argos-logo.svg"></a>
|
||||
<button class="collapse navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"><i class="fas fa-bars ml-1"></i></button>
|
||||
<div class="navbar-collapse" id="navbarResponsive">
|
||||
<ul class="navbar-nav text-uppercase ml-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link dropbtn active-nav-link" href="#about">ABOUT</a>
|
||||
<div id="aboutDropdown" class="dropdown-content">
|
||||
<div class="dropdown-top"></div>
|
||||
<div class="dropdown-options">
|
||||
<a href="how-it-works.html">How it works</a>
|
||||
<a href="https://trello.com/b/x49lylnK/argos" target="_blank">
|
||||
Roadmap
|
||||
<i class="fas fa-external-link-alt ext-link-icon"></i>
|
||||
</a>
|
||||
<a href="faqs.html">faqs</a>
|
||||
<a href="contributors.html">Contributors</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link dropbtn" href="#resources">RESOURCES</a>
|
||||
<div id="resourcesDropdown" class="dropdown-content">
|
||||
<div class="dropdown-top"></div>
|
||||
<div class="dropdown-options">
|
||||
<a href="../resources/media-kit.html">Media kit</a>
|
||||
<a href="../resources/user-guide.html">User Guide</a>
|
||||
<a href="../resources/co-branding.html">Co-branding</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item"><a class="nav-link" href="../contact.html">CONTACT</a></li>
|
||||
<li class="nav-item"><li class="nav-item"><a class="nav-link" href="/login">LOG IN</a></li></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<!-- How it works -->
|
||||
<section class="page-section how-it-works" id="how-it-works">
|
||||
<div class="container-small">
|
||||
<div class="col">
|
||||
<div class="page-title">About</div>
|
||||
</div>
|
||||
<div class="col pt-5 pb-3">
|
||||
<div class="row title-4">What it is</div>
|
||||
</div>
|
||||
<p class="pt-3">
|
||||
ARGOS is the joint effort of OpenAIRE and EUDAT to deliver an open platform for Data Management Planning
|
||||
that addresses FAIR and Open best practices and assumes no barriers for its use and adoption.
|
||||
</p>
|
||||
<p class="pt-2">
|
||||
It is an open extensible service - available as a standalone service (OpenDMP) and as a OpenAIRE service
|
||||
(ARGOS)
|
||||
- that simplifies the management, validation, monitoring and maintenance of Data Management Plans. It
|
||||
allows actors (researchers, managers, supervisors etc) to create actionable DMPs that may be freely
|
||||
exchanged among infrastructures for carrying out specific aspects of the Data management process in
|
||||
accordance with the intentions and commitment of Data owners.
|
||||
</p>
|
||||
<p class="pt-2">
|
||||
ARGOS is a service that is integrated within the OpenAIRE platform and is freely offered for use through
|
||||
the
|
||||
<a href="http://catalogue.openaire.eu/"><u>OpenAIRE Service Catalogue</u></a> and the EOSC Catalogue.
|
||||
ARGOS enhances the OpenAIRE
|
||||
Research Graph while at the same time utilises its
|
||||
underlying services, external sources and semantics to add value to the Dataset Description templates it
|
||||
produces thus increasing validation of DMPs. DMPs in ARGOS are treated as research outputs that can be
|
||||
assigned DOIs, licenses and can be re-distributed in a FAIR manner.
|
||||
</p>
|
||||
|
||||
<div class="text-box">
|
||||
<p>
|
||||
<b>The Name:</b> ARGOS is inspired by Greek mythology, both from
|
||||
<a href="https://en.wikipedia.org/wiki/Argus_Panoptes"><u>Argus Panoptes</u></a> the hundred-eyed
|
||||
giant and
|
||||
from <a href="https://en.wikipedia.org/wiki/Argus_(Argonaut)"><u>Argus (Argonaut)</u></a> builder of
|
||||
Argos ship, for the many-eyes monitoring sense and for the crafting
|
||||
and building for endurance concealing long-term goals.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="col pt-0 pb-3">
|
||||
<div class="row title-4">How it works</div>
|
||||
</div>
|
||||
|
||||
|
||||
<p class="pt-3">
|
||||
Research Data Management (RDM) is a vital part of Open Science that lies at the heart of European
|
||||
research for it increases the quality of produced data and ensures integrity and preservation of
|
||||
research outputs. RDM refers to activities undertaken throughout a research lifecycle, spanning from
|
||||
data collection to data process and analysis. Open Access and FAIR principles govern data activities
|
||||
today to foster data discovery, distribution and exploitation, thus accelerating scientific breakthroughs.
|
||||
Coronavirus vaccine is the ultimate example of what can be achieved in a short amount of time when
|
||||
data are openly shared across the global scientific community. RDM urges scientific practices to be
|
||||
adjusted in ways that enable data understandability and re-usability from both humans and machines;
|
||||
services and tools are realised or re-designed to support the shift towards Open and FAIR research outputs.
|
||||
</p>
|
||||
|
||||
<p class="pt-2">
|
||||
Argos is a service for creating and publishing plans that describe data management activities,
|
||||
commonly known as Data Management Plans (DMPs). The plans are produced as machine-actionable
|
||||
outputs (ma-DMPs), in the form of rich text documents, following Open and FAIR practices and are
|
||||
published in Zenodo. Argos supports RDM at the beginning of research for planning data activities to
|
||||
be performed, as well as throughout and at the end of research for documenting the steps and
|
||||
processes followed according to institutional or funder RDM requirements.
|
||||
</p>
|
||||
|
||||
<div class="col pt-5 pb-3">
|
||||
<div class="row title-5">Dmp Lifecycle</div>
|
||||
</div>
|
||||
|
||||
<p class="pt-2">
|
||||
Argos follows a full DMP publication lifecycle. Users create their DMPs and add descriptions for their
|
||||
datasets. DMPs and Datasets are created in private mode by default and can be shared with
|
||||
colleagues to facilitate the writing process. Datasets are added in DMPs per type and / or per scientific
|
||||
discipline that they concern. That way information is well-organized and it is easier to distinguish
|
||||
relevant information from a pool of data activities detailed in a single DMP record. Once created, DMPs
|
||||
and their Datasets are in draft status and are treated as living documents in the Argos environment,
|
||||
meaning that they can be versioned and updated at any time. When ready, users can validate and
|
||||
finalize their DMPs, including corresponding Datasets, and change their visibility status from private to
|
||||
open. Open DMPs in Argos are available and accessible to all from the Public Dashboards. To close the
|
||||
DMP lifecycle, Argos integrates Zenodo, so users are able to publish their DMPs directly from its environment.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<div class="container">
|
||||
|
||||
<div class="col-12" style="margin-top: 121px; ">
|
||||
|
||||
<div style="position: relative;" id="lifecycle-img-container">
|
||||
|
||||
<img id="img-coloured" class="image-coloured img-sharp" src="../assets/img/lifecycle_full_color.png" alt="Dmp Lifecycle">
|
||||
<img class="image-grey img-sharp" src="../assets/img/lifecycle_full_color.png" alt="Dmp Lifecycle">
|
||||
<!-- <img class="preface-img" src="../assets/img/lifecycle_full_color.png" alt=""> -->
|
||||
|
||||
<!-- EDITORS-DRAFT -->
|
||||
<div class="red-dot navigate-dot" data-navigate-to="multiple-navigation-1" data-clip-mode="clip-draft" style="top:24.7%; left: 23.5%; cursor: pointer;">
|
||||
<div class="inner-red-dot"></div>
|
||||
</div>
|
||||
<!-- VALIDATED -->
|
||||
<div class="red-dot navigate-dot" data-navigate-to="navigation-tab-2" data-clip-mode="clip-validated" style="top:19%; left: 56.5% ; cursor: pointer;">
|
||||
<div class="inner-red-dot"></div>
|
||||
</div>
|
||||
<!-- FINALIZED -->
|
||||
<div class="red-dot navigate-dot" data-navigate-to="navigation-tab-3" data-clip-mode="clip-finalized" style="top:39%; right: 19.7%; cursor: pointer;">
|
||||
<div class="inner-red-dot"></div>
|
||||
</div>
|
||||
<!-- DMP -->
|
||||
<div class="red-dot navigate-dot" data-navigate-to="navigation-tab-4" data-clip-mode="clip-dmp" style="top:67%; right: -0.3%; cursor: pointer;">
|
||||
<div class="inner-red-dot"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col-12" style="margin-top: 121px; ">
|
||||
<div class="options-menu" id="options-menu">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-7">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="tab" id="multiple-navigation-1" data-img-fragment href="#create_and_add">Create & Add</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" id="navigation-tab-2" data-img-fragment="img-fragment-validated-is" href="#validate">Validate</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" id="navigation-tab-3" data-img-fragment="img-fragment-finalized-is" href="#finalize">Finalize</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" id="navigation-tab-4" data-img-fragment="img-fragment-dmp-out" href="#dmp">Ma-Dmp Outputs</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane show active" id="create_and_add">
|
||||
<div class="nav-tab-inner-text">
|
||||
Argos consists of two main editors: the DMP editor and the Dataset editor.
|
||||
Both editors integrate OpenAIRE and ESOC APIs to ease the writing process and
|
||||
help create links with other outputs. Also, the editors incorporate a mechanism
|
||||
to enable compliance with the <a href="https://github.com/RDA-DMP-Common/RDA-DMP-Common-Standard" style="color: #23BCBA;">RDA DMP Common Standard</a>.
|
||||
</div>
|
||||
|
||||
<!-- nested naviation -->
|
||||
<ul class="nav nav-pills" style="padding-top: 2em;">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link sub-navigation-button active" data-toggle="tab" data-img-fragment="img-fragment-dmp-editor" href="#dmp_editor_pane">DMP Editor</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link sub-navigation-button" data-toggle="tab" data-img-fragment="img-fragment-dataset-editor" href="#dataset_editor_pane">Dataset Editor</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane show active" id="dmp_editor_pane">
|
||||
<div class="nav-tab-inner-text">
|
||||
The DMP editor embeds the Dataset editor to provide a holistic view of a project's
|
||||
scope, beneficiaries and data activities. Therefore, it guides users step-by-step
|
||||
into adding appropriate administrative information, selecting templates that
|
||||
correspond to research needs and requirements, and describing data activities.
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane fade" id="dataset_editor_pane">
|
||||
<div class="nav-tab-inner-text">
|
||||
The Dataset editor concerns information that is solely for datasets, such as how Open
|
||||
and FAIR principles have been applied to them throughout data management activities.
|
||||
It is the place to select RDM templates and start answering data questions. Moreover,
|
||||
the Dataset editor can be used independently at any time when new data are produced
|
||||
throughout a project lifetime. That allows users to quickly describe their new data and
|
||||
link them to existing DMPs in their dashboard.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane fade" id="validate">
|
||||
<div class="nav-tab-inner-text">
|
||||
Information contained in DMPs should be validated before being published.
|
||||
Validation at this stage checks for mandatory fields in the DMP and reports back
|
||||
when necessary information has not been provided by the user. Once the user
|
||||
adds all necessary information, validation is successful.
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane fade" id="finalize">
|
||||
<div class="nav-tab-inner-text">
|
||||
DMPs finalization is the process of locking working drafts of DMPs and publishing
|
||||
them, either just on the Argos platform or on Zenodo where they also get a DOI.
|
||||
It is possible for datasets contained in DMPs to be finalized independently. That
|
||||
is important especially for datasets that can not be shared openly, such as those
|
||||
of sensitive content. Before publishing DMPs, sensitive datasets can be detached
|
||||
from its core. That way data descriptions are equally protected form being openly
|
||||
shared along with the DMP content.
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane fade" id="dmp">
|
||||
<div class="nav-tab-inner-text">
|
||||
Argos ma-DMP outputs carry rich information that exceeds metadata provided in
|
||||
DMPs when they are created and deposited as plain texts. Argos applies the RDA
|
||||
DMP Common Standard to comply with global practices on the machine-actinability.
|
||||
This is important for two reasons:
|
||||
</div>
|
||||
|
||||
<div class="row pt-2 nav-tab-inner-text">
|
||||
<div class="col-auto" style="width:2.5em;color: #129D99;">I.</div>
|
||||
<div class="col">It enables researchers to switch platforms at any time and seamlessly work across
|
||||
different ma-DMP providers without losing vital information.
|
||||
</div>
|
||||
</div>
|
||||
<div class="row nav-tab-inner-text pt-4">
|
||||
<div class="col-auto " style="width:2.5em;color: #129D99;">II.</div>
|
||||
<div class="col">Adds to the Scholarly Communication ecology and pushes for best practices
|
||||
in neighbour areas to keep up pace, e.g. deposit in repositories and
|
||||
classification of DMPs as data management plans and not as publications, reports or other outputs.</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Images -->
|
||||
<div class="col" style="min-height: 20em;">
|
||||
<img src="../assets/img/3_dmp_editor.png" class="img-fragment-step opacity-1 img-sharp" id="img-fragment-dmp-editor" alt="DMP editor">
|
||||
<img src="../assets/img/dmp_out.png" class="img-fragment-step img-sharp" id="img-fragment-dmp-out" alt="DMP outputs">
|
||||
<img src="../assets/img/4_dataset_editor.png" class="img-fragment-step img-sharp" id="img-fragment-dataset-editor" alt="Dataset editor">
|
||||
<img src="../assets/img/6_validated_is.png" class="img-fragment-step img-sharp" id="img-fragment-validated-is" alt="Validated DMP">
|
||||
<img src="../assets/img/8_finalized_is.png" class="img-fragment-step img-sharp" id="img-fragment-finalized-is" alt="Finalized DMP">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-small" style="margin-top: 7em;">
|
||||
|
||||
<div class="col pt-5 pb-3" >
|
||||
<div class="row title-5">Argos in the OpenAIRE ecosystem</div>
|
||||
</div>
|
||||
|
||||
<p class="pt-2">
|
||||
Argos is hooked on the OpenAIRE ecosystem comprising a diverse set of services and tools for Open
|
||||
Science and Scholarly Communication, from technical to educational and consultative in nature.
|
||||
OpenAIRE services and tools are provided for immediate consumption by end-users, i.e. researchers,
|
||||
research communities, research performing or funding organizations and policymakers. Moreover,
|
||||
OpenAIRE services are exploitable by software engineers. Argos integrates other OpenAIRE services to
|
||||
maximise efficiency of operations in Open and FAIR ecosystems and to make connections that add
|
||||
value in Open Science at global scale. OpenAIRE services that Argos connects to are:
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="col" style="margin-top: 121px; position: relative;">
|
||||
<img src="../assets/img/openaire_ecosystem.png" style="width: 100%; height: auto;" alt="">
|
||||
|
||||
<!-- apis -->
|
||||
<div class="red-dot" style="top:8%; left: 22%"
|
||||
data-toggle="tooltip" data-placement="bottom"
|
||||
title='<h2>APIs</h2>
|
||||
Utilises OpenAIRE pool of resources
|
||||
and APIs to provide quick input to
|
||||
users (e.g. CORDIS, Datacite, re3data,
|
||||
ORCID, etc).'
|
||||
><div class="inner-red-dot"></div>
|
||||
</div>
|
||||
<!-- zenodo -->
|
||||
<div class="red-dot" style="top:10%; left: 54%"
|
||||
data-toggle="tooltip" data-placement="bottom"
|
||||
title='<h2>Zenodo</h2>
|
||||
Closes the DMP lifecycle by offering a
|
||||
DMP platform to expose DMP for
|
||||
their immediate publication in an
|
||||
open and FAIR manner (DMPs are
|
||||
assigned DOIs, get licenses, follow
|
||||
versioning mechanism etc).'
|
||||
><div class="inner-red-dot"></div>
|
||||
</div>
|
||||
<!-- provide -->
|
||||
<div class="red-dot" style="top:48.2%; left: 2.5%"
|
||||
data-toggle="tooltip" data-placement="bottom"
|
||||
title='<h2>Provide</h2>
|
||||
Sends notifications to repository
|
||||
managers of the OpenAIRE network
|
||||
when datasets described in Argos
|
||||
ma-DMPs are claimed to be
|
||||
deposited in their repositories.'
|
||||
><div class="inner-red-dot"></div>
|
||||
</div>
|
||||
<!-- monitor -->
|
||||
<div class="red-dot" style="top:60.2%; right: 2.5%"
|
||||
data-toggle="tooltip" data-placement="bottom"
|
||||
title="<h2>Monitor</h2>
|
||||
Collects contextualised information
|
||||
about ma-DMPs to understand how
|
||||
RDM and DMPs evolve in time and
|
||||
support decision making of funders
|
||||
and policymakers."
|
||||
>
|
||||
<div class="inner-red-dot"></div>
|
||||
</div>
|
||||
<!-- graph -->
|
||||
<div class="red-dot" style="bottom:14.2%; left: 40.5%"
|
||||
data-toggle="tooltip" data-placement="bottom"
|
||||
title='<h2>Research Graph</h2>
|
||||
Enriches the ma-DMP entity in the
|
||||
OpenAIRE knowledge graph for open
|
||||
scholarly communication information
|
||||
and creates relationships with other
|
||||
research outputs and links, adding in
|
||||
the OpenAIRE LOD ecology.'
|
||||
>
|
||||
<div class="inner-red-dot"></div>
|
||||
</div>
|
||||
<!-- explore -->
|
||||
<div class="red-dot" style="bottom:1%; left: 56%" data-toggle="tooltip" data-placement="bottom"
|
||||
title='
|
||||
<h2>Explore</h2>
|
||||
Adds ma-DMPs in the OpenAIRE
|
||||
search engine and makes them
|
||||
findable under a dedicated resource
|
||||
type category "data managment
|
||||
plan".'>
|
||||
<div class="inner-red-dot"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-small">
|
||||
|
||||
<p class="mt-3 pt-4" style="font-weight: bolder;" >Useful Resources</p>
|
||||
<div class="resources-list">
|
||||
<div class="row">
|
||||
<div class="col-auto" style="padding-top: .5em;">
|
||||
<div class="blue-dot"></div>
|
||||
</div>
|
||||
<div class="col p-0">
|
||||
Argos RDA output adoption:
|
||||
<br>
|
||||
<a href="https://www.rd-alliance.org/implementing-dmp-common-standard-argos-tool-madmps">
|
||||
https://www.rd-alliance.org/implementing-dmp-common-standard-argos-tool-madmps
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-auto" style="padding-top: .5em;">
|
||||
<div class="blue-dot"></div>
|
||||
</div>
|
||||
<div class="col p-0">
|
||||
Paper in the DaMaLOS conference:
|
||||
<br>
|
||||
<a href="https://repository.publisso.de/resource/frl:6423283">
|
||||
https://repository.publisso.de/resource/frl:6423283
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" >
|
||||
<div class="col-auto" style="padding-top: .5em;">
|
||||
<div class="blue-dot"></div>
|
||||
</div>
|
||||
<div class="col p-0">
|
||||
Webinar:
|
||||
<br>
|
||||
<a href="https://www.rd-alliance.org/implementing-dmp-common-standard-argos-tool-madmps">
|
||||
https://www.rd-alliance.org/implementing-dmp-common-standard-argos-tool-madmps
|
||||
</a>
|
||||
(starts at 30:15)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<p class="pt-2">
|
||||
More details on ARGOS as registered in the OpenAIRE services catalogue is available here:
|
||||
<a href="http://catalogue.openaire.eu/service/openaire.argos"><u>http://catalogue.openaire.eu/service/openaire.argos</u></a>.
|
||||
ARGOS as a Data Management
|
||||
Planning tool within
|
||||
EOSC can be explored in the EOSC catalogue of services here:
|
||||
<a href="https://catalogue.eosc-portal.eu/service/openaire.argos"><u>https://catalogue.eosc-portal.eu/service/openaire.argos</u></a>
|
||||
</p>
|
||||
<p class="pt-2 pb-5">
|
||||
ARGOS is offered as a standalone service, where
|
||||
users can download the source code and co-brand it. Read more on how to implement that in the
|
||||
<a href="../resources/co-branding.html"><u>Resources section</u></a>.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Footer-->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-auto">
|
||||
<img src="../assets/img/argos-logo - Copy.svg" width="98" height="37">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="footer-text">ARGOS receives funding from the European Union's Horizon 2020
|
||||
Research and Innovation programme under Grant Agreement No. 777541.</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<a href="https://www.openaire.eu/">
|
||||
<img src="../assets/img/Logo_Horizontal_white_small.png" width="126" height="30">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center pt-5">
|
||||
<div class="col d-flex justify-content-end">
|
||||
<a class="btn rounded-circle btn-social mx-1" href="https://www.facebook.com/groups/openaire/"><i class="fab fa-lg fa-facebook-f"></i></a>
|
||||
<a class="btn rounded-circle btn-social twitter mx-1" href="https://twitter.com/OpenAIRE_eu"><i class="fab fa-lg fa-twitter"></i></a>
|
||||
<a class="btn rounded-circle btn-social linkedin mx-1" href="https://www.linkedin.com/groups/3893548/"><i class="fab fa-lg fa-linkedin-in"></i></a>
|
||||
<a class="btn rounded-circle btn-social youtube mx-1" href="https://www.youtube.com/channel/UChFYqizc-S6asNjQSoWuwjw"><i class="fab fa-lg fa-youtube"></i></a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a class="btn mx-1" href="https://www.openaire.eu/newsletter/listing"><span class="newsletter">Newsletter</span><i class="fas fa-lg fa-wifi wifi-rotate"></i></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center pt-5">
|
||||
<a class="col-auto conditions-policy" href="/opensource-licences">Οpensource licences</a>
|
||||
<a class="col-auto conditions-policy" href="/terms-and-conditions">Terms and conditions</a>
|
||||
<a class="col-auto conditions-policy" href="/cookies-policy">Cookies policy</a>
|
||||
</div>
|
||||
<div class="row justify-content-center pt-5">
|
||||
<div class="col-auto"><img src="../assets/img/Cc.logo.circle.png" width="24" height="24"></div>
|
||||
<div class="col-auto pl-0"><img src="../assets/img/univ-access.png" width="24" height="24"></div>
|
||||
<div class="licence">Unless otherwise indicated, all materials created by OpenAIRE are licenced under
|
||||
</div>
|
||||
<div><u><a class="licence" href="https://creativecommons.org/licenses/by/4.0/">
|
||||
ATTRIBUTION 4.0 INTERNATIONAL LICENSE.
|
||||
<i class="fas fa-external-link-alt ext-link-icon"></i>
|
||||
</a></u></div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- Core theme JS-->
|
||||
<script src="../js/scripts.js"></script>
|
||||
<!-- Bootstrap -->
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
|
||||
<!-- Js for this file -->
|
||||
<script src="../js/how-it-works.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
Before Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 395 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 155 KiB |
Before Width: | Height: | Size: 205 KiB |
Before Width: | Height: | Size: 457 KiB |
Before Width: | Height: | Size: 310 KiB |
Before Width: | Height: | Size: 482 KiB |
Before Width: | Height: | Size: 158 KiB |
Before Width: | Height: | Size: 183 KiB |
Before Width: | Height: | Size: 196 KiB |
Before Width: | Height: | Size: 185 KiB |
Before Width: | Height: | Size: 277 KiB |
Before Width: | Height: | Size: 241 KiB |
Before Width: | Height: | Size: 5.0 MiB |
Before Width: | Height: | Size: 2.8 MiB |
Before Width: | Height: | Size: 2.0 MiB |