diff --git a/Makefile b/Makefile
index 0508fb0..c041a77 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,8 @@
# Important directories
VUE_APP_DIR = shacl-vue
DIST_DIR = dist
+PLUGIN_DIR = plugins
+RUNTIME_PLUGIN_DIR = $(VUE_APP_DIR)/src/runtime-plugins
all: build
@@ -9,9 +11,11 @@ install:
npm install vite
cd $(VUE_APP_DIR) && npm install
+# Copy runtime plugins before build
# Build shacl-vue using top-level Vite-config
# Copy shacl-vue config to dist directory
build: clean
+ cp -r $(PLUGIN_DIR) $(RUNTIME_PLUGIN_DIR)
cd $(VUE_APP_DIR) && npm run build:app
mv $(VUE_APP_DIR)/dist/app ./$(DIST_DIR)
cp -r templates $(DIST_DIR)/
diff --git a/config.yaml b/config.yaml
index 079020c..aaf3e29 100644
--- a/config.yaml
+++ b/config.yaml
@@ -4,6 +4,11 @@
app_name: TRR379 Knowledge Pooling Tool (v0)
documentation_url: https://docs.trr379.de/howtos/pool-tool/index.html
external_config_url: https://pool.v0.trr379.de/ui/config_ri_default.yaml
+footer_links:
+ - url: https://www.fz-juelich.de/en/legal-notice
+ text: Legal notice
+ - url: https://dfg-cp-survey.trr379.de/#privacy-policy
+ text: Privacy policy
page_title: TRR379 Knowledge
source_code_url: https://hub.trr379.de/q02/pool.v0.trr379.de-ui
@@ -13,14 +18,20 @@ source_code_url: https://hub.trr379.de/q02/pool.v0.trr379.de-ui
content:
depiction-upload-template:
url: templates/depiction-upload.ttl
- doi-template:
- url: templates/doi.ttl
+ doi-import-wizard-template:
+ url: templates/doi-import-wizard.nunjucks.ttl
doi-logo:
url: https://hub.psychoinformatics.de/datalink/assets/raw/branch/main/shacl-vue/DOI_logo_24.svg
+ doi-template:
+ url: templates/doi.ttl
file-upload-template:
url: templates/file-upload.ttl
FrontPageHTML:
url: frontpage.html
+ orcid-logo:
+ url: https://hub.psychoinformatics.de/datalink/assets/raw/branch/main/shacl-vue/orcid_logo_24.svg
+ person-depiction-upload-template:
+ url: templates/person-depiction-upload.nunjucks.ttl
# --------------
@@ -52,21 +63,77 @@ component_config:
NodeShapeViewer:
recordNumberStepSize: 5
textTruncateWidth: '85%'
+ hideBackLinks:
+ - dlthings:AnnotationTag
+ - dlthings:Convention
+ - dlthings:Property
+ - dlthings:Rule
+ - trr379ri:TRR379AgentRole
+ - trr379ri:TRR379Activity
+ - trr379ri:TRR379ActivityRole
+ specialButtons:
+ ORCID:
+ slot: dcterms:identifier
+ match:
+ - key: rdf:type
+ val: trr379ri:ORCID
+ return: skos:notation
+ template: 'https://orcid.org/{return}'
+ icon: content:orcid-logo
+ tooltip: Visit ORCID page
+ DOI:
+ slot: dcterms:identifier
+ match:
+ - key: rdf:type
+ val: dlthings:DOI
+ return: skos:notation
+ template: 'https://doi.org/{return}'
+ icon: content:doi-logo
+ tooltip: Go to DOI
+ DownloadUrl:
+ slot: dlthings:characterized_by
+ match:
+ - key: rdf:type
+ val: dlthings:Statement
+ - key: rdf:predicate
+ val: dcat:downloadUrl
+ return: rdf:object
+ template: '{return}'
+ icon: mdi-download
+ tooltip: Download
+ Homepage:
+ slot: dlthings:attributes
+ match:
+ - key: rdf:type
+ val: dlthings:AttributeSpecification
+ - key: rdf:predicate
+ val: foaf:homepage
+ return: rdf:value
+ template: '{return}'
+ icon: mdi-home
+ tooltip: Homepage
W3CISO8601DateTimeEditor:
yearStart: 1990
yearEnd: 2028
+filter_records_by:
+ - dlthings:short_name
id_resolves_externally:
- trr379root
show_classes:
- - https://concepts.datalad.org/s/things/v2/AnnotationTag
- - https://concepts.datalad.org/s/things/v2/Convention
+ - dlthings:AnnotationTag
+ - dlthings:Convention
# must list the next to get all identifiers to show
- - https://concepts.datalad.org/s/things/v2/Identifier
- - https://concepts.datalad.org/s/things/v2/DOI
- - https://concepts.datalad.org/s/things/v2/ISSN
- - https://concepts.datalad.org/s/things/v2/ORCID
- - https://concepts.datalad.org/s/things/v2/Rule
- - https://concepts.datalad.org/s/things/v2/Property
+ - dlthings:Identifier
+ - dlthings:DOI
+ - dlthings:ISSN
+ - dlthings:ORCID
+ - dlthings:Rule
+ - dlthings:Property
+priority_classes:
+ - class: dlthings:Thing
+ icon: mdi-view-list
+ title: All
+ include_subclasses: true
# -----------------------
# Service API integration
@@ -76,18 +143,20 @@ service_base_url:
type: write
- url: https://pool.v0.trr379.de/api/public/
type: read
-token_info: Please refer to the documentation on how to obtain a new token.
+token_info: Please refer to the documentation on how to obtain a new token
token_info_url: https://docs.trr379.de/howtos/pool-tool/setup/index.html
use_service: true
use_token: true
service_fetch_before:
- get-record: []
- get-records: []
-footer_links:
- - url: https://www.fz-juelich.de/en/legal-notice
- text: Legal notice
- - url: https://dfg-cp-survey.trr379.de/#privacy-policy
- text: Privacy policy
+ get-records:
+ - dlthings:AnnotationTag
+ - dlthings:Convention
+ - dlthings:Property
+ - dlthings:Rule
+ - trr379ri:TRR379Activity
+ - trr379ri:TRR379AgentRole
+ - trr379ri:TRR379DepictionType
+ - trr379ri:TRR379Person
# ----------------
# Special features
@@ -104,23 +173,24 @@ gitannex_p2phttp_config_wizard:
- name: TRR379 Hub
base_url: https://hub.trr379.de/git-annex-p2phttp/git-annex
repositories:
- - name: File Upload Repo
+ - name: Public uploads
annex_uuid: d10eeb70-bb68-4ae4-8c5a-713203d86733
-# -------------
-# Update Shapes
-# -------------
-# would also work for any usage of a slot via update_shapes_default + _all_property_shapes
-update_shapes:
- trr379ri:TRR379Person:
- dlthings:depiction:
- # this triggers the button
- shaclvue:gitAnnexUpload: true
-
# -------
# Wizards
# -------
wizard_editors:
+ DepictionUploadWizard:
+ name: Depiction Upload Wizard
+ tooltip: Upload a depiction
+ icon: mdi-account-box-outline
+ description: Upload an image of the person and hit *Save*
+ inputs:
+ - prop: file
+ name: File
+ type: upload
+ required: true
+ template: content:person-depiction-upload-template
DOIWizard:
name: DOI Wizard
tooltip: Add a Digital Object Identifier
@@ -136,6 +206,40 @@ wizard_editors:
# pattern:
# default:
template: content:doi-template
+ DOIImportWizard:
+ name: DOI Import Wizard
+ tooltip: Import a publication via DOI
+ icon: mdi-import
+ description: >-
+ Enter the 'DOI' field and hit *Import* in order to import metadata.
+ This will prepopulate editable fields such as *Title* and *Authors*.
+ An attempt is made to match individual imported *Author*s with known
+ *Person* records via ORCID identifiers. These matches can be accepted
+ as is without editing. The dropdown next to each imported and unmatched
+ author can be used to manually identify the correct associated Person
+ record. Also, additional authors can be added to the list. If no Person
+ record is selected for any given author in the list, a new Person record
+ will be created with a random and unique identifier, associated with the
+ entered given and family name.
+ component: doi:DOIFetcher
+ inputs:
+ - prop: title
+ type: text
+ - prop: abstract
+ type: text-paragraph
+ - prop: authors
+ type: object
+ multi_valued: true
+ inputs:
+ - prop: pid
+ type: text
+ - prop: given_name
+ type: text
+ - prop: family_name
+ type: text
+ - prop: role
+ type: select
+ template: content:doi-import-wizard-template
FileUploadWizard:
name: File Upload Wizard
tooltip: Upload a file
@@ -148,7 +252,12 @@ wizard_editors:
required: true
template: content:file-upload-template
wizard_editor_selection:
+ trr379ri:TRR379Person:
+ _record:
+ - DepictionUploadWizard
trr379ri:TRR379Publication:
+ _class:
+ - DOIImportWizard
_record:
- DOIWizard
_slots:
diff --git a/config_ri_default.yaml b/config_ri_default.yaml
index 6db9099..7c9a816 100644
--- a/config_ri_default.yaml
+++ b/config_ri_default.yaml
@@ -33,108 +33,40 @@ use_default_shapes: false
# Identifier settings
# -------------------
id_autogenerate:
- https://concepts.datalad.org/s/things/v2/AnnotationTag:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: annotation-tags/
- https://concepts.datalad.org/s/things/v2/Property:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: properties/
- https://concepts.datalad.org/s/things/v2/Rule:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: rules/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Accolade:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: accolades/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Activity:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: activities/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379ActivityRole:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: activity-roles/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379AgentRole:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: agent-roles/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379BibliographicType:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: bibliographic-types/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Competition:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: competitions/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379CompetitionType:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: competition-types/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Concept:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: concepts/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Convention:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: conventions/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379DataItem:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: dataitems/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379DataType:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: datatypes/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Dataset:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: datasets/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Depiction:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: depictions/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379DepictionType:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: depiction-types/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Document:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: documents/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379EntityRole:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: entity-roles/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379File:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: files/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Grant:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: grants/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Instrument:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: instruments/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379InstrumentType:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: instrument-types/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Objective:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: objectives/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Organization:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: organizations/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Person:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: persons/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Project:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: projects/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Publication:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: publications/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379PublicationVenue:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: publication-venues/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Quality:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: qualities/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Study:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: studies/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Subject:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: subjects/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379SubjectType:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: subject-types/
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Topic:
- id_autogenerate_prefix: trr379
- id_autogenerate_prepend: topics/
+ dlthings:AnnotationTag: 'trr379:annotation-tags/{_randomUUID}'
+ dlthings:Property: 'trr379:properties/{_randomUUID}'
+ dlthings:Rule: 'trr379:rules/{_randomUUID}'
+ trr379ri:TRR379Accolade: 'trr379:accolades/{_randomUUID}'
+ trr379ri:TRR379Activity: 'trr379:activities/{_randomUUID}'
+ trr379ri:TRR379ActivityRole: 'trr379:activity-roles/{_randomUUID}'
+ trr379ri:TRR379AgentRole: 'trr379:agent-roles/{_randomUUID}'
+ trr379ri:TRR379BibliographicType: 'trr379:bibliographic-types/{_randomUUID}'
+ trr379ri:TRR379Competition: 'trr379:competitions/{_randomUUID}'
+ trr379ri:TRR379CompetitionType: 'trr379:competition-types/{_randomUUID}'
+ trr379ri:TRR379Concept: 'trr379:concepts/{_randomUUID}'
+ trr379ri:TRR379Convention: 'trr379:conventions/{_randomUUID}'
+ trr379ri:TRR379DataItem: 'trr379:dataitems/{_randomUUID}'
+ trr379ri:TRR379DataType: 'trr379:datatypes/{_randomUUID}'
+ trr379ri:TRR379Dataset: 'trr379:datasets/{_randomUUID}'
+ trr379ri:TRR379Depiction: 'trr379:depictions/{_randomUUID}'
+ trr379ri:TRR379DepictionType: 'trr379:depiction-types/{_randomUUID}'
+ trr379ri:TRR379Document: 'trr379:documents/{_randomUUID}'
+ trr379ri:TRR379EntityRole: 'trr379:entity-roles/{_randomUUID}'
+ trr379ri:TRR379File: 'trr379:files/{_randomUUID}'
+ trr379ri:TRR379Grant: 'trr379:grants/{_randomUUID}'
+ trr379ri:TRR379Instrument: 'trr379:instruments/{_randomUUID}'
+ trr379ri:TRR379InstrumentType: 'trr379:instrument-types/{_randomUUID}'
+ trr379ri:TRR379Objective: 'trr379:objectives/{_randomUUID}'
+ trr379ri:TRR379Organization: 'trr379:organizations/{_randomUUID}'
+ trr379ri:TRR379Person: 'trr379:persons/{_randomUUID}'
+ trr379ri:TRR379Project: 'trr379:projects/{_randomUUID}'
+ trr379ri:TRR379Publication: 'trr379:publications/{_randomUUID}'
+ trr379ri:TRR379PublicationVenue: 'trr379:publication-venues/{_randomUUID}'
+ trr379ri:TRR379Quality: 'trr379:qualities/{_randomUUID}'
+ trr379ri:TRR379Study: 'trr379:studies/{_randomUUID}'
+ trr379ri:TRR379Subject: 'trr379:subjects/{_randomUUID}'
+ trr379ri:TRR379SubjectType: 'trr379:subject-types/{_randomUUID}'
+ trr379ri:TRR379Topic: 'trr379:topics/{_randomUUID}'
id_autogenerate_override: true
id_iri: https://concepts.datalad.org/s/things/v2/pid
id_resolves_externally:
@@ -158,80 +90,80 @@ id_resolves_externally:
# ------------
allow_copy_record_urls: true
allow_edit_instances:
- - https://concepts.datalad.org/s/things/v2/Checksum
- - https://concepts.datalad.org/s/things/v2/DOI
- - https://concepts.trr379.de/s/research-information/unreleased/TRR379Communication
- - https://concepts.trr379.de/s/research-information/unreleased/TRR379Influence
+ - dlthings:Checksum
+ - dlthings:DOI
+ - trr379ri:TRR379Communication
+ - trr379ri:TRR379Influence
class_name_display: name
class_icons:
- https://concepts.trr379.de/s/research-information/unreleased/ORCID: mdi-identifier
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Accolade: mdi-medal
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Activity: mdi-run
- https://concepts.trr379.de/s/research-information/unreleased/TRR379ActivityRole: mdi-washing-machine
- https://concepts.trr379.de/s/research-information/unreleased/TRR379AgentRole: mdi-function
- https://concepts.trr379.de/s/research-information/unreleased/TRR379BibliographicType: mdi-newspaper
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Communication: mdi-message-text-outline
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Competition: mdi-podium-gold
- https://concepts.trr379.de/s/research-information/unreleased/TRR379CompetitionType: mdi-podium
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Concept: mdi-shape-outline
- https://concepts.trr379.de/s/research-information/unreleased/TRR379DataItem: mdi-file-document-outline
- https://concepts.trr379.de/s/research-information/unreleased/TRR379DataType: mdi-tape-measure
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Dataset: mdi-database
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Depiction: mdi-image
- https://concepts.trr379.de/s/research-information/unreleased/TRR379DepictionType: mdi-folder-multiple-image
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Document: mdi-file-document-outline
- https://concepts.trr379.de/s/research-information/unreleased/TRR379EntityRole: mdi-excavator
- https://concepts.trr379.de/s/research-information/unreleased/TRR379File: mdi-folder-arrow-right-outline
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Grant: mdi-cash-100
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Influence: mdi-arrow-decision
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Instrument: mdi-microscope
- https://concepts.trr379.de/s/research-information/unreleased/TRR379InstrumentType: mdi-beaker-question-outline
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Objective: mdi-bullseye-arrow
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Organization: mdi-account-group
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Person: mdi-face-man
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Project: mdi-briefcase-outline
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Publication: mdi-newspaper-variant-outline
- https://concepts.trr379.de/s/research-information/unreleased/TRR379PublicationVenue: mdi-office-building-outline
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Quality: mdi-bag-personal-tag-outline
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Study: mdi-school-outline
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Subject: mdi-account-search
- https://concepts.trr379.de/s/research-information/unreleased/TRR379SubjectType: mdi-tag-search
- https://concepts.trr379.de/s/research-information/unreleased/TRR379Topic: mdi-book-information-variant
- https://concepts.datalad.org/s/things/v2/Annotation: mdi-tag-outline
- https://concepts.datalad.org/s/things/v2/AnnotationTag: mdi-tag-outline
- https://concepts.datalad.org/s/things/v2/Association: mdi-account-switch
- https://concepts.datalad.org/s/things/v2/Attribution: mdi-account-star
- https://concepts.datalad.org/s/things/v2/AttributeSpecification: mdi-playlist-check
- https://concepts.datalad.org/s/things/v2/Checksum: mdi-file-check-outline
- https://concepts.datalad.org/s/things/v2/Communication: mdi-message-text-outline
- https://concepts.datalad.org/s/things/v2/Convention: mdi-script-text-outline
- https://concepts.datalad.org/s/things/v2/Dataset: mdi-database
- https://concepts.datalad.org/s/things/v2/DataItem: mdi-file-document-outline
- https://concepts.datalad.org/s/things/v2/Delegation: mdi-badge-account
- https://concepts.datalad.org/s/things/v2/Derivation: mdi-toolbox
- https://concepts.datalad.org/s/things/v2/Document: mdi-file-document-outline
- https://concepts.datalad.org/s/things/v2/DOI: mdi-identifier
- https://concepts.datalad.org/s/things/v2/End: mdi-clock-end
- https://concepts.datalad.org/s/things/v2/File: mdi-folder-arrow-right-outline
- https://concepts.datalad.org/s/things/v2/Generation: mdi-auto-fix
- https://concepts.datalad.org/s/things/v2/Grant: mdi-cash-100
- https://concepts.datalad.org/s/things/v2/Identifier: mdi-identifier
- https://concepts.datalad.org/s/things/v2/Influence: mdi-arrow-decision
- https://concepts.datalad.org/s/things/v2/Instrument: mdi-microscope
- https://concepts.datalad.org/s/things/v2/Invalidation: mdi-glass-fragile
- https://concepts.datalad.org/s/things/v2/Organization: mdi-account-group
- https://concepts.datalad.org/s/things/v2/Person: mdi-face-man
- https://concepts.datalad.org/s/things/v2/Project: mdi-briefcase-outline
- https://concepts.datalad.org/s/things/v2/Property: mdi-contain-start
- https://concepts.datalad.org/s/things/v2/Publication: mdi-newspaper-variant-outline
- https://concepts.datalad.org/s/things/v2/Quotation: mdi-comment-quote
- https://concepts.datalad.org/s/things/v2/Revision: mdi-numeric-positive-1
- https://concepts.datalad.org/s/things/v2/Rule: mdi-gavel
- https://concepts.datalad.org/s/things/v2/Start: mdi-clock-start
- https://concepts.datalad.org/s/things/v2/Statement: mdi-comment-text-outline
- https://concepts.datalad.org/s/things/v2/Study: mdi-school-outline
- https://concepts.datalad.org/s/things/v2/Subject: mdi-account-search
- https://concepts.datalad.org/s/things/v2/Usage: mdi-format-list-checks
+ trr379ri:ORCID: mdi-identifier
+ trr379ri:TRR379Accolade: mdi-medal
+ trr379ri:TRR379Activity: mdi-run
+ trr379ri:TRR379ActivityRole: mdi-washing-machine
+ trr379ri:TRR379AgentRole: mdi-function
+ trr379ri:TRR379BibliographicType: mdi-newspaper
+ trr379ri:TRR379Communication: mdi-message-text-outline
+ trr379ri:TRR379Competition: mdi-podium-gold
+ trr379ri:TRR379CompetitionType: mdi-podium
+ trr379ri:TRR379Concept: mdi-shape-outline
+ trr379ri:TRR379DataItem: mdi-file-document-outline
+ trr379ri:TRR379DataType: mdi-tape-measure
+ trr379ri:TRR379Dataset: mdi-database
+ trr379ri:TRR379Depiction: mdi-image
+ trr379ri:TRR379DepictionType: mdi-folder-multiple-image
+ trr379ri:TRR379Document: mdi-file-document-outline
+ trr379ri:TRR379EntityRole: mdi-excavator
+ trr379ri:TRR379File: mdi-folder-arrow-right-outline
+ trr379ri:TRR379Grant: mdi-cash-100
+ trr379ri:TRR379Influence: mdi-arrow-decision
+ trr379ri:TRR379Instrument: mdi-microscope
+ trr379ri:TRR379InstrumentType: mdi-beaker-question-outline
+ trr379ri:TRR379Objective: mdi-bullseye-arrow
+ trr379ri:TRR379Organization: mdi-account-group
+ trr379ri:TRR379Person: mdi-face-man
+ trr379ri:TRR379Project: mdi-briefcase-outline
+ trr379ri:TRR379Publication: mdi-newspaper-variant-outline
+ trr379ri:TRR379PublicationVenue: mdi-office-building-outline
+ trr379ri:TRR379Quality: mdi-bag-personal-tag-outline
+ trr379ri:TRR379Study: mdi-school-outline
+ trr379ri:TRR379Subject: mdi-account-search
+ trr379ri:TRR379SubjectType: mdi-tag-search
+ trr379ri:TRR379Topic: mdi-book-information-variant
+ dlthings:Annotation: mdi-tag-outline
+ dlthings:AnnotationTag: mdi-tag-outline
+ dlthings:Association: mdi-account-switch
+ dlthings:Attribution: mdi-account-star
+ dlthings:AttributeSpecification: mdi-playlist-check
+ dlthings:Checksum: mdi-file-check-outline
+ dlthings:Communication: mdi-message-text-outline
+ dlthings:Convention: mdi-script-text-outline
+ dlthings:Dataset: mdi-database
+ dlthings:DataItem: mdi-file-document-outline
+ dlthings:Delegation: mdi-badge-account
+ dlthings:Derivation: mdi-toolbox
+ dlthings:Document: mdi-file-document-outline
+ dlthings:DOI: mdi-identifier
+ dlthings:End: mdi-clock-end
+ dlthings:File: mdi-folder-arrow-right-outline
+ dlthings:Generation: mdi-auto-fix
+ dlthings:Grant: mdi-cash-100
+ dlthings:Identifier: mdi-identifier
+ dlthings:Influence: mdi-arrow-decision
+ dlthings:Instrument: mdi-microscope
+ dlthings:Invalidation: mdi-glass-fragile
+ dlthings:Organization: mdi-account-group
+ dlthings:Person: mdi-face-man
+ dlthings:Project: mdi-briefcase-outline
+ dlthings:Property: mdi-contain-start
+ dlthings:Publication: mdi-newspaper-variant-outline
+ dlthings:Quotation: mdi-comment-quote
+ dlthings:Revision: mdi-numeric-positive-1
+ dlthings:Rule: mdi-gavel
+ dlthings:Start: mdi-clock-start
+ dlthings:Statement: mdi-comment-text-outline
+ dlthings:Study: mdi-school-outline
+ dlthings:Subject: mdi-account-search
+ dlthings:Usage: mdi-format-list-checks
component_config:
# InstancesUploadEditor:
InstancesSelectEditor:
@@ -242,12 +174,6 @@ component_config:
- trr379ri
hide_classes: []
hide_classes_with_prefix: []
- InstancesUploadEditor:
- trr379ri:TRR379Depiction:
- pid_template: "trr379:depictions/{_randomUUID}"
- # this effectively limits the use of the Depiction class to
- # portrait images -- which is why we want to use the wizard approach instead
- ttl_template: content:depiction-upload-template
URIEditor:
default: curie
W3CISO8601DateTimeEditor:
@@ -313,7 +239,7 @@ filter_records_by:
hide_classes: []
hide_classes_with_prefix: []
no_edit_classes:
- - https://concepts.trr379.de/s/research-information/unreleased/TRR379BibliographicType
+ - trr379ri:TRR379BibliographicType
show_all_fields: false
show_classes_with_prefix:
- trr379ri
@@ -329,6 +255,7 @@ service_endpoints:
post-record: 'record/{name}?format=ttl'
get-record: 'record?pid={curie}&format=ttl'
get-records: 'records/{name}?format=ttl'
+ get-records-before: 'records/{name}?format=ttl'
get-paginated-records: 'records/p/{name}?format=ttl&size=100&page={page_number}'
get-paginated-records-constrained: 'records/p/{name}?format=ttl&matching=%25{match_string}%25&size=100&page={page_number}'
# service_fetch_before:
@@ -663,46 +590,51 @@ update_shapes_default:
update_shapes:
+# Things
+ dlthings:Thing:
+ rdfs:label: All types
+ rdfs:comment: Here you can search through records of all types (i.e. any `Thing`)
+
# Things that are "classifiers" (i.e., tags) without a provenance interface
# Non-Things, such as association classes
dlthings:Association:
sh:property:
rdf:object:
- dash:propertyRole: http://datashapes.org/dash#KeyInfoRole
+ dash:propertyRole: dash:KeyInfoRole
sh:or:
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Person
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Organization
sh:class: null
dlthings:roles:
- sh:class: https://concepts.trr379.de/s/research-information/unreleased/TRR379AgentRole
+ sh:class: trr379ri:TRR379AgentRole
dlthings:Attribution:
sh:property:
rdf:object:
- dash:propertyRole: http://datashapes.org/dash#KeyInfoRole
+ dash:propertyRole: dash:KeyInfoRole
sh:or:
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Person
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Organization
sh:class: null
dlthings:roles:
- sh:class: https://concepts.trr379.de/s/research-information/unreleased/TRR379AgentRole
+ sh:class: trr379ri:TRR379AgentRole
dlthings:Delegation:
sh:property:
rdf:object:
- dash:propertyRole: http://datashapes.org/dash#KeyInfoRole
+ dash:propertyRole: dash:KeyInfoRole
sh:or:
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Person
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Organization
sh:class: null
dlthings:roles:
- sh:class: https://concepts.trr379.de/s/research-information/unreleased/TRR379AgentRole
+ sh:class: trr379ri:TRR379AgentRole
dlthings:Communication:
sh:property:
rdf:object:
- dash:propertyRole: http://datashapes.org/dash#KeyInfoRole
+ dash:propertyRole: dash:KeyInfoRole
sh:or:
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Activity
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Competition
@@ -710,12 +642,12 @@ update_shapes:
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Study
sh:class: null
dlthings:roles:
- sh:class: https://concepts.trr379.de/s/research-information/unreleased/TRR379ActivityRole
+ sh:class: trr379ri:TRR379ActivityRole
dlthings:Generation:
sh:property:
rdf:object:
- dash:propertyRole: http://datashapes.org/dash#KeyInfoRole
+ dash:propertyRole: dash:KeyInfoRole
sh:or:
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Activity
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Competition
@@ -723,12 +655,12 @@ update_shapes:
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Study
sh:class: null
dlthings:roles:
- sh:class: https://concepts.trr379.de/s/research-information/unreleased/TRR379ActivityRole
+ sh:class: trr379ri:TRR379ActivityRole
dlthings:Invalidation:
sh:property:
rdf:object:
- dash:propertyRole: http://datashapes.org/dash#KeyInfoRole
+ dash:propertyRole: dash:KeyInfoRole
sh:or:
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Activity
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Competition
@@ -736,27 +668,27 @@ update_shapes:
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Study
sh:class: null
dlthings:roles:
- sh:class: https://concepts.trr379.de/s/research-information/unreleased/TRR379ActivityRole
+ sh:class: trr379ri:TRR379ActivityRole
dlthings:Quotation:
sh:property:
rdf:object:
- dash:propertyRole: http://datashapes.org/dash#KeyInfoRole
+ dash:propertyRole: dash:KeyInfoRole
dlthings:Start:
sh:property:
dlthings:at_time:
- dash:propertyRole: http://datashapes.org/dash#KeyInfoRole
+ dash:propertyRole: dash:KeyInfoRole
dlthings:End:
sh:property:
dlthings:at_time:
- dash:propertyRole: http://datashapes.org/dash#KeyInfoRole
+ dash:propertyRole: dash:KeyInfoRole
trr379ri:TRR379Communication:
sh:property:
rdf:object:
- dash:propertyRole: http://datashapes.org/dash#KeyInfoRole
+ dash:propertyRole: dash:KeyInfoRole
sh:or:
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Activity
- http://www.w3.org/ns/shacl#class: https://concepts.trr379.de/s/research-information/unreleased/TRR379Competition
@@ -771,13 +703,8 @@ update_shapes:
trr379ri:distributions:
shaclvue:gitAnnexUpload: true
- trr379ri:TRR379Person:
- sh:property:
- dlthings:depiction:
- shaclvue:gitAnnexUpload: true
-
trr379ri:TRR379Influence:
sh:property:
rdf:object:
- dash:propertyRole: http://datashapes.org/dash#KeyInfoRole
+ dash:propertyRole: dash:KeyInfoRole
diff --git a/plugins/doi/DOIFetcher.vue b/plugins/doi/DOIFetcher.vue
new file mode 100644
index 0000000..abfad90
--- /dev/null
+++ b/plugins/doi/DOIFetcher.vue
@@ -0,0 +1,261 @@
+
+
+
+
+
+
+
+ mdi-alert {{ errorTitle }}: {{ errorMessage }}
+ Ok
+
+
+
+
+ Import
+
+
+
+
+ Imported metadata
+
+ Title
+
+
+ Abstract
+
+
+ Authors
+
+
+
+ Given Name
+ Family Name
+ Role
+ Linked Record
+ Type
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-check-all
+
+
+
+
+
+
+ mdi-account-check
+
+
+
+
+
+
+ mdi-account
+
+
+
+
+
+
+
+
+
+
+ Add author
+
+
+
+
+
+
+
+
diff --git a/plugins/doi/index.js b/plugins/doi/index.js
new file mode 100644
index 0000000..bc452ff
--- /dev/null
+++ b/plugins/doi/index.js
@@ -0,0 +1,201 @@
+import { DLTHINGS, RDF, SKOS } from '@/modules/namespaces';
+import { namespace } from 'shacl-tulip';
+import { DataFactory } from 'n3';
+
+const { namedNode, blankNode, literal, quad } = DataFactory;
+const DCTERMS = namespace('http://purl.org/dc/terms/');
+const OBO = namespace('http://purl.obolibrary.org/obo/');
+const MARCREL = namespace('http://id.loc.gov/vocabulary/relators/');
+const DOI_BASE = "https://doi.org/"
+const TRR379RI = namespace('https://concepts.trr379.de/s/research-information/unreleased/');
+
+export async function importMetadata(args) {
+ const doi = args.doi;
+ const rdfDS = args.rdfDS;
+ try {
+ let result = await fetchCSL(doi);
+ const enrichedRecord = processRecord(result, rdfDS);
+ return enrichedRecord
+ } catch (error) {
+ throw(error)
+ }
+}
+
+async function fetchCSL(doi) {
+ const endpoint = `${DOI_BASE}${doi}`
+ const response = await fetch(endpoint, {
+ headers: {
+ Accept: "application/vnd.citationstyles.csl+json"
+ }
+ })
+ if (!response.ok) {
+ throw new Error(`DOI lookup failed ${response.status}`)
+ }
+ return await response.json()
+}
+
+async function fetchCitation(doi) {
+ const endpoint = `${DOI_BASE}${doi}`
+ const response = await fetch(endpoint, {
+ headers: {
+ Accept: "text/x-bibliography; style=apa"
+ }
+ })
+ if (!response.ok) {
+ return null
+ }
+ return await response.text()
+}
+
+function getAuthors(citeprocMetadata) {
+ return citeprocMetadata.author ?? []
+}
+
+function getContributions(citeprocMetadata, rdfDS) {
+ const authors = getAuthors(citeprocMetadata)
+ const persons = [];
+ const contributions = [];
+ for (const auth of authors) {
+ // if record has ORCID, try to find known Person with that identifier
+ // if person found via ORCID, this is the pid to add to the object slot of attribution
+ // if person not found: create new person record
+ let attr = {
+ roles: [getAuthorRole(auth)],
+ }
+ let person_pid
+ let person_found_via
+ if (auth['ORCID']) {
+ person_pid = findRecordWithIdentifier(auth['ORCID'].replace('https://orcid.org/', ''), rdfDS)
+ person_found_via = 'orcid'
+ }
+ attr['object'] = person_pid;
+ contributions.push(attr)
+ persons.push({
+ pid: person_pid,
+ given_name: auth['given'] ? auth['given'] : '',
+ family_name: auth['family'] ? auth['family'] : '',
+ role: getAuthorRole(auth),
+ found_via: person_found_via,
+ })
+ }
+
+ return {
+ persons: persons,
+ contributions: contributions,
+ }
+}
+
+function findRecordWithIdentifier(notation, rdfDS) {
+
+ let identifiers = rdfDS.data.graph.getQuads(
+ null,
+ namedNode(SKOS.notation.value),
+ literal(notation),
+ null
+ ).map(q => q.subject);
+ const records = identifiers.flatMap(id =>
+ rdfDS.data.graph.getQuads(
+ null,
+ namedNode(DCTERMS.identifier.value),
+ id,
+ null
+ ).map(q => q.subject)
+ )
+ if (records.length) {
+ return records[0].value
+ }
+ return undefined
+}
+
+export function findPublicationWithDOI(doi, rdfDS) {
+ // First try and find publication records with linked identifiers
+ // Then try to find publications with DOI as PID
+ let publication = findRecordWithIdentifier(doi, rdfDS)
+ if (publication) {
+ return publication
+ } else {
+ let pubPIDs = rdfDS.data.graph.getQuads(
+ namedNode(`${DOI_BASE}${doi}`),
+ namedNode(RDF.type.value),
+ namedNode(TRR379RI.TRR379Publication.value),
+ null
+ ).map(q => q.subject);
+ if (pubPIDs.length) {
+ return pubPIDs[0].value;
+ }
+ }
+ return undefined
+}
+
+function findPersonWithNames(givenName, familyName, rdfDS) {
+ // persons with matching family name
+ const familyMatches = rdfDS.data.graph.getQuads(
+ null,
+ namedNode(DLTHINGS.family_name.value),
+ literal(familyName),
+ null
+ ).map(q => q.subject.value)
+ // persons with matching given name
+ const givenMatches = rdfDS.data.graph.getQuads(
+ null,
+ namedNode(DLTHINGS.given_name.value),
+ literal(givenName),
+ null
+ ).map(q => q.subject.value)
+ // intersection
+ const persons = familyMatches.filter(p => givenMatches.includes(p))
+ if (persons.length) {
+ return persons[0]
+ }
+ return undefined
+}
+
+function getAuthorRole(author) {
+ let seq = author['sequence']
+ if (seq) {
+ if (seq == 'first') {
+ return OBO.MS_1002034.value;
+ } else if (seq == 'additional') {
+ return OBO.MS_1002036.value;
+ } else {
+ return MARCREL.aut.value;
+ }
+ }
+ return MARCREL.aut.value;
+}
+
+function htmlDecode(input) {
+ var doc = new DOMParser().parseFromString(input, "text/html");
+ return doc.documentElement.textContent;
+}
+
+function getTitle(citeprocMetadata) {
+ return citeprocMetadata.title ? htmlDecode(citeprocMetadata.title) : ''
+}
+
+function getAbstract(citeprocMetadata) {
+ return citeprocMetadata.abstract ? htmlDecode(citeprocMetadata.abstract) : ''
+}
+
+function processRecord(citeprocMetadata, rdfDS) {
+ // authors => attributed_to and persons
+ // publishing activity (date / ISSN) => generated_by
+ // licenses => rules
+ const {persons, contributions} = getContributions(citeprocMetadata, rdfDS)
+ const title = getTitle(citeprocMetadata, rdfDS)
+ const abstract = getAbstract(citeprocMetadata, rdfDS)
+ const pub = {
+ attributed_to: contributions,
+ generated_by: [],
+ about: [],
+ description: "",
+ identifiers: [],
+ pid:'',
+ title:title,
+ }
+ return {
+ authors: persons,
+ title: title,
+ abstract: abstract,
+ }
+}
\ No newline at end of file
diff --git a/shacl-vue b/shacl-vue
index 718ab3b..c219907 160000
--- a/shacl-vue
+++ b/shacl-vue
@@ -1 +1 @@
-Subproject commit 718ab3bca7c9caf6dfcb475bfb7cf5b2ae77700e
+Subproject commit c219907f5a87bf1940fc580faba9521c34fb3a17
diff --git a/templates/doi-import-wizard.nunjucks.ttl b/templates/doi-import-wizard.nunjucks.ttl
new file mode 100644
index 0000000..10ed8d7
--- /dev/null
+++ b/templates/doi-import-wizard.nunjucks.ttl
@@ -0,0 +1,49 @@
+@prefix trr379: .
+@prefix trr379ri: .
+@prefix rdf: .
+@prefix dlthings: .
+@prefix obo: .
+@prefix xsd: .
+@prefix sio: .
+@prefix dcterms: .
+@prefix skos: .
+@prefix orcid: .
+
+{% set pubId = _randomUUID() -%}
+{% set pubURI = "https://trr379.de/ns/publications/" + pubId -%}
+<{{ pubURI }}> a trr379ri:TRR379Publication .
+{% if title -%}
+<{{ pubURI }}> dlthings:title {{ title | ttl }} .
+{%- endif %}
+{% if abstract -%}
+<{{ pubURI }}> dcterms:description {{ abstract | ttl }} .
+{%- endif %}
+
+{% if doi %}
+<{{ pubURI }}> dcterms:identifier _:doiNode .
+_:doiNode a dlthings:DOI ;
+ skos:notation {{ doi | ttl }} .
+{% endif %}
+
+{% for author in authors -%}
+{% if author.pid %}
+{% set personURI = author.pid -%}
+{% else -%}
+{% set personId = _randomUUID() -%}
+{% set personURI = "https://trr379.de/ns/persons/" + personId -%}
+<{{ personURI }}> a trr379ri:TRR379Person .
+{% if author.given_name -%}
+<{{ personURI }}> dlthings:given_name {{ author.given_name | ttl }} .
+{%- endif %}
+
+{% if author.family_name -%}
+<{{ personURI }}> dlthings:family_name {{ author.family_name | ttl }} .
+{%- endif %}
+{% endif %}
+
+<{{ pubURI }}> dlthings:attributed_to _:attr{{ loop.index }} .
+_:attr{{ loop.index }} a dlthings:Attribution ;
+ rdf:object <{{ personURI }}> ;
+ dlthings:roles <{{ author.role }}> .
+
+{% endfor -%}
\ No newline at end of file
diff --git a/templates/person-depiction-upload.nunjucks.ttl b/templates/person-depiction-upload.nunjucks.ttl
new file mode 100644
index 0000000..36869de
--- /dev/null
+++ b/templates/person-depiction-upload.nunjucks.ttl
@@ -0,0 +1,30 @@
+@prefix dcat: .
+@prefix dcterms: .
+@prefix dldi: .
+@prefix dlthings: .
+@prefix rdf: .
+@prefix skos: .
+@prefix spdx: .
+@prefix trr379: .
+@prefix trr379ri: .
+@prefix xsd: .
+
+{% set depictionId = _randomUUID() -%}
+{% set depictionURI = "https://trr379.de/ns/depictions/" + depictionId -%}
+dldi:{{ file.annexKey }} a trr379ri:TRR379File;
+ skos:prefLabel {{ file.name | ttl }}^^xsd:string;
+ dlthings:distribution_of <{{ depictionURI }}>;
+ dlthings:byte_size {{ file.size | ttl }}^^xsd:nonNegativeInteger;
+ dlthings:characterized_by _:n0-1.
+_:n0-1 a dlthings:Statement;
+ rdf:object <{{ file.downloadUrl }}>;
+ rdf:predicate dcat:downloadUrl.
+dldi:{{ file.annexKey }} dlthings:checksums _:n0-2.
+_:n0-2 a dlthings:Checksum;
+ skos:notation {{ file.hash | ttl }}^^xsd:hexBinary;
+ dcterms:creator spdx:checksumAlgorithm_sha256.
+<{{ depictionURI }}> a trr379ri:TRR379Depiction;
+ dcterms:subject <{{ pid }}>;
+ dcterms:type ;
+ dlthings:distributions dldi:{{ file.annexKey }}.
+<{{ pid }}> dlthings:depiction <{{ depictionURI }}>.
\ No newline at end of file