Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 4 additions & 24 deletions assets/js/components/record_details/CreatePublicRecordModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@

import React, { Component } from "react";
import PropTypes from "prop-types";
import {
Button,
Checkbox,
Header,
Icon,
Message,
Modal,
} from "semantic-ui-react";
import { Button, Checkbox, Header, Icon, Message, Modal } from "semantic-ui-react";

Check failure on line 9 in assets/js/components/record_details/CreatePublicRecordModal.js

View workflow job for this annotation

GitHub Actions / JS

Replace `·Button,·Checkbox,·Header,·Icon,·Message,·Modal·` with `⏎··Button,⏎··Checkbox,⏎··Header,⏎··Icon,⏎··Message,⏎··Modal,⏎`
import { http } from "react-invenio-forms";
import { i18next } from "@translations/invenio_rdm_records/i18next";

Expand Down Expand Up @@ -120,9 +113,7 @@
</Message>
) : publicRecord ? (
<Message positive>
<Message.Header>
{i18next.t("Public record created")}
</Message.Header>
<Message.Header>{i18next.t("Public record created")}</Message.Header>

Check failure on line 116 in assets/js/components/record_details/CreatePublicRecordModal.js

View workflow job for this annotation

GitHub Actions / JS

Replace `{i18next.t("Public·record·created")}` with `⏎················{i18next.t("Public·record·created")}⏎··············`
<Message.Content>
{i18next.t("The public record has been created successfully.")}{" "}
<a
Expand All @@ -149,9 +140,7 @@

<Checkbox
checked={agreedToTerms}
onChange={(_, { checked }) =>
this.setState({ agreedToTerms: checked })
}
onChange={(_, { checked }) => this.setState({ agreedToTerms: checked })}

Check failure on line 143 in assets/js/components/record_details/CreatePublicRecordModal.js

View workflow job for this annotation

GitHub Actions / JS

Replace `·this.setState({·agreedToTerms:·checked·})` with `⏎··················this.setState({·agreedToTerms:·checked·})⏎················`
label={
<label>
{i18next.t(
Expand Down Expand Up @@ -213,11 +202,7 @@
)}
</Modal.Content>
<Modal.Actions>
<Button
floated="left"
onClick={this.handleClose}
disabled={submitting}
>
<Button floated="left" onClick={this.handleClose} disabled={submitting}>

Check failure on line 205 in assets/js/components/record_details/CreatePublicRecordModal.js

View workflow job for this annotation

GitHub Actions / JS

Replace `·floated="left"·onClick={this.handleClose}·disabled={submitting}` with `⏎············floated="left"⏎············onClick={this.handleClose}⏎············disabled={submitting}⏎··········`
{publicRecord ? i18next.t("Close") : i18next.t("Cancel")}
</Button>
{!publicRecord && (
Expand All @@ -238,11 +223,6 @@
CreatePublicRecordModal.propTypes = {
open: PropTypes.bool.isRequired,
record: PropTypes.object.isRequired,
approvedReportNumber: PropTypes.string,
onClose: PropTypes.func.isRequired,
onSuccess: PropTypes.func.isRequired,
};

CreatePublicRecordModal.defaultProps = {
approvedReportNumber: null,
};
60 changes: 32 additions & 28 deletions assets/js/components/record_details/EPApproval.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@
if (epApproval.is_public_approved_record) {
const {
approved_report_number: pubRn,
draft_record_id,
can_view_reviewed_version,
draft_record_id: draftRecordId,
can_view_reviewed_version: canViewReviewedVersion,
} = epApproval;
return (
<Grid.Column className="pb-20 pt-0">
Expand All @@ -150,11 +150,11 @@
{pubRn
? i18next.t("EP-approved as {{rn}}", { rn: pubRn })
: i18next.t("EP-approved record")}
{can_view_reviewed_version && draft_record_id && (
{canViewReviewedVersion && draftRecordId && (
<>
{" · "}
<a
href={`/records/${draft_record_id}`}
href={`/records/${draftRecordId}`}
target="_blank"
rel="noreferrer"
>
Expand All @@ -169,44 +169,44 @@
}

const {
can_submit,
can_create_public,
open_request,
approved_report_number,
receiver_group,
ep_approval,
can_submit: canSubmit,
can_create_public: canCreatePublicFlag,
open_request: openRequest,
approved_report_number: approvedReportNumber,
receiver_group: receiverGroup,
ep_approval: epApprovalField,
} = epApproval;

// Public record URL: prefer the URL captured at creation time; fall back to
// the recid stored on the parent (approved_public_version) for page-load case.
const resolvedPublicRecordUrl =
publicRecordUrl ||
(ep_approval?.approved_public_version
? `/records/${ep_approval.approved_public_version}`
(epApprovalField?.approved_public_version
? `/records/${epApprovalField.approved_public_version}`
: null);

const isPending = open_request?.status === "submitted";
const isDeclined = open_request?.status === "declined";
const isAccepted = open_request?.status === "accepted";
// approved_report_number is always populated by the backend (scans the full
const isPending = openRequest?.status === "submitted";
const isDeclined = openRequest?.status === "declined";
const isAccepted = openRequest?.status === "accepted";
// approvedReportNumber is always populated by the backend (scans the full
// parent if the current version doesn't carry the CF itself).
const canResubmit =
can_submit && !isPending && !approved_report_number && !isAccepted;
// can_create_public comes from the backend and already encodes version-order
canSubmit && !isPending && !approvedReportNumber && !isAccepted;
// canCreatePublicFlag comes from the backend and already encodes version-order
// eligibility (only versions >= the approved version may create a public record).
const canCreatePublic = can_create_public && !publicRecordId;
const canCreatePublic = canCreatePublicFlag && !publicRecordId;

const requestLink =
open_request?.links?.self_html ||
(open_request?.id ? `/requests/${open_request.id}` : null);
openRequest?.links?.self_html ||
(openRequest?.id ? `/requests/${openRequest.id}` : null);

// Timeline step states
// Step 1 — Request for approval
const step1Completed = !!approved_report_number;
const step1Completed = !!approvedReportNumber;
const step1Active = !step1Completed && !isPending;

// Step 2 — EP Board review
const step2Completed = !!approved_report_number;
const step2Completed = !!approvedReportNumber;
const step2Active = isPending;
const step2Disabled = !isPending && !step2Completed;

Expand Down Expand Up @@ -280,7 +280,7 @@
<EPApprovalSubmitModal
open={submitModalOpen}
record={record}
receiverGroup={receiver_group}
receiverGroup={receiverGroup}
onClose={() => this.setState({ submitModalOpen: false })}
onSuccess={this.handleSubmitSuccess}
/>
Expand All @@ -300,15 +300,19 @@
<Step.Description>
{step2Completed ? (
requestLink ? (
<a href={requestLink} target="_blank" rel="noreferrer">
<a

Check failure on line 303 in assets/js/components/record_details/EPApproval.js

View workflow job for this annotation

GitHub Actions / JS

Replace `⏎··························href={requestLink}⏎··························target="_blank"⏎··························rel="noreferrer"⏎························` with `·href={requestLink}·target="_blank"·rel="noreferrer"`
href={requestLink}
target="_blank"
rel="noreferrer"
>
{i18next.t("Approved as {{rn}}", {
rn: approved_report_number,
rn: approvedReportNumber,
})}
<Icon name="external alternate" className="ml-5" />
</a>
) : (
i18next.t("Approved as {{rn}}", {
rn: approved_report_number,
rn: approvedReportNumber,
})
)
) : (
Expand Down Expand Up @@ -384,7 +388,7 @@
<CreatePublicRecordModal
open={createPublicModalOpen}
record={record}
approvedReportNumber={approved_report_number}
approvedReportNumber={approvedReportNumber}
onClose={() => this.setState({ createPublicModalOpen: false })}
onSuccess={this.handlePublicRecordCreated}
/>
Expand Down
22 changes: 4 additions & 18 deletions assets/js/components/requests/EPApprovalRequestDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import { Timeline } from "@js/invenio_requests/timelineParent";
import RequestMetadata from "@js/invenio_requests/request/RequestMetadata";

const BoolCell = ({ value }) => (
<>{value ? i18next.t("Yes") : i18next.t("No")}</>
);
const BoolCell = ({ value }) => <>{value ? i18next.t("Yes") : i18next.t("No")}</>;

Check warning on line 14 in assets/js/components/requests/EPApprovalRequestDetails.js

View workflow job for this annotation

GitHub Actions / JS

Fragments should contain more than one child - otherwise, there’s no need for a Fragment at all

Check failure on line 14 in assets/js/components/requests/EPApprovalRequestDetails.js

View workflow job for this annotation

GitHub Actions / JS

Replace `<>{value·?·i18next.t("Yes")·:·i18next.t("No")}</>` with `(⏎··<>{value·?·i18next.t("Yes")·:·i18next.t("No")}</>⏎)`

BoolCell.propTypes = { value: PropTypes.bool.isRequired };

Expand Down Expand Up @@ -50,11 +48,7 @@
<Table.Row>
<Table.Cell>{i18next.t("Latest version at")}</Table.Cell>
<Table.Cell>
<a
href={payload.latest_version_url}
target="_blank"
rel="noreferrer"
>
<a href={payload.latest_version_url} target="_blank" rel="noreferrer">

Check failure on line 51 in assets/js/components/requests/EPApprovalRequestDetails.js

View workflow job for this annotation

GitHub Actions / JS

Replace `·href={payload.latest_version_url}·target="_blank"·rel="noreferrer"` with `⏎················href={payload.latest_version_url}⏎················target="_blank"⏎················rel="noreferrer"⏎··············`
{payload.latest_version_url}
</a>
</Table.Cell>
Expand All @@ -76,11 +70,11 @@
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>{i18next.t("Paper signed by whole collaboration")}</Table.Cell>

Check failure on line 73 in assets/js/components/requests/EPApprovalRequestDetails.js

View workflow job for this annotation

GitHub Actions / JS

Replace `{i18next.t("Paper·signed·by·whole·collaboration")}` with `⏎············{i18next.t("Paper·signed·by·whole·collaboration")}⏎··········`
<Table.Cell>
<BoolCell value={!!payload.paper_signed} />
{!payload.paper_signed && payload.num_non_signers > 0 && (
<> — {i18next.t("{{n}} non-signer(s)", { n: payload.num_non_signers })}</>

Check failure on line 77 in assets/js/components/requests/EPApprovalRequestDetails.js

View workflow job for this annotation

GitHub Actions / JS

Replace `·—·{i18next.t("{{n}}·non-signer(s)",·{·n:·payload.num_non_signers·})}` with `⏎················{"·"}⏎················—{"·"}⏎················{i18next.t("{{n}}·non-signer(s)",·{⏎··················n:·payload.num_non_signers,⏎················})}⏎··············`
)}
</Table.Cell>
</Table.Row>
Expand Down Expand Up @@ -127,18 +121,10 @@
<Grid stackable reversed="mobile">
<Grid.Column mobile={16} tablet={12} computer={13}>
{isEPApproval && <EPApprovalPayloadCard request={request} />}
<Timeline
userAvatar={userAvatar}
request={request}
permissions={permissions}
/>
<Timeline userAvatar={userAvatar} request={request} permissions={permissions} />

Check failure on line 124 in assets/js/components/requests/EPApprovalRequestDetails.js

View workflow job for this annotation

GitHub Actions / JS

Replace `·userAvatar={userAvatar}·request={request}·permissions={permissions}` with `⏎··········userAvatar={userAvatar}⏎··········request={request}⏎··········permissions={permissions}⏎·······`
</Grid.Column>
<Grid.Column mobile={16} tablet={4} computer={3}>
<RequestMetadata
request={request}
permissions={permissions}
config={config}
/>
<RequestMetadata request={request} permissions={permissions} config={config} />
</Grid.Column>
</Grid>
);
Expand Down
22 changes: 14 additions & 8 deletions invenio.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ CDS_EOS_OFFLOAD_X509_KEY_PATH = ""
# check nginx config for more details
CDS_EOS_OFFLOAD_REDIRECT_BASE_PATH = ""

CDS_CERN_SCIENTIFIC_COMMUNITY_ID = "5ad76c90-e035-401e-ac52-9aab978955a1"
CDS_CERN_SCIENTIFIC_COMMUNITY_ID = ""
"""The id of the CERN Scientific community."""

# EP / Publication Approval Workflow
Expand All @@ -456,19 +456,25 @@ CDS_EP_APPROVAL_COMMUNITIES = {
# Map community UUID → workflow config.
# UUIDs are used (not slugs) because slugs can be renamed.
#
"8665a816-6bea-4afd-b605-66e676621f43": {
"label": "EP approval", # shown in UI buttons/headings
"referee_group": "ep-test", # CERN e-group slug
"report_number_pattern": "CERN-EP-{year}-{seq:03d}",
},
# "4b121eb9-3559-487d-9f73-8af1027668e9": {
# "label": "EP approval", # shown in UI buttons/headings
# "referee_group": "cds-ph-ep-publication", # CERN e-group slug
# "report_number": {
# "prefix": "CERN-EP", # literal prefix, e.g. "CERN-EP"
# "include_year": True, # append the current year after prefix
# "counter_digits": 3, # zero-padding width, e.g. 3 → "001"
# },
# },
}
"""Communities enrolled in the Publication Approval Workflow.

Keyed by community UUID. Each entry must have:
- ``label``: human-readable name shown in the UI (e.g. "EP approval")
- ``referee_group``: CERN e-group whose members act as referees
- ``report_number_pattern``: Python format string with ``{year}`` and
``{seq:03d}`` placeholders (e.g. ``"CERN-EP-{year}-{seq:03d}"``).
- ``report_number``: dict with:
- ``prefix`` (str): fixed prefix, e.g. ``"CERN-EP"``
- ``include_year`` (bool, default True): append ``-{year}`` after prefix
- ``counter_digits`` (int, default 3): zero-padding for the counter

All generated numbers share the ``apprn`` PID type, so uniqueness is
enforced across all enrolled communities.
Expand Down
10 changes: 3 additions & 7 deletions site/cds_rdm/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

"""CDS RDM service components."""

import re

from flask import current_app
from flask_principal import ActionNeed
from invenio_access import Permission
Expand Down Expand Up @@ -158,17 +156,15 @@ def _is_privileged(self, identity):
).allows(identity)

def _ep_approval_prefixes(self):
"""Return the set of fixed prefixes from all configured EP patterns.
"""Return the set of fixed prefixes from all configured EP communities.

E.g. pattern "CERN-EP-{year}-{seq:03d}" → prefix "CERN-EP-".
E.g. config ``{"prefix": "CERN-EP"}`` → prefix ``"CERN-EP"``.
Used to detect cdsrn values that collide with EP report numbers.
"""
communities = current_app.config.get("CDS_EP_APPROVAL_COMMUNITIES", {})
prefixes = set()
for cfg in communities.values():
pattern = cfg.get("report_number_pattern", "")
# Extract the literal part before the first placeholder.
prefix = re.split(r"\{", pattern)[0]
prefix = cfg.get("report_number", {}).get("prefix")
if prefix:
prefixes.add(prefix)
return prefixes
Expand Down
2 changes: 1 addition & 1 deletion site/cds_rdm/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
from cds_rdm.clc_sync.resources.config import CLCSyncResourceConfig
from cds_rdm.clc_sync.resources.resource import CLCSyncResource
from cds_rdm.clc_sync.resources.utils import get_clc_sync_entry
from cds_rdm.requests.ep_approval_state import get_ep_approval_state
from cds_rdm.clc_sync.services.config import CLCSyncServiceConfig
from cds_rdm.clc_sync.services.service import CLCSyncService
from cds_rdm.harvester_download.resources import (
HarvesterDownloadResource,
HarvesterDownloadResourceConfig,
)
from cds_rdm.requests.ep_approval_state import get_ep_approval_state

from . import config
from .utils import evaluate_permissions
Expand Down
Loading
Loading