diff --git a/firebase_to_xml/firebase_to_xml/record_json_to_yaml.py b/firebase_to_xml/firebase_to_xml/record_json_to_yaml.py index 9cd45382..12ba6110 100644 --- a/firebase_to_xml/firebase_to_xml/record_json_to_yaml.py +++ b/firebase_to_xml/firebase_to_xml/record_json_to_yaml.py @@ -105,6 +105,7 @@ def record_json_to_yaml(record): "title": record.get("title"), "identifier": record.get("datasetIdentifier"), "abstract": record.get("abstract"), + "associated_resources": record.get("associated_resources", []), "dates": { "creation": date_from_datetime_str(record.get("dateStart")), "publication": date_from_datetime_str(record.get("datePublished")), diff --git a/src/__tests__/isoCodeList.test.js b/src/__tests__/isoCodeList.test.js index b3d0ff82..0cb822dc 100644 --- a/src/__tests__/isoCodeList.test.js +++ b/src/__tests__/isoCodeList.test.js @@ -1,7 +1,9 @@ -import { eovList, progressCodes, roleCodes } from "../isoCodeLists"; +import { eovList, progressCodes, roleCodes, associationTypeCode, initiativeTypeCode } from "../isoCodeLists"; it("Defines constants", () => { expect(eovList).toBeDefined(); expect(progressCodes).toBeDefined(); expect(roleCodes).toBeDefined(); + expect(associationTypeCode).toBeDefined(); + expect(initiativeTypeCode).toBeDefined(); }); diff --git a/src/associationTypeMapping.js b/src/associationTypeMapping.js new file mode 100644 index 00000000..63cc0f8d --- /dev/null +++ b/src/associationTypeMapping.js @@ -0,0 +1,38 @@ +const associationTypeToIso = { + "IsCitedBy": "crossReference", + "Cites": "crossReference", + "IsSupplementTo": "crossReference", + "IsSupplementedBy": "crossReference", + "IsContinuedBy": "series", + "Continues": "series", + "IsDescribedBy": "crossReference", + "Describes": "crossReference", + "HasMetadata": "crossReference", + "IsMetadataFor": "crossReference", + "HasVersion": "revisionOf", + "IsVersionOf": "revisionOf", + "IsNewVersionOf": "revisionOf", + "PreviousVersionOf": "crossReference", + "IsPartOf": "largerWorkCitation", + "HasPart": "isComposedOf", + "IsPublishedIn": "largerWorkCitation", + "IsReferencedBy": "crossReference", + "References": "crossReference", + "IsDocumentedBy": "crossReference", + "Documents": "crossReference", + "IsCompiledBy": "dependency", + "Compiles": "dependency", + "IsVariantFormOf": "crossReference", + "IsOriginalFormOf": "crossReference", + "IsIdenticalTo": "crossReference", + "IsReviewedBy": "crossReference", + "Reviews": "crossReference", + "IsDerivedFrom": "dependency", + "IsSourceOf": "dependency", + "Requires": "dependency", + "IsRequiredBy": "dependency", + "IsObsoletedBy": "crossReference", + "Obsoletes": "revisionOf", +}; + +export default associationTypeToIso; \ No newline at end of file diff --git a/src/components/FormComponents/RelatedWorks.jsx b/src/components/FormComponents/RelatedWorks.jsx new file mode 100644 index 00000000..a4ece7e1 --- /dev/null +++ b/src/components/FormComponents/RelatedWorks.jsx @@ -0,0 +1,266 @@ +import React from "react"; +import { + Add, + Delete, + ArrowUpwardSharp, + ArrowDownwardSharp, +} from "@material-ui/icons"; +import { Button, Grid, Paper, TextField } from "@material-ui/core"; +import validator from "validator"; +import { useParams } from "react-router-dom"; +import { En, Fr, I18n } from "../I18n"; +import { associationTypeCode, identifierType } from "../../isoCodeLists"; + +import BilingualTextInput from "./BilingualTextInput"; +import RequiredMark from "./RequiredMark"; +import SelectInput from "./SelectInput"; +import { deepCopy } from "../../utils/misc"; +import { QuestionText, paperClass, SupplementalText } from "./QuestionStyles"; + +import associationTypeToIso from "../../associationTypeMapping" +const validateURL = (url) => !url || validator.isURL(url); + +const RelatedWorks = ({ updateResources, resources, disabled }) => { + + const emptyResource = { title: { en: "", fr: "" }, authority: "", code: "", association_type: "", association_type_iso: ""}; + const { language } = useParams(); + + function addResource() { + updateResources(resources.concat(deepCopy(emptyResource))); + } + + // removes the resource section from the list at index i + function removeResource(i) { + updateResources(resources.filter((e, index) => index !== i)); + } + + // move the resource section + function moveResource(i, newIndex) { + if (newIndex < 0 || newIndex >= resources.length) return; + const element = resources.splice(i, 1)[0]; + resources.splice(newIndex, 0, element); + updateResources(resources); + } + + return ( +
+ {resources.map((dist = deepCopy(emptyResource), i) => { + function urlIsValid(url) { + return !url || validateURL(url); + } + function handleResourceChange(key) { + return (e) => { + const newValue = [...resources]; + newValue[i][key] = e.target.value; + updateResources(newValue); + }; + } + + function handleAssociationTypeChange() { + let key = "association_type"; + console.log("In handleAssociationTypeChange") + return (e) => { + const newValue = [...resources]; + newValue[i]["association_type_iso"] = associationTypeToIso[e.target.value]; + newValue[i][key] = e.target.value; + updateResources(newValue); + }; + } + function handleIdentifierChange(key) { + return (e) => { + + const newValue = [...resources]; + newValue[i][key] = e.target.value; + + let s = newValue[i]['code'] + switch (true) { + case urlIsValid(newValue[i]['code']) && /^http.?:\/\/doi\.org\//i.test(s): + newValue[i]['authority'] = 'DOI' + console.log('MATCH DOI') + break; + case urlIsValid(newValue[i]['code']): + newValue[i]['authority'] = 'URL' + console.log('MATCH URL') + break; + default: + newValue[i]['authority'] = '' + break; + } + updateResources(newValue); + }; + } + return ( + + + + + + Enter the title of the related resource + Entrez le titre de l'œuvre concernée + + + {" "} + } + value={dist.title} + onChange={handleResourceChange("title")} + disabled={disabled} + /> + + + + + Enter the identifier for the related resource + Saisissez l'identifiant de l'œuvre concernée + + + + + + +

+ The identifier may be to a resource, or metadata record on another + repository or another record within CIOOS. A DOI or full URL are preferred. +

+
+ +

+ L'identifiant peut provenir d'une ressource ou d'un enregistrement de métadonnées sur un autre + référentiel ou un autre enregistrement dans CIOOS. Un DOI ou une URL complète sont préférés. +

+
+
+
+
+ } + value={dist.code} + onChange={handleIdentifierChange("code")} + fullWidth + disabled={disabled} + /> +
+ + + + Enter the identifier type + Entrez le type d'identifiant + + + + + } + fullWidth={false} + /> + + + + + What is the relation type? + + Quel est le type de relation? + + + + + +

+ Specify the relationship from (A) the primary resource; to (B) the related resource. For example: +

+
    +
  • Use 'Is New Version Of' to indicate the primary resource described in this metadata record (A) is a new version of (B) the related resource.
  • +
  • Use 'Is Part of' to indicate the primary resource (A) is a subset of (B) the related larger resource.
  • +
  • Use 'Has Part' to indicate the primary resource (A) is the larger work that includes (B) the related resource.
  • +
  • Use 'Cites' to indicate that (A) cites (B).
  • +
  • Use 'Is Cited by to indicate that (B) cites (A)
  • +
+ +
+ +

+ Spécifiez la relation à partir de (A) la ressource principale ; à (B) la ressource associée. Par exemple: +

+
    +
  • Utilisez "Est une nouvelle version de" pour indiquer que la ressource principale décrite dans cet enregistrement de métadonnées (A) est une nouvelle version de (B) la ressource associée.
  • +
  • Utilisez "Fait partie de" pour indiquer que la ressource principale (A) est un sous-ensemble de (B) la ressource plus grande associée.
  • +
  • Utilisez "A une partie" pour indiquer que la ressource principale (A) est le travail le plus important qui comprend (B) la ressource associée.
  • +
  • Utilisez "Cites" pour indiquer que (A) cite (B).
  • +
  • Utilisez "Est cité par" pour indiquer que (B) cite (A)
  • +
+ +
+
+
+
+ title[language] + )} + optionTooltips={Object.values(associationTypeCode).map( + ({ text }) => text[language] + )} + disabled={disabled} + label={} + fullWidth={false} + /> +
+ + + + + +
+
+ ); + })} + + + + +
+ ); +}; + +export default RelatedWorks; diff --git a/src/components/Pages/MetadataForm.jsx b/src/components/Pages/MetadataForm.jsx index 7e66e65f..d63d1c26 100644 --- a/src/components/Pages/MetadataForm.jsx +++ b/src/components/Pages/MetadataForm.jsx @@ -24,6 +24,7 @@ import SimpleModal from "../FormComponents/SimpleModal"; import StartTab from "../Tabs/StartTab"; import ContactTab from "../Tabs/ContactTab"; import ResourcesTab from "../Tabs/ResourcesTab"; +import RelatedWorksTab from "../Tabs/RelatedWorksTab"; import IdentificationTab from "../Tabs/IdentificationTab"; import PlatformTab from "../Tabs/PlatformTab"; import SpatialTab from "../Tabs/SpatialTab"; @@ -468,6 +469,12 @@ class MetadataForm extends FormClassTemplate { label={tabs.resources[language]} value="distribution" /> + - + + + { + const updateResources = updateRecord("associated_resources"); + return ( +
+ + + Enter links to other metadata records, publications or works that are + related to the primary resources this metadata record describes. + + + Entrez des liens vers d'autres enregistrements de métadonnées, publications ou ouvrages qui sont + liés aux ressources principales décrites par cet enregistrement de métadonnées. + + + + + + Related works may be: +
    +
  • Other datasets that are part of the same collection, project, or sampling protocol
  • +
  • Metadata records on other catalogues such as OBIS or FRDR that describe the same dataset
  • +
  • Any work that adds context to or describes the primary resource for which you are creating this metadata record for
  • +
+ + Some of the ways a work can be related are: +
    +
  • Cross Reference - Reference from one record to another. Use to identify related documents or related records that may be part of the same collection or project
  • +
  • Dependency - Associated through a dependency
  • +
  • Is Composed Of/Larger Work Citation - Reference to record(s) that are parts of this resource or which this one is a part of
  • +
  • Revision Of - Resource is a revision of associated record
  • +
+
+ + Les œuvres connexes peuvent être : +
    +
  • Autres ensembles de données faisant partie de la même collection, du même projet ou du même protocole d'échantillonnage
  • +
  • Enregistrements de métadonnées sur d'autres catalogues tels que OBIS ou FRDR qui décrivent le même ensemble de données
  • +
  • Tout travail qui ajoute du contexte ou décrit la ressource principale pour laquelle vous créez cet enregistrement de métadonnées
  • +
+ + Certaines des façons dont une œuvre peut être liée sont : +
    +
  • Référence croisée - référence d'un enregistrement à un autre. À utiliser pour identifier des documents ou des enregistrements associés pouvant faire partie de la même collection ou du même projet.
  • +
  • Dépendance - Associé via une dépendance
  • +
  • Est composé de/Citation de travail plus grande - Référence à un ou plusieurs enregistrements qui font partie de cette ressource ou dont celle-ci fait partie
  • +
  • Révision de - la ressource est une révision de l'enregistrement associé
  • +
+
+
+
+
+
+ +
+ ); +}; + +export default RelatedWorksTab; diff --git a/src/components/Tabs/ResourcesTab.jsx b/src/components/Tabs/ResourcesTab.jsx index 8e628cbb..3caa9f23 100644 --- a/src/components/Tabs/ResourcesTab.jsx +++ b/src/components/Tabs/ResourcesTab.jsx @@ -18,10 +18,16 @@ const ResourcesTab = ({ disabled, record, updateRecord }) => {
- Enter any links to information associated with this dataset. + Enter one or more links to the primary resource described by this + metadata record. Resources added here should not already have their + own metadata record or digital object identifier, such resources + should be added to the "Related Works" section. - Entrez les liens vers les informations associées à ce jeu de - données. + Entrez un ou plusieurs liens vers la ressource principale décrite par + cet enregistrement de métadonnées. Les ressources ajoutées ici ne + doivent pas déjà avoir leur propre enregistrement de métadonnées ou + identifiant d'objet numérique, ces ressources doivent être ajoutées à + la section "Travaux associés". @@ -29,26 +35,28 @@ const ResourcesTab = ({ disabled, record, updateRecord }) => { Some examples of resources are:
    -
  • supporting documentation (eg text or pdf files)
  • +
  • Protocols or methods documents
  • CSV files
  • ERDDAP datasets
  • -
  • images
  • +
  • Images
  • +
  • Online forms to request access to the data
- At least one item is required. A Resource URL can link to a - (compressed) data package or folder. + A Resource URL that links to a compressed data package or folder is + preferred. Otherwise, list primary resource first followed by + supporting resources.
Voici quelques exemples de ressources :
    -
  • - Documentation à l'appui (par exemple, fichiers texte ou pdf) -
  • +
  • Documents de protocoles ou de méthodes
  • Fichiers CSV
  • -
  • Jeux de données ERDDAP
  • +
  • Ensembles de données ERDDAP
  • Images
  • +
  • Formulaires en ligne pour demander l'accès aux données
- Au moins une ressource est requise. Une URL de ressource peut - être liée à un paquet de données (compressé) ou à un dossier. + Une URL de ressource qui renvoie à un package ou un dossier de données + compressées est préférable. Sinon, répertoriez d'abord la ressource + principale, suivie des ressources de support.
diff --git a/src/isoCodeLists.js b/src/isoCodeLists.js index c7f2772f..dbfd4fd1 100644 --- a/src/isoCodeLists.js +++ b/src/isoCodeLists.js @@ -217,3 +217,364 @@ export const depthDirections = { heightPositive: { en: "Depth Positive", fr: "Profondeur positive" }, depthPositive: { en: "Height Positive", fr: "Hauteur positive" }, }; + +export const associationTypeCode = { + IsCitedBy: { + title: { en: "Is Cited By", fr: "Est cité par" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + Cites: { + title: { en: "Cites", fr: "Cites" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + IsSupplementTo: { + title: { en: "Is Supplement To", fr: "Est un supplément à" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + IsSupplementedBy: { + title: { en: "Is Supplemented By", fr: "Est complété par" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + IsContinuedBy: { + title: { en: "Is Continued By", fr: "Est continué par" }, + text: { + en: "mapped to ISO value 'series'", fr: "mappé à la valeur ISO 'series'", + }, + isoValue: "series" + }, + Continues: { + title: { en: "Continues", fr: "Continue" }, + text: { + en: "mapped to ISO value 'series'", fr: "mappé à la valeur ISO 'series'", + }, + isoValue: "series" + }, + IsDescribedBy: { + title: { en: "Is Described By", fr: "Est décrit par" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + Describes: { + title: { en: "Describes", fr: "Décrit" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + HasMetadata: { + title: { en: "Has Metadata", fr: "Possède des métadonnées" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + IsMetadataFor: { + title: { en: "Is Metadata For", fr: "Les métadonnées sont-elles destinées" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + HasVersion: { + title: { en: "Has Version", fr: "A une version" }, + text: { + en: "mapped to ISO value 'revisionOf'", fr: "mappé à la valeur ISO 'revisionOf'", + }, + isoValue: "revisionOf" + }, + IsVersionOf: { + title: { en: "Is Version Of", fr: "Est la version de" }, + text: { + en: "mapped to ISO value 'revisionOf'", fr: "mappé à la valeur ISO 'revisionOf'", + }, + isoValue: "revisionOf" + }, + IsNewVersionOf: { + title: { en: "Is New Version Of", fr: "Est-ce une nouvelle version de" }, + text: { + en: "mapped to ISO value 'revisionOf'", fr: "mappé à la valeur ISO 'revisionOf'", + }, + isoValue: "revisionOf" + }, + PreviousVersionOf: { + title: { en: "Previous Version Of", fr: "Version précédente de" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + IsPartOf: { + title: { en: "Is Part Of", fr: "Fait partie de" }, + text: { + en: "mapped to ISO value 'largerWorkCitation'", fr: "mappé à la valeur ISO 'largerWorkCitation'", + }, + isoValue: "largerWorkCitation" + }, + HasPart: { + title: { en: "Has Part", fr: "A une partie" }, + text: { + en: "mapped to ISO value 'isComposedOf'", fr: "mappé à la valeur ISO 'isComposedOf'", + }, + isoValue: "isComposedOf" + }, + IsPublishedIn: { + title: { en: "Is Published In", fr: "Est publié dans" }, + text: { + en: "mapped to ISO value 'largerWorkCitation'", fr: "mappé à la valeur ISO 'largerWorkCitation'", + }, + isoValue: "largerWorkCitation" + }, + IsReferencedBy: { + title: { en: "Is Referenced By", fr: "Est référencé par" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + References: { + title: { en: "References", fr: "Les références" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + IsDocumentedBy: { + title: { en: "Is Documented By", fr: "Est documenté par" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + Documents: { + title: { en: "Documents", fr: "Documents" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + IsCompiledBy: { + title: { en: "Is Compiled By", fr: "Est compilé par" }, + text: { + en: "mapped to ISO value 'dependency'", fr: "mappé à la valeur ISO 'dependency'", + }, + isoValue: "dependency" + }, + Compiles: { + title: { en: "Compiles", fr: "Compile" }, + text: { + en: "mapped to ISO value 'dependency'", fr: "mappé à la valeur ISO 'dependency'", + }, + isoValue: "dependency" + }, + IsVariantFormOf: { + title: { en: "Is Variant Form Of", fr: "Est une forme variante de" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + IsOriginalFormOf: { + title: { en: "Is Original Form Of", fr: "Est la forme originale de" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + IsIdenticalTo: { + title: { en: "Is Identical To", fr: "Est identique à" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + IsReviewedBy: { + title: { en: "Is Reviewed By", fr: "Est révisé par" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + Reviews: { + title: { en: "Reviews", fr: "Commentaires" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + IsDerivedFrom: { + title: { en: "Is Derived From", fr: "Dérive de" }, + text: { + en: "mapped to ISO value 'dependency'", fr: "mappé à la valeur ISO 'dependency'", + }, + isoValue: "dependency" + }, + IsSourceOf: { + title: { en: "Is Source Of", fr: "est la source de" }, + text: { + en: "mapped to ISO value 'dependency'", fr: "mappé à la valeur ISO 'dependency'", + }, + isoValue: "dependency" + }, + Requires: { + title: { en: "Requires", fr: "A besoin" }, + text: { + en: "mapped to ISO value 'dependency'", fr: "mappé à la valeur ISO 'dependency'", + }, + isoValue: "dependency" + }, + IsRequiredBy: { + title: { en: "Is Required By", fr: "Est requis par" }, + text: { + en: "mapped to ISO value 'dependency'", fr: "mappé à la valeur ISO 'dependency'", + }, + isoValue: "dependency" + }, + IsObsoletedBy: { + title: { en: "Is Obsoleted By", fr: "Est obsolète par" }, + text: { + en: "mapped to ISO value 'crossReference'", fr: "mappé à la valeur ISO 'crossReference'", + }, + isoValue: "crossReference" + }, + Obsoletes: { + title: { en: "Obsoletes", fr: "Obsolètes" }, + text: { + en: "mapped to ISO value 'revisionOf'", fr: "mappé à la valeur ISO 'revisionOf'", + }, + isoValue: "revisionOf" + }, +}; + + + +export const initiativeTypeCode = { + campaign: { + title: { en: "campaign", fr: "" }, + text: { + en: "series of organized planned actions", fr: "", + }, + }, + collection: { + title: { en: "collection", fr: "" }, + text: { + en: "accumulation of datasets assembled for a specific purpose", fr: "", + }, + }, + exercise: { + title: { en: "exercise", fr: "" }, + text: { + en: "specific performance of a function or group of functions", fr: "", + }, + }, + experiment: { + title: { en: "experiment", fr: "" }, + text: { + en: "process designed to find if something is effective or valid", fr: "", + }, + }, + investigation: { + title: { en: "investigation", fr: "" }, + text: { + en: "search or systematic inquiry", fr: "", + }, + }, + mission: { + title: { en: "mission", fr: "" }, + text: { + en: "specific operation of a data collection system", fr: "", + }, + }, + operation: { + title: { en: "operation", fr: "" }, + text: { + en: "action that is part of a series of actions", fr: "", + }, + }, + platform: { + title: { en: "platform", fr: "" }, + text: { + en: "vehicle or other support base that holds a sensor", fr: "", + }, + }, + process: { + title: { en: "process", fr: "" }, + text: { + en: "method of doing something involving a number of steps", fr: "", + }, + }, + program: { + title: { en: "program", fr: "" }, + text: { + en: "specific planned activity", fr: "", + }, + }, + project: { + title: { en: "project", fr: "" }, + text: { + en: "organized undertaking, research, or development", fr: "", + }, + }, + sensor: { + title: { en: "sensor", fr: "" }, + text: { + en: "device or piece of equipment which detects or records", fr: "", + }, + }, + study: { + title: { en: "study", fr: "" }, + text: { + en: "examination or investigation", fr: "", + }, + }, + task: { + title: { en: "task", fr: "" }, + text: { + en: "piece of work", fr: "", + }, + }, + trial: { + title: { en: "trial", fr: "" }, + text: { + en: "process of testing to discover or demonstrate somethin", fr: "", + }, + }, + +}; + +export const identifierType = [ + "ARK", + "arXiv", + "bibcode", + "ca.cioos", + "DOI", + "EAN13", + "EISSN", + "Handle", + "IGSN", + "ISBN", + "ISSN", + "ISTC", + "LISSN", + "LSID", + "PMID", + "PURL", + "UPC", + "URL", + "URN", + "w3id", +] + diff --git a/src/utils/recordToDataCite.js b/src/utils/recordToDataCite.js index 9503625b..eee7a7fb 100644 --- a/src/utils/recordToDataCite.js +++ b/src/utils/recordToDataCite.js @@ -239,9 +239,18 @@ function recordToDataCite(metadata, language, region) { // Auto-populate Datacite Resource type general as 'dataset' mappedDataCiteObject.data.attributes.types = { - resourceTypeGeneral: "Dataset", + resourceTypeGeneral: "Dataset", // TODO: change this to reflect resource type in form }; + // Link related works to this record via relatedIdentifiers datacire field + if (metadata.associated_resources) { + mappedDataCiteObject.data.attributes.relatedIdentifiers = metadata.associated_resources.map(({authority, code, association_type}) => ({ + relatedIdentifier: code, + relatedIdentifierType: authority, + relationType: association_type + })); + } + // Generate URL element mappedDataCiteObject.data.attributes.url = `${regions[region].catalogueURL[language]}dataset/ca-cioos_${metadata.identifier}`; diff --git a/src/utils/tabs.js b/src/utils/tabs.js index 666bc85d..7fb9fa41 100644 --- a/src/utils/tabs.js +++ b/src/utils/tabs.js @@ -5,6 +5,7 @@ const tabs = { spatial: { en: "Spatial", fr: "Spatial" }, contacts: { en: "Contacts", fr: "Contacts" }, resources: { en: "Resources", fr: "Ressources" }, + relatedworks: { en: "Related Works", fr: "Travaux connexes" }, platform: { en: "Platform", fr: "Plateforme" }, platformInstruments: { en: "Platform - instruments", diff --git a/src/utils/validate.js b/src/utils/validate.js index 240f25ac..65a3fb0c 100644 --- a/src/utils/validate.js +++ b/src/utils/validate.js @@ -214,6 +214,21 @@ const validators = { "Doit avoir au moins une ressource. Vérifiez si votre URL est valide.", }, }, + associated_resources: { + tab: "relatedworks", + validation: (val) => + !val || + (val && + val.every( + (work) => work.title && work.title.en && work.title.fr && work.authority && work.code && work.association_type + )), + error: { + en: + "Related works must contain a Title, Identifier, Identifier Type, and a Relation Type to be valid.", + fr: + "Les œuvres connexes doivent contenir un titre, un identifiant, un type d'identifiant et un type de relation pour être valides.", + }, + }, platformID: { tab: "platform", validation: (val, record) => record.noPlatform || val,