From f9280c1efa17703ba557012f954e876693edf1a5 Mon Sep 17 00:00:00 2001 From: Dimitris Frangiadakis Date: Fri, 21 Apr 2023 16:59:00 +0300 Subject: [PATCH] deposit form: add references field to deposit form --- .../deposit/api/DepositRecordSerializer.js | 9 +++ .../api/DepositRecordSerializer.test.js | 47 ++++++++++++ .../src/deposit/errors/FormFeedback.js | 1 + .../fields/ReferencesField/ReferencesField.js | 76 +++++++++++++++++++ .../ReferencesField/ReferencesField.test.js | 28 +++++++ .../deposit/fields/ReferencesField/index.js | 8 ++ .../fields/ReferencesField/initialValues.js | 9 +++ .../src/deposit/fields/index.js | 1 + invenio_rdm_records/config.py | 17 +++-- .../services/schemas/metadata.py | 8 +- 10 files changed, 189 insertions(+), 15 deletions(-) create mode 100644 invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/ReferencesField.js create mode 100644 invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/ReferencesField.test.js create mode 100644 invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/index.js create mode 100644 invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/initialValues.js diff --git a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/api/DepositRecordSerializer.js b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/api/DepositRecordSerializer.js index 619832977..0101d34d8 100644 --- a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/api/DepositRecordSerializer.js +++ b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/api/DepositRecordSerializer.js @@ -220,6 +220,15 @@ export class RDMDepositRecordSerializer extends DepositRecordSerializer { }, deserializedDefault: [], }), + references: new SchemaField({ + fieldpath: "metadata.references", + schema: { + reference: new Field({ + fieldpath: "reference", + }), + }, + deserializedDefault: [], + }), subjects: new AllowAdditionsVocabularyField({ fieldpath: "metadata.subjects", deserializedDefault: [], diff --git a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/api/DepositRecordSerializer.test.js b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/api/DepositRecordSerializer.test.js index d2b0976da..879ca4d03 100644 --- a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/api/DepositRecordSerializer.test.js +++ b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/api/DepositRecordSerializer.test.js @@ -9,6 +9,7 @@ import { RDMDepositRecordSerializer } from "./DepositRecordSerializer"; import { emptyDate } from "../fields/DatesField/initialValues"; import { emptyIdentifier } from "../fields/Identifiers/initialValues"; import { emptyRelatedWork } from "../fields/RelatedWorksField/initialValues"; +import { emptyReference } from "../fields/ReferencesField/initialValues"; describe("RDMDepositRecordSerializer tests", () => { const defaultLocale = "en"; @@ -137,6 +138,40 @@ describe("RDMDepositRecordSerializer tests", () => { expect(serializedRecord).toEqual({ metadata: {}, custom_fields: {}, pids: {} }); }); }); + + describe("references", () => { + it("serializes array as-is if filled", () => { + const record = { + metadata: { + references: [ + { + reference: "Test reference", + }, + ], + }, + }; + + const serializedRecord = serializer.serialize(record); + + expect(serializedRecord.metadata.references).toEqual([ + { + reference: "Test reference", + }, + ]); + }); + + it("doesn't serialize if only default is present", () => { + const record = { + metadata: { + references: [emptyReference], + }, + }; + + const serializedRecord = serializer.serialize(record); + + expect(serializedRecord).toEqual({ metadata: {}, custom_fields: {}, pids: {} }); + }); + }); }); describe("deserialize", () => { @@ -161,6 +196,7 @@ describe("RDMDepositRecordSerializer tests", () => { languages: [], identifiers: [], related_identifiers: [], + references: [], subjects: [], rights: [], funding: [], @@ -280,6 +316,11 @@ describe("RDMDepositRecordSerializer tests", () => { relation_type: "requires", }, ], + references: [ + { + reference: "Test reference", + }, + ], subjects: [ { subject: "MeSH: Cognitive Neuroscience", @@ -411,6 +452,12 @@ describe("RDMDepositRecordSerializer tests", () => { __key: 0, }, ], + references: [ + { + reference: "Test reference", + __key: 0, + }, + ], subjects: [ { id: "mesh_1", diff --git a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/errors/FormFeedback.js b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/errors/FormFeedback.js index d898e8732..6194886e7 100644 --- a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/errors/FormFeedback.js +++ b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/errors/FormFeedback.js @@ -46,6 +46,7 @@ const defaultLabels = { "metadata.version": i18next.t("Version"), "metadata.publisher": i18next.t("Publisher"), "metadata.related_identifiers": i18next.t("Related works"), + "metadata.references": i18next.t("References"), "metadata.identifiers": i18next.t("Alternate identifiers"), "access.embargo.until": i18next.t("Embargo until"), "pids.doi": i18next.t("DOI"), diff --git a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/ReferencesField.js b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/ReferencesField.js new file mode 100644 index 000000000..69744fcb2 --- /dev/null +++ b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/ReferencesField.js @@ -0,0 +1,76 @@ +// This file is part of Invenio-RDM-Records +// Copyright (C) 2020-2023 CERN. +// Copyright (C) 2020-2022 Northwestern University. +// Copyright (C) 2021 Graz University of Technology. +// +// Invenio-RDM-Records is free software; you can redistribute it and/or modify it +// under the terms of the MIT License; see LICENSE file for more details. + +import React, { Component } from "react"; +import PropTypes from "prop-types"; + +import { TextField, GroupField, ArrayField, FieldLabel } from "react-invenio-forms"; +import { Button, Form, Icon } from "semantic-ui-react"; + +import { emptyReference } from "./initialValues"; +import { i18next } from "@translations/invenio_rdm_records/i18next"; + +export class ReferencesField extends Component { + render() { + const { fieldPath, label, labelIcon, required, showEmptyValue } = this.props; + + return ( + <> + } + required={required} + showEmptyValue={showEmptyValue} + > + {({ arrayHelpers, indexPath }) => { + const fieldPathPrefix = `${fieldPath}.${indexPath}`; + + return ( + + + + + + + + ); + }} + + + ); + } +} + +ReferencesField.propTypes = { + fieldPath: PropTypes.string.isRequired, + label: PropTypes.string, + labelIcon: PropTypes.string, + required: PropTypes.bool, + showEmptyValue: PropTypes.bool, +}; + +ReferencesField.defaultProps = { + label: i18next.t("References"), + labelIcon: "bookmark", + required: undefined, + showEmptyValue: false, +}; diff --git a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/ReferencesField.test.js b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/ReferencesField.test.js new file mode 100644 index 000000000..c1dafe5b9 --- /dev/null +++ b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/ReferencesField.test.js @@ -0,0 +1,28 @@ +// This file is part of Invenio-RDM-Records +// Copyright (C) 2020-2023 CERN. +// Copyright (C) 2020-2022 Northwestern University. +// +// Invenio-RDM-Records is free software; you can redistribute it and/or modify it +// under the terms of the MIT License; see LICENSE file for more details. + +import React from "react"; +import ReactDOM from "react-dom"; + +import { Form, Formik } from "formik"; + +import { ReferencesField } from "./ReferencesField"; + +it("renders without crashing", () => { + const div = document.createElement("div"); + + ReactDOM.render( + + {() => ( +
+ + + )} +
, + div + ); +}); diff --git a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/index.js b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/index.js new file mode 100644 index 000000000..8528556dd --- /dev/null +++ b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/index.js @@ -0,0 +1,8 @@ +// This file is part of Invenio-RDM-Records +// Copyright (C) 2020-2023 CERN. +// Copyright (C) 2020-2022 Northwestern University. +// +// Invenio-RDM-Records is free software; you can redistribute it and/or modify it +// under the terms of the MIT License; see LICENSE file for more details. + +export { ReferencesField } from "./ReferencesField"; diff --git a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/initialValues.js b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/initialValues.js new file mode 100644 index 000000000..fdda6ce03 --- /dev/null +++ b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/ReferencesField/initialValues.js @@ -0,0 +1,9 @@ +// This file is part of Invenio-RDM-Records +// Copyright (C) 2020-2023 CERN. +// Copyright (C) 2020-2022 Northwestern University. +// +// Invenio-RDM-Records is free software; you can redistribute it and/or modify it +// under the terms of the MIT License; see LICENSE file for more details. +export const emptyReference = { + reference: "", +}; diff --git a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/index.js b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/index.js index 6b7f44f48..24f37ade0 100644 --- a/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/index.js +++ b/invenio_rdm_records/assets/semantic-ui/js/invenio_rdm_records/src/deposit/fields/index.js @@ -15,6 +15,7 @@ export { PIDField, IdentifiersField } from "./Identifiers"; export { LicenseField } from "./License"; export { PublicationDateField } from "./PublicationDateField"; export { PublisherField } from "./PublisherField"; +export { ReferencesField } from "./ReferencesField"; export { RelatedWorksField } from "./RelatedWorksField"; export { ResourceTypeField } from "./ResourceTypeField"; export { SubjectsField } from "./SubjectsField"; diff --git a/invenio_rdm_records/config.py b/invenio_rdm_records/config.py index ca7082dbf..f37272e35 100644 --- a/invenio_rdm_records/config.py +++ b/invenio_rdm_records/config.py @@ -63,9 +63,15 @@ def always_valid(identifier): "validator": idutils.is_ads, "datacite": "bibcode", }, + "crossreffunderid": { + "label": _("Crossref Funder ID"), + "validator": always_valid, + "datacite": "Crossref Funder ID", + }, "doi": {"label": _("DOI"), "validator": idutils.is_doi, "datacite": "DOI"}, "ean13": {"label": _("EAN13"), "validator": idutils.is_ean13, "datacite": "EAN13"}, "eissn": {"label": _("EISSN"), "validator": idutils.is_issn, "datacite": "EISSN"}, + "grid": {"label": _("GRID"), "validator": always_valid, "datacite": "GRID"}, "handle": { "label": _("Handle"), "validator": idutils.is_handle, @@ -73,6 +79,7 @@ def always_valid(identifier): }, "igsn": {"label": _("IGSN"), "validator": always_valid, "datacite": "IGSN"}, "isbn": {"label": _("ISBN"), "validator": idutils.is_isbn, "datacite": "ISBN"}, + "isni": {"label": _("ISNI"), "validator": idutils.is_isni, "datacite": "ISNI"}, "issn": {"label": _("ISSN"), "validator": idutils.is_issn, "datacite": "ISSN"}, "istc": {"label": _("ISTC"), "validator": idutils.is_istc, "datacite": "ISTC"}, "lissn": {"label": _("LISSN"), "validator": idutils.is_issn, "datacite": "LISSN"}, @@ -83,16 +90,10 @@ def always_valid(identifier): "url": {"label": _("URL"), "validator": idutils.is_url, "datacite": "URL"}, "urn": {"label": _("URN"), "validator": idutils.is_urn, "datacite": "URN"}, "w3id": {"label": _("W3ID"), "validator": always_valid, "datacite": "w3id"}, + "other": {"label": _("Other"), "validator": always_valid, "datacite": "Other"}, } -"""These are used for main, alternate and related identifiers.""" +"""These are used for references, main, alternate and related identifiers.""" - -RDM_RECORDS_REFERENCES_SCHEMES = { - "isni": {"label": _("ISNI"), "validator": idutils.is_isni}, - "grid": {"label": _("GRID"), "validator": always_valid}, - "crossreffunderid": {"label": _("Crossref Funder ID"), "validator": always_valid}, - "other": {"label": _("Other"), "validator": always_valid}, -} RDM_RECORDS_LOCATION_SCHEMES = { "wikidata": {"label": _("Wikidata"), "validator": always_valid}, "geonames": {"label": _("GeoNames"), "validator": always_valid}, diff --git a/invenio_rdm_records/services/schemas/metadata.py b/invenio_rdm_records/services/schemas/metadata.py index f862d4d7a..90c5a2454 100644 --- a/invenio_rdm_records/services/schemas/metadata.py +++ b/invenio_rdm_records/services/schemas/metadata.py @@ -48,12 +48,6 @@ lambda: current_app.config["RDM_RECORDS_IDENTIFIERS_SCHEMES"] ) - -record_references_schemes = LocalProxy( - lambda: current_app.config["RDM_RECORDS_REFERENCES_SCHEMES"] -) - - record_location_schemes = LocalProxy( lambda: current_app.config["RDM_RECORDS_LOCATION_SCHEMES"] ) @@ -275,7 +269,7 @@ class ReferenceSchema(IdentifierSchema): def __init__(self, **kwargs): """Constructor.""" super().__init__( - allowed_schemes=record_references_schemes, + allowed_schemes=record_identifiers_schemes, identifier_required=False, **kwargs )