From da3c02fb5d54e96fc3c12bf66c6333afc5046a99 Mon Sep 17 00:00:00 2001 From: Paul Sarando Date: Thu, 7 Dec 2023 18:34:18 -0700 Subject: [PATCH] CORE-1966 Initial Local Contexts support in Metadata Templates * Updated the mock DataciteMetadataTemplate with DataCite 4.2 and Local Contexts changes in QA. * Added markdown support for Metadata Template attribute descriptions. * Allow multi-line input for String attributes. * Converted Enum attribute fields to `select` FormTextFields for consistency in other forms. --- src/components/metadata/templates/index.js | 40 ++- stories/metadata/TemplateMocks.js | 310 ++++++++++++++++++++- 2 files changed, 330 insertions(+), 20 deletions(-) diff --git a/src/components/metadata/templates/index.js b/src/components/metadata/templates/index.js index 4dac61475..8f9ca08a6 100644 --- a/src/components/metadata/templates/index.js +++ b/src/components/metadata/templates/index.js @@ -16,6 +16,7 @@ import { urlField } from "components/utils/validations"; import AttributeTypes from "components/models/metadata/TemplateAttributeTypes"; import ConfirmationDialog from "components/utils/ConfirmationDialog"; import DEDialog from "components/utils/DEDialog"; +import markdownToHtml from "components/utils/markdownToHtml"; import TableLoading from "components/table/TableLoading"; import withErrorAnnouncer from "components/error/withErrorAnnouncer"; @@ -31,7 +32,6 @@ import { import FormMultilineTextField from "components/forms/FormMultilineTextField"; import FormTextField from "components/forms/FormTextField"; import FormTimestampField from "components/forms/FormTimestampField"; -import FormSelectField from "components/forms/FormSelectField"; import FormNumberField from "components/forms/FormNumberField"; @@ -98,6 +98,27 @@ const newAVU = (attrTemplate) => { }; }; +const AttributeDescription = ({ attribute }) => { + const [infoHtml, setInfoHtml] = React.useState(""); + + React.useEffect(() => { + if (attribute?.description) { + markdownToHtml(attribute.description).then((html) => + setInfoHtml(html) + ); + } else { + setInfoHtml(""); + } + }, [attribute]); + + return ( + + ); +}; + const MetadataTemplateAttributeForm = (props) => { const { field, @@ -124,8 +145,8 @@ const MetadataTemplateAttributeForm = (props) => { const { t } = useTranslation("metadata"); const classes = useStyles(); - const onAttrExpandedChange = (prevExpanded, attr, attrExpanded) => { - setExpanded({ ...prevExpanded, [attr]: attrExpanded }); + const onAttrExpandedChange = (attr, attrExpanded) => { + setExpanded({ ...expanded, [attr]: attrExpanded }); }; const onAddAVU = (arrayHelpers, attribute) => { @@ -134,7 +155,7 @@ const MetadataTemplateAttributeForm = (props) => { arrayHelpers.push(avu); - onAttrExpandedChange(expanded, attribute.name, true); + onAttrExpandedChange(attribute.name, true); }; const addSubAVUs = (attribute, avu) => { @@ -195,9 +216,10 @@ const MetadataTemplateAttributeForm = (props) => { break; case AttributeTypes.ENUM: - FieldComponent = FormSelectField; + FieldComponent = FormTextField; fieldProps = { ...fieldProps, + select: true, children: attribute.values && attribute.values.map((enumVal, index) => ( @@ -237,6 +259,7 @@ const MetadataTemplateAttributeForm = (props) => { default: FieldComponent = FormTextField; + fieldProps.multiline = true; break; } @@ -351,7 +374,6 @@ const MetadataTemplateAttributeForm = (props) => { expanded={!!expanded[attribute.name]} onChange={(event, attrExpanded) => onAttrExpandedChange( - expanded, attribute.name, attrExpanded ) @@ -413,9 +435,9 @@ const MetadataTemplateAttributeForm = (props) => { alignItems="stretch" > - - {attribute.description} - + {avuFields} diff --git a/stories/metadata/TemplateMocks.js b/stories/metadata/TemplateMocks.js index 6fbb0c3af..614e0e9ef 100644 --- a/stories/metadata/TemplateMocks.js +++ b/stories/metadata/TemplateMocks.js @@ -151,9 +151,9 @@ export const NestedAttrMetadataTemplate = { // curl -X GET --header 'Accept: application/json' 'http://localhost:31331/templates/ae75bc42-45ec-11e5-801c-43dab0dfe096?user=ipctest' | jq 'def attrs: . | {id: .id, name: .name, description: .description, required: .required?, type: .type, values: .values?, attributes: [.attributes[]? | attrs]} | if .values then . else del(.values) end | if (.attributes | length) > 0 then . else del(.attributes) end; {id: .id, name: .name, description: .description, deleted: false, attributes: [.attributes[] | attrs]}' export const DataciteMetadataTemplate = { id: DOI_DATACITE_TEMPLATE_ID, - name: "DOI Request - DataCite 4.1", + name: "DOI Request - DataCite 4.2", description: - "New copy of the DataCite metadata template for testing submissions to the DataCite API", + "DataCite 4.2 metadata template for submissions to the DataCite API and for Local Contexts Notices and Labels.", deleted: false, attributes: [ { @@ -212,14 +212,6 @@ export const DataciteMetadataTemplate = { required: true, type: "String", attributes: [ - { - id: "5e10ea38-7415-11e8-8326-008cfa5ae621", - name: "affiliation", - description: - "The organizational or institutional affiliation of the creator.", - required: true, - type: "String", - }, { id: "5e129e64-7415-11e8-8326-008cfa5ae621", name: "nameIdentifier", @@ -251,6 +243,14 @@ export const DataciteMetadataTemplate = { }, ], }, + { + id: "5e10ea38-7415-11e8-8326-008cfa5ae621", + name: "affiliation", + description: + "The organizational or institutional affiliation of the creator.", + required: true, + type: "String", + }, ], }, { @@ -682,7 +682,7 @@ export const DataciteMetadataTemplate = { id: "b2b4adfa-7419-11e8-ad87-008cfa5ae621", name: "rights", description: - "All CyVerse Curated Data in the Data Commons is open access. You can choose between ODC PDDL for non-copyrightable materials (i.e., data only) or CC0 for copyrightable material (Workflows, White Papers, Project Documents). More information is available at https://wiki.cyverse.org/wiki/display/DC/Permanent+Identifier+FAQs#PermanentIdentifierFAQs-WhichlicensecanIusetopublishmydata? If you need a different license because of prior restrictions on your data, please contact us.", + "All CyVerse Curated Data in the Data Commons is open access. You can choose between ODC PDDL for non-copyrightable materials (i.e., data only) or CC0 for copyrightable material (Workflows, White Papers, Project Documents).\nMore information is available at https://cyverse.atlassian.net/wiki/spaces/DC/pages/241867502/Permanent+Identifier+FAQs#PermanentIdentifierFAQs-WhichlicensecanIusetopublishmydata%3F\nIf you need a different license because of prior restrictions on your data, please contact us.", required: true, type: "Enum", values: [ @@ -707,6 +707,232 @@ export const DataciteMetadataTemplate = { }, ], }, + { + id: "ad9e41bc-94ae-11ee-b224-62d47aced14b", + name: "LocalContexts", + description: + "From https://localcontexts.org:\nLocal Contexts is a global initiative that supports Indigenous communities with tools that can reassert cultural authority in heritage collections and data. By focusing on Indigenous Cultural and Intellectual Property and Indigenous Data Sovereignty, Local Contexts helps Indigenous communities repatriate knowledge and gain control over how data is collected, managed, displayed, accessed, and used in the future.\n\nUse this field for the Local Contexts Rights label or notice text.\nSee the DataCite guide on these metadata fields for some examples: https://support.datacite.org/docs/local-contexts-notices-and-labels\nNote that notices should use the exact text from its landing page. For more information on Notices see https://localcontexts.org/notices/aboutnotices/", + required: false, + type: "String", + attributes: [ + { + id: "ada034a4-94ae-11ee-b224-62d47aced14b", + name: "rightsURI", + description: + "The URL of the project in the Local Contexts hub.", + required: true, + type: "URL/URI", + }, + { + id: "ada1e006-94ae-11ee-b224-62d47aced14b", + name: "rightsIdentifier", + description: + "The identifier of the specific Notice or Label being applied.\nIf referring to the entire project, leave blank.\nFor more information on Notices, see https://localcontexts.org/notices/aboutnotices/\nFor more information on TK Lables, see https://localcontexts.org/labels/traditional-knowledge-labels/\nFor more information on BC Lables, see https://localcontexts.org/labels/biocultural-labels/", + required: false, + type: "Enum", + values: [ + { + id: "ada2f25c-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-Notice", + }, + { + id: "ada36be2-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "BC-Notice", + }, + { + id: "ada3d6a4-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "Attribution-Incomplete", + }, + { + id: "ada43dec-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "Open-To-Collaborate", + }, + { + id: "ada4aa5c-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-A", + }, + { + id: "ada5025e-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-CL", + }, + { + id: "ada5aede-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-F", + }, + { + id: "ada60a96-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-MC", + }, + { + id: "ada66f36-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-CV", + }, + { + id: "ada6c454-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-CR", + }, + { + id: "ada72bba-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-V", + }, + { + id: "ada794c4-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-NV", + }, + { + id: "ada80148-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-S", + }, + { + id: "ada86872-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-WG", + }, + { + id: "ada8d5be-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-MG", + }, + { + id: "ada96e84-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-MR", + }, + { + id: "ada9de8c-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-WR", + }, + { + id: "adaa3ecc-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-CS", + }, + { + id: "adaaa0b0-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-SS", + }, + { + id: "adab0276-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-OC", + }, + { + id: "adab60f4-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-NC", + }, + { + id: "adabc080-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-CO", + }, + { + id: "adac2232-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-O", + }, + { + id: "adac7f2a-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "TK-CB", + }, + { + id: "adace49c-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "BC-P", + }, + { + id: "adad3f46-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "BC-MC", + }, + { + id: "adadb43a-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "BC-CL", + }, + { + id: "adae1af6-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "BC-CV", + }, + { + id: "adae7780-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "BC-CNV", + }, + { + id: "adaef4e4-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "BC-R", + }, + { + id: "adaf534e-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "BC-CB", + }, + { + id: "adafb276-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "BC-OC", + }, + { + id: "adb01676-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "BC-O", + }, + { + id: "adb07b7a-94ae-11ee-b224-62d47aced14b", + is_default: false, + value: "BC-NC", + }, + ], + }, + { + id: "adb1a9a0-94ae-11ee-b224-62d47aced14b", + name: "rightsIdentifierScheme", + description: "", + required: true, + type: "Enum", + values: [ + { + id: "adb3011a-94ae-11ee-b224-62d47aced14b", + is_default: true, + value: "Local Contexts", + }, + ], + }, + { + id: "adb43a62-94ae-11ee-b224-62d47aced14b", + name: "schemeURI", + description: "", + required: true, + type: "Enum", + values: [ + { + id: "adb56162-94ae-11ee-b224-62d47aced14b", + is_default: true, + value: "https://localcontexts.org", + }, + ], + }, + ], + }, { id: "52b91254-74b1-11e8-b2bf-008cfa5ae621", name: "version", @@ -1090,6 +1316,68 @@ export const DataciteMetadataTemplate = { }, ], }, + { + id: "b99524e4-867c-11e9-8a26-008cfa5ae621", + name: "geoLocationPolygon", + description: + "A drawn polygon area, defined by a set of points and lines connecting the points in a closed chain. If geoLocationPolygon27 is used, polygonPoint must be used as well. There must be at least 4 non-aligned points to make a closed curve, with the last point described the same as the first point.", + required: false, + type: "Grouping", + attributes: [ + { + id: "1e719256-867f-11e9-8a26-008cfa5ae621", + name: "polygonPoint", + description: + "A point location in a polygon. If geoLocationPolygon27 is used, polygonPoint must be used as well. There must be at least 4 non-aligned points to make a closed curve, with the last point described the same as the first point. CyVerse recommends using decimal degrees.", + required: false, + type: "Grouping", + attributes: [ + { + id: "024edfee-8683-11e9-91b5-008cfa5ae621", + name: "inPolygonPoint", + description: + 'For any bound area that is larger than half the earth, define a (random) point inside. inPolygonPoint is only necessary to indicate the "inside" of the polygon if the polygon is larger than half the earth. Otherwise the smallest of the two areas bounded by the polygon will be used.', + required: false, + type: "Grouping", + attributes: [ + { + id: "024f6892-8683-11e9-91b5-008cfa5ae621", + name: "pointLongitude", + description: + "Longitudinal dimension of point. If inPolygonPoint28 is used pointLongitude is mandatory. Longitude of the geographic point expressed in decimal degrees (positive east).", + required: false, + type: "Number", + }, + { + id: "024ff406-8683-11e9-91b5-008cfa5ae621", + name: "pointLatitude", + description: + "Latitudinal dimension of point. If inPolygonPoint is used, pointLatitude is mandatory. Latitude of the geographic point expressed in decimal degrees (positive north).", + required: false, + type: "String", + }, + ], + }, + { + id: "0250758e-8683-11e9-91b5-008cfa5ae621", + name: "pointLongitude", + description: + "Longitudinal dimension of point. If polygonPoint is used pointLongitude is mandatory. Longitude of the geographic point expressed in decimal degrees (positive east). Domain: -180 <= pointLongitude <= 180", + required: false, + type: "Number", + }, + { + id: "0251017a-8683-11e9-91b5-008cfa5ae621", + name: "pointLatitude", + description: + "Latitudinal dimension of point. If polygonPoint is used pointLatitude is mandatory. Latitude of the geographic point expressed in decimal degrees (positive north). Domain: -90<= pointLatitude <= 90", + required: false, + type: "Number", + }, + ], + }, + ], + }, ], }, {