diff --git a/app_data/vocabularies.yaml b/app_data/vocabularies.yaml index f51b6d81..36d524c9 100644 --- a/app_data/vocabularies.yaml +++ b/app_data/vocabularies.yaml @@ -21,6 +21,15 @@ experiments: departments: pid-type: dep data-file: vocabularies/departments.yaml +committees: + pid-type: com + data-file: vocabularies/committees.yaml +open_access_levels: + pid-type: oal + data-file: vocabularies/open_access_levels.yaml +open_access_funding_models: + pid-type: oaf + data-file: vocabularies/open_access_funding_models.yaml accelerators: pid-type: acc data-file: vocabularies/accelerators.yaml diff --git a/app_data/vocabularies/committees.yaml b/app_data/vocabularies/committees.yaml new file mode 100644 index 00000000..7ec2786f --- /dev/null +++ b/app_data/vocabularies/committees.yaml @@ -0,0 +1,54 @@ +- id: DRDC + title: + en: DRDC - Detector Research & Development Committee +- id: EEC + title: + en: EEC - Electronic Experiments Committee +- id: EmC + title: + en: EmC - Emulsion Committee +- id: ISC + title: + en: ISC - ISOLDE (Isotope On-Line Detector) Committee +- id: ISRC + title: + en: ISRC - Intersecting Storage-Rings Committee +- id: ISTC + title: + en: ISTC - ISOLDE and Neutron Time-of-flight Committee +- id: LEPC + title: + en: LEPC - Large Electron-Positron Collider Experiments Committee +- id: NPRC + title: + en: NPRC - Nuclear Physics Research Committee +- id: NSC + title: + en: NSC - Nuclear Structure Committee +- id: PH-I + title: + en: PH-I - Physics I Committee +- id: PH-III + title: + en: PH-III - Physics III Committee +- id: PSC + title: + en: PSC - Proton Synchrotron Committee +- id: PSCC + title: + en: PSCC - Proton Synchrotron & SynchroCyclotron Committee +- id: SC and PS Advisory Committee + title: + en: SC and PS Advisory Committee +- id: SCC + title: + en: SCC - SynchroCyclotron Committee +- id: SPSC + title: + en: SPSC - Super Proton Synchrotron Committee +- id: SPSLC + title: + en: SPSLC - Super Proton Synchrotron and LEAR Committee +- id: TCC + title: + en: TCC - Track Chamber Committee diff --git a/app_data/vocabularies/departments.yaml b/app_data/vocabularies/departments.yaml index 9c3a97c8..7a306779 100644 --- a/app_data/vocabularies/departments.yaml +++ b/app_data/vocabularies/departments.yaml @@ -1,54 +1,315 @@ - id: BE title: - en: BE + en: BE - Beams Department + props: + section: current - id: DGU title: - en: DGU + en: DGU - DG Unit + props: + section: current - id: EN title: - en: EN + en: EN - Engineering Department + props: + section: current - id: EP title: - en: EP + en: EP - Experimental Physics Department + props: + section: current - id: FAP title: - en: FAP + en: FAP - Finance and Administrative Processes Department + props: + section: current - id: FP title: - en: FP + en: FP - Finance and Procurement Department + props: + section: current - id: GS title: - en: GS + en: GS - General Infrastructure Services Department + props: + section: current - id: HR title: - en: HR + en: HR - Human Resources Department + props: + section: current - id: HSE title: - en: HSE + en: HSE - Occupational Health & Safety and Environmental Protection Unit + props: + section: current - id: IPT title: - en: IPT + en: IPT - Industry, Procurement and Knowledge Transfer Department + props: + section: current - id: IR title: - en: IR + en: IR - International Relations Sector + props: + section: current - id: IT title: - en: IT + en: IT - Information Technology Department + props: + section: current - id: PH title: - en: PH + en: PH - Physics Department + props: + section: current - id: SMB title: - en: SMB + en: SMB - Site Management and Buildings Department + props: + section: current - id: SY title: - en: SY + en: SY - Accelerator Systems Department + props: + section: current - id: TE title: - en: TE + en: TE - Technology Department + props: + section: current - id: TH title: - en: TH + en: TH - Theoretical Physics Department + props: + section: current - id: CIO title: - en: CIO \ No newline at end of file + en: CIO - Chief Information Officer + props: + section: current +- id: SR + title: + en: SR - Stakeholder Relations + props: + section: current +- id: OSI + title: + en: OSI - Organisational Support and Improvement Department + props: + section: current +- id: SCE + title: + en: SCE - Site and Civil Engineering Department + props: + section: current +- id: ADM + title: + en: ADM - Administration (1955-1969) + props: + section: former +- id: PS + title: + en: PS - Proton Synchrotron (1955-2009) + props: + section: former +- id: SB + title: + en: SB - Site and Buildings (1955-1989) + props: + section: former +- id: SC + title: + en: SC - Synchro-Cyclotron (1955-1979) + props: + section: former +- id: STS + title: + en: STS - Scientific and Technical Services (1955-1969) + props: + section: former +- id: AR + title: + en: AR - Accelerator Research (1960-1969) + props: + section: former +- id: DD + title: + en: DD - Data Handling (1960-1989) + props: + section: former +- id: ENG + title: + en: ENG - Engineering (1960-1969) + props: + section: former +- id: FI + title: + en: FI - Finance (1960-2009) + props: + section: former +- id: ISR + title: + en: ISR - Intersecting Storage Rings (1960-1989) + props: + section: former +- id: MPS + title: + en: MPS - Machine Proton Synchrotron (1960-1979) + props: + section: former +- id: MSC + title: + en: MSC - Machine Synchro-Cyclotron (1960-1979) + props: + section: former +- id: NP + title: + en: NP - Nuclear Physics (1960-1979) + props: + section: former +- id: NPA + title: + en: NPA - Nuclear Physics Apparatus (1960-1969) + props: + section: former +- id: PE + title: + en: PE - Personnel (1960-1999) + props: + section: former +- id: SI + title: + en: SI - Synchrotron Injector (1960-1979) + props: + section: former +- id: TC + title: + en: TC - Track Chambers (1960-1979) + props: + section: former +- id: EF + title: + en: EF - Experimental Physics Facilities (1970-1989) + props: + section: former +- id: HS + title: + en: HS - Health and Safety (1970-1989) + props: + section: former +- id: SPS + title: + en: SPS - Super Proton Synchrotron (1970-1989) + props: + section: former +- id: DOC + title: + en: DOC - Documentation Department (1980-1989) + props: + section: former +- id: LEP + title: + en: LEP - Large Electron Positron (1980-1989) + props: + section: former +- id: MI + title: + en: MI - Management Information Department (1980-1989) + props: + section: former +- id: ST + title: + en: ST - Technical Support (1980-2009) + props: + section: former +- id: TIS + title: + en: TIS - Technical Inspection and Safety Commission (1980-2009) + props: + section: former +- id: AS + title: + en: AS - Administrative Support (1990-2009) + props: + section: former +- id: AT + title: + en: AT - Accelerator Technologies (1990-2019) + props: + section: former +- id: CN + title: + en: CN - Computing and Networks (1990-1999) + props: + section: former +- id: ECP + title: + en: ECP - Electronics and Computing for Physics (1990-1999) + props: + section: former +- id: EST + title: + en: EST - Engineering Support and Technologies (1990-2009) + props: + section: former +- id: LHC + title: + en: LHC - Large Hadron Collider (1990-1999) + props: + section: former +- id: MT + title: + en: MT - Mechanical Technologies (1990-1999) + props: + section: former +- id: PPE + title: + en: PPE - Particle Physics Experiment (1990-1999) + props: + section: former +- id: SL + title: + en: SL - SPS and LEP (1990-2009) + props: + section: former +- id: SPL + title: + en: SPL - Supplies, Procurements and Logistics (1990-2009) + props: + section: former +- id: AB + title: + en: AB - Accelerators and Beams (2000-2009) + props: + section: former +- id: DSU + title: + en: DSU - Directorate Service Unit (2000-2009) + props: + section: former +- id: ETT + title: + en: ETT - Education and Technology Transfer (2000-2009) + props: + section: former +- id: TS + title: + en: TS - Technical Support (2000-2009) + props: + section: former +- id: DGS + title: + en: DGS - DG Safety (2010-2019) + props: + section: former +- id: RC + title: + en: RC - Research and Computing Sector (2010-2019) + props: + section: former +- id: SE + title: + en: SE - Stakeholder Engagement (2020-2025) + props: + section: former diff --git a/app_data/vocabularies/open_access_funding_models.yaml b/app_data/vocabularies/open_access_funding_models.yaml new file mode 100644 index 00000000..999185ef --- /dev/null +++ b/app_data/vocabularies/open_access_funding_models.yaml @@ -0,0 +1,15 @@ +- id: cern-read-publish + title: + en: CERN Read and Publish agreement +- id: cern-individual-apcs + title: + en: CERN individual APCs +- id: scoap3 + title: + en: SCOAP3 +- id: other-collective-models + title: + en: Other collective models +- id: other + title: + en: Other diff --git a/app_data/vocabularies/open_access_levels.yaml b/app_data/vocabularies/open_access_levels.yaml new file mode 100644 index 00000000..9af1ea44 --- /dev/null +++ b/app_data/vocabularies/open_access_levels.yaml @@ -0,0 +1,20 @@ +- id: closed + title: + en: Closed Access + props: + color: dark-blue +- id: bronze + title: + en: Bronze Open Access + props: + color: brown +- id: green + title: + en: Green Open Access + props: + color: green +- id: gold + title: + en: Gold Open Access + props: + color: orange diff --git a/app_data/vocabularies/resource_types.yaml b/app_data/vocabularies/resource_types.yaml index d3a77a79..45061dbb 100644 --- a/app_data/vocabularies/resource_types.yaml +++ b/app_data/vocabularies/resource_types.yaml @@ -372,6 +372,28 @@ tags: - depositable - linkable +- id: publication-note + icon: file alternate + props: + csl: report + datacite_general: Text + datacite_type: Other + openaire_resourceType: "0020" + openaire_type: publication + eurepo: info:eu-repo/semantics/other + schema.org: https://schema.org/CreativeWork + subtype: publication-note + type: publication + marc21_type: publication + marc21_subtype: note + title: + en: Note + sv: Note + de: Notiz + cs: Poznámka + tags: + - depositable + - linkable - id: publication-workingpaper icon: file alternate props: @@ -548,6 +570,28 @@ tags: - depositable - linkable +- id: publication-meetingminutes + icon: list alternate outline + props: + csl: report + datacite_general: Text + datacite_type: Other + openaire_resourceType: "0020" + openaire_type: publication + eurepo: info:eu-repo/semantics/other + schema.org: https://schema.org/CreativeWork + subtype: publication-meetingminutes + type: publication + marc21_type: publication + marc21_subtype: minutes + title: + en: Event + sv: Evenemang + de: Veranstaltung + cs: Událost + tags: + - depositable + - linkable - id: dataset icon: table props: diff --git a/assets/templates/custom_fields/CERNFields.js b/assets/templates/custom_fields/CERNFields.js index d8d6b491..999e88bc 100644 --- a/assets/templates/custom_fields/CERNFields.js +++ b/assets/templates/custom_fields/CERNFields.js @@ -19,6 +19,7 @@ export class CERNFields extends Component { "custom_fields.cern:programmes", "custom_fields.cern:administrative_unit", "custom_fields.cern:department", + "custom_fields.cern:committees", "custom_fields.cern:experiments", "custom_fields.cern:accelerators", "custom_fields.cern:beams", @@ -32,6 +33,7 @@ export class CERNFields extends Component { const { key, children, label, active } = this.props; const [ department, + committees, administrativeUnit, programme, accelerator, @@ -68,6 +70,7 @@ export class CERNFields extends Component { /> + {committees} {projects} {studies} {facilities} diff --git a/assets/templates/custom_fields/CERNPublication.js b/assets/templates/custom_fields/CERNPublication.js new file mode 100644 index 00000000..3a499bd8 --- /dev/null +++ b/assets/templates/custom_fields/CERNPublication.js @@ -0,0 +1,66 @@ +// 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 GPL-2.0 License; see LICENSE file for more details. + +import React, { Component } from "react"; + +import { Grid } from "semantic-ui-react"; + +import PropTypes from "prop-types"; +import { AccordionField } from "react-invenio-forms"; + +export class CERNPublication extends Component { + feedbackCfg = { + "publication-section": [ + "custom_fields.journal:journal", + "custom_fields.cern:oa_level", + "custom_fields.cern:oa_funding_model", + "custom_fields.imprint:imprint", + "custom_fields.thesis:thesis", + ], + }; + + render() { + const { key, children, label, active } = this.props; + const [journal, oaLevel, oaFundingModel, imprint, thesis] = children; + return ( + + {journal} + + {oaLevel} + {oaFundingModel} + + {imprint} + {thesis} + + ); + } +} + +CERNPublication.propTypes = { + label: PropTypes.string, + children: PropTypes.arrayOf( + PropTypes.shape({ + field: PropTypes.string.isRequired, + ui_widget: PropTypes.string.isRequired, + props: PropTypes.object, + }) + ).isRequired, + active: PropTypes.bool, + key: PropTypes.string, +}; + +CERNPublication.defaultProps = { + label: "CERN", + active: true, + key: "CERNPublication", +}; diff --git a/assets/templates/custom_fields/DepartmentDropdown.js b/assets/templates/custom_fields/DepartmentDropdown.js new file mode 100644 index 00000000..8ad048f6 --- /dev/null +++ b/assets/templates/custom_fields/DepartmentDropdown.js @@ -0,0 +1,134 @@ +// This file is part of Invenio-RDM-Records +// Copyright (C) 2020-2025 CERN. +// +// Invenio-RDM-Records is free software; you can redistribute it and/or modify it +// under the terms of the GPL-2.0 License; see LICENSE file for more details. + +import React, { Component } from "react"; +import { FieldLabel, SelectField } from "react-invenio-forms"; +import { Dropdown as SUIDropdown } from "semantic-ui-react"; +import PropTypes from "prop-types"; + +export class DepartmentDropdown extends Component { + serializeOptions = (options) => { + if (!options) return []; + + const current = options.filter((o) => o.props?.section === "current"); + const former = options.filter((o) => o.props?.section === "former"); + const other = options.filter((o) => !o.props?.section); + + const result = []; + + if (current.length > 0) { + result.push({ + key: "header-current", + text: "", + content: ( + + ), + disabled: true, + isHeader: true, + }); + current.forEach((o) => + result.push({ key: o.id, value: o.id, text: o.title_l10n }) + ); + } + + if (former.length > 0) { + result.push({ + key: "header-former", + text: "", + content: ( + + ), + disabled: true, + isHeader: true, + }); + former.forEach((o) => + result.push({ key: o.id, value: o.id, text: o.title_l10n }) + ); + } + + other.forEach((o) => + result.push({ key: o.id, value: o.id, text: o.title_l10n }) + ); + + return result; + }; + + searchFn = (options, query) => + options.filter( + (opt) => + !opt.isHeader && opt.text.toLowerCase().includes(query.toLowerCase()) + ); + + render() { + const { + fieldPath, + label, + icon, + labelIcon: labelIconProp, + description, + helpText: helpTextProp, + placeholder, + options, + multiple, + clearable, + required, + disabled, + optimized, + } = this.props; + + const helpText = helpTextProp ?? description; + const labelIcon = labelIconProp ?? icon; + + return ( + + } + options={this.serializeOptions(options)} + search={this.searchFn} + aria-label={label} + multiple={multiple} + disabled={disabled} + placeholder={{ role: "option", content: placeholder }} + clearable={clearable} + required={required} + defaultValue={multiple ? [] : ""} + helpText={helpText} + optimized={optimized} + /> + ); + } +} + +DepartmentDropdown.propTypes = { + fieldPath: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + options: PropTypes.array.isRequired, + icon: PropTypes.string, + labelIcon: PropTypes.string, + description: PropTypes.string, + helpText: PropTypes.string, + placeholder: PropTypes.string, + multiple: PropTypes.bool, + clearable: PropTypes.bool, + required: PropTypes.bool, + disabled: PropTypes.bool, + optimized: PropTypes.bool, +}; + +DepartmentDropdown.defaultProps = { + icon: undefined, + labelIcon: undefined, + description: undefined, + helpText: undefined, + placeholder: undefined, + multiple: false, + clearable: true, + required: false, + disabled: false, + optimized: true, +}; diff --git a/scripts/metadata_checks.py b/scripts/metadata_checks.py index 96321b94..bee37310 100644 --- a/scripts/metadata_checks.py +++ b/scripts/metadata_checks.py @@ -16,11 +16,11 @@ from copy import deepcopy +from flask import current_app from invenio_checks.models import CheckConfig, Severity from invenio_communities.proxies import current_communities from invenio_db import db from werkzeug.local import LocalProxy -from flask import current_app community_service = LocalProxy(lambda: current_communities.service) diff --git a/site/cds_rdm/custom_fields/__init__.py b/site/cds_rdm/custom_fields/__init__.py index a7fc352d..9970c218 100644 --- a/site/cds_rdm/custom_fields/__init__.py +++ b/site/cds_rdm/custom_fields/__init__.py @@ -18,7 +18,10 @@ MEETING_CUSTOM_FIELDS_UI, MEETING_NAMESPACE, ) -from cds_rdm.custom_fields.publishing import PUBLISHING_FIELDS_UI +from cds_rdm.custom_fields.publishing import ( + PUBLISHING_CUSTOM_FIELDS, + PUBLISHING_FIELDS_UI, +) NAMESPACES = { "cern": "https://greybook.cern.ch/", @@ -31,6 +34,7 @@ CUSTOM_FIELDS = [ *CERN_CUSTOM_FIELDS, + *PUBLISHING_CUSTOM_FIELDS, # journal *JOURNAL_CUSTOM_FIELDS, # imprint diff --git a/site/cds_rdm/custom_fields/cern.py b/site/cds_rdm/custom_fields/cern.py index ea7b45af..bbbe5b7d 100644 --- a/site/cds_rdm/custom_fields/cern.py +++ b/site/cds_rdm/custom_fields/cern.py @@ -24,6 +24,12 @@ dump_options=True, multiple=True, ), + VocabularyCF( + name="cern:committees", + vocabulary_id="committees", + dump_options=True, + multiple=True, + ), KeywordCF(name="cern:administrative_unit"), VocabularyCF( name="cern:accelerators", @@ -54,7 +60,7 @@ "fields": [ dict( field="cern:departments", - ui_widget="Dropdown", + ui_widget="DepartmentDropdown", landing_page_search_attr="id", display_url="https://scientific-info.cern/archives/history_CERN/internal_organisation/20s", props=dict( @@ -68,6 +74,21 @@ autocompleteFrom="/api/vocabularies/departments", ), ), + dict( + field="cern:committees", + ui_widget="Dropdown", + landing_page_search_attr="id", + props=dict( + label="Committee", + icon="users", + description="Please select a CERN committee related to this record if applicable.", + search=True, + multiple=True, + sort_by="title_sort", + clearable=True, + autocompleteFrom="/api/vocabularies/committees", + ), + ), dict( field="cern:administrative_unit", ui_widget="Input", diff --git a/site/cds_rdm/custom_fields/publishing.py b/site/cds_rdm/custom_fields/publishing.py index 28eb9736..73fe30a7 100644 --- a/site/cds_rdm/custom_fields/publishing.py +++ b/site/cds_rdm/custom_fields/publishing.py @@ -11,14 +11,60 @@ from invenio_rdm_records.contrib.imprint import IMPRINT_CUSTOM_FIELDS_UI from invenio_rdm_records.contrib.journal import JOURNAL_CUSTOM_FIELDS_UI from invenio_rdm_records.contrib.thesis import THESIS_CUSTOM_FIELDS_UI +from invenio_vocabularies.services.custom_fields import VocabularyCF + +PUBLISHING_CUSTOM_FIELDS = [ + VocabularyCF( + name="cern:oa_level", + vocabulary_id="open_access_levels", + dump_options=True, + multiple=False, + ), + VocabularyCF( + name="cern:oa_funding_model", + vocabulary_id="open_access_funding_models", + dump_options=True, + multiple=False, + ), +] PUBLISHING_FIELDS_UI = { "section": _("Publishing information (Imprint, Journal, Thesis)"), - "hide_from_landing_page": True, # hide meeting section from Additional details in landing page + "hide_from_landing_page": True, + # hide meeting section from Additional details in landing page + "ui_widget": "CERNPublication", "active": True, # collapsed by default "fields": [ # journal - *JOURNAL_CUSTOM_FIELDS_UI["fields"], + *JOURNAL_CUSTOM_FIELDS_UI["fields"] + [ + dict( + field="cern:oa_level", + ui_widget="Dropdown", + props=dict( + label=_("Open Access Level"), + icon="lock open", + description=_("Select the open access level of this record."), + search=True, + multiple=False, + clearable=True, + autocompleteFrom="/api/vocabularies/open_access_levels", + ), + ), + dict( + field="cern:oa_funding_model", + ui_widget="Dropdown", + props=dict( + label=_("Publication funding model"), + icon="dollar sign", + description=_( + "Select how open access was obtained for this record."), + search=True, + multiple=False, + clearable=True, + autocompleteFrom="/api/vocabularies/open_access_funding_models", + ), + ), + ], # imprint *IMPRINT_CUSTOM_FIELDS_UI["fields"], # thesis diff --git a/site/cds_rdm/legacy/redirector.py b/site/cds_rdm/legacy/redirector.py index 8999ebbc..71a407e6 100644 --- a/site/cds_rdm/legacy/redirector.py +++ b/site/cds_rdm/legacy/redirector.py @@ -11,14 +11,7 @@ from pathlib import Path from urllib.parse import unquote -from flask import ( - Blueprint, - current_app, - redirect, - render_template, - request, - url_for, -) +from flask import Blueprint, current_app, redirect, render_template, request, url_for from flask_login import current_user from invenio_app_rdm.records_ui.views.records import record_tombstone_error from invenio_base import invenio_url_for diff --git a/site/cds_rdm/vcs/handlers.py b/site/cds_rdm/vcs/handlers.py index f533127d..912e8dda 100644 --- a/site/cds_rdm/vcs/handlers.py +++ b/site/cds_rdm/vcs/handlers.py @@ -11,10 +11,7 @@ from flask_login import current_user -from cds_rdm.errors import ( - GitLabIdentityNotFoundError, - KeycloakGitLabMismatchError, -) +from cds_rdm.errors import GitLabIdentityNotFoundError, KeycloakGitLabMismatchError def gitlab_account_info_serializer(original_serializer):