Skip to content
Snippets Groups Projects
Commit b57e8188 authored by Simon Delcamp's avatar Simon Delcamp
Browse files

Merge branch '793-improve-the-mint-doi-panel' into 'main'

Resolve "Improve the Mint DOI panel"

Closes #793

See merge request !689
parents 888548f2 f3760436
No related branches found
No related tags found
1 merge request!689Resolve "Improve the Mint DOI panel"
Pipeline #221832 waiting for manual action
......@@ -31,8 +31,10 @@
"doi": {
"link": "https://doi.esrf.fr/",
"minimalAbstractLength": 150,
"minimalTitleLength": 40,
"facilityPrefix": "10.15151",
"facilitySuffix": "ESRF-DC"
"facilitySuffix": "ESRF-DC",
"referenceDoi": "https://doi.esrf.fr/10.15151/ESRF-DC-2011729981"
},
"fileBrowser": {
"maxFileNb": 1000
......
......@@ -37,8 +37,10 @@
"doi": {
"link": "https://doi.esrf.fr/",
"minimalAbstractLength": 150,
"minimalTitleLength": 40,
"facilityPrefix": "10.15151",
"facilitySuffix": "ESRF-DC"
"facilitySuffix": "ESRF-DC",
"referenceDoi": "https://doi.esrf.fr/10.15151/ESRF-DC-2011729981"
},
"fileBrowser": {
"maxFileNb": 1000
......
import { Button, Modal, Spinner } from 'react-bootstrap';
import { Button, Modal, Spinner, Form } from 'react-bootstrap';
import { useState } from 'react';
import { ORCID } from '@edata-portal/core';
import { useConfig } from '@edata-portal/core';
export function MintDOIModal({
show,
......@@ -15,39 +18,74 @@ export function MintDOIModal({
data: any; // TODO : type to be updated when endpoint will be updated
submitting: boolean;
}) {
const [certify, setCertify] = useState(false);
const config = useConfig();
const onClose = () => {
setCertify(false);
onCancel();
};
return (
<Modal show={show} onHide={onCancel} size="lg">
<Modal show={show} onHide={onClose} size="lg" scrollable={true}>
<Modal.Header closeButton>
<Modal.Title>Confirmation</Modal.Title>
</Modal.Header>
{data !== null && (
<Modal.Body>
<p>
Minting a DOI is <b>irreversible</b>. Please carefully review the
following points before proceeding:
DOIs are a system of persistent identifiers, therefore minting a DOI
is permanent i.e. <strong>irreversible</strong>. Data DOIs are like
publications, they should be as clear as possible. Here is an
example of a well formatted{' '}
<a
href={config.ui.doi.referenceDoi}
target="_blank"
rel="noreferrer"
>
DOI.
</a>
<p>
We kindly ask you to please carefully review the following points
before clicking on <strong>Mint</strong>:
</p>
</p>
<ul>
<li className="p-2 ">
<li className="p-2">
<strong>
{' '}
Number of dataset{data.datasetIdList.length > 1
? 's'
: ''}:{' '}
</strong>
{data.datasetIdList.length}
</li>
<li className="p-2">
<strong>Title</strong> : Ensure it provides a concise and
descriptive name for the data, offering a clear understanding of
its content.
<div className="fst-italic">{data.title}</div>
<div className="fst-italic p-2">{data.title}</div>
</li>
<li className="p-2">
<strong>Abstract</strong> : Confirm it provides detailed
information about the resource, explaining its purpose and
significance.
<div className="fst-italic">{data.abstract}</div>
information about the data pointed to by the DOI, explaining what
they represent, their purpose and significance. Add additional
information about the files included.
<div className="fst-italic p-2">{data.abstract}</div>
</li>
<li className="p-2">
<strong>Authors</strong>: Double-check the list of authors, ensure
their order is correct, and include their ORCID IDs wherever
possible.
their order is correct (first author on top), and include their
ORCID IDs wherever possible. The order of authors can be modified
by selecting an author and moving the author up or down.
<ul className="fst-italic">
{data.authors.map((authors: any, index: any) => (
<li key={authors.name}>
{authors.name}, {authors.surname}, {authors.orcid}
<li key={authors.name} className="p-1">
{authors.name}, {authors.surname}
{authors.orcid !== '' && (
<>
, <ORCID orcid={authors.orcid} isCompactView={true} />
</>
)}
</li>
))}
</ul>
......@@ -95,12 +133,31 @@ export function MintDOIModal({
</ul>
</Modal.Body>
)}
<Form.Check
type="switch"
id="switch-herby"
checked={certify}
label={
'I confirm that there are no mistake in the fields above and that they help make the data interoperable and reusable. I want to proceed to mint the DOI.'
}
onChange={(e) => {
setCertify(e.currentTarget.checked);
}}
className="m-2"
required
/>
<div className="justify-content-left p-1">
<Button onClick={onMint} className="m-1" variant="primary">
<Button
onClick={onMint}
className="m-1"
variant="primary"
disabled={!certify}
>
{submitting ? <Spinner size="sm" /> : 'Mint DOI'}
</Button>
<Button onClick={onCancel} className="m-1" variant="danger">
Cancel
<Button onClick={onClose} className="m-1" variant="danger">
Return
</Button>
</div>
</Modal>
......
......@@ -144,6 +144,7 @@ function FormSection({
type: 'textarea',
label: 'Title',
required: true,
minLength: config.ui.doi.minimalTitleLength,
},
abstract: {
type: 'textarea',
......
import {
faArrowDown,
faArrowUp,
faBars,
faPlus,
faRemove,
faTrash,
faEllipsis,
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import type {
......@@ -61,6 +61,172 @@ export function RenderFormArray({
<Card className={error ? 'border-danger' : ''}>
<Card.Body className="p-2">
<Row className="g-2">
{resolvedDescription.addFromPreset?.length ? (
<Col xs={'auto'}>
<ReactSelect
menuPortalTarget={document.body}
placeholder={`Select an ${labelSingular} to add...`}
isClearable={false}
value={null}
options={resolvedDescription.addFromPreset}
onChange={(v) => {
if (v?.value) {
fields.push(v.value);
}
}}
/>
</Col>
) : null}
{fields?.length ? (
<small>
<Table
size="sm"
responsive
hover
borderless
className="mt-2"
>
<tbody>
{reorderedIndexesWithDragState.map(
(originalIndex, currentIndex) => {
const newPath = `${path}.${originalIndex}`;
return (
<tr
key={originalIndex}
onDragOver={(e) => {
setDraggingOver(currentIndex);
}}
>
{enableDragNDrop ? (
<td
style={{
width: 1,
verticalAlign: 'middle',
cursor: 'move',
fontSize: '1.5em',
}}
draggable={enableDragNDrop}
//drag for desktops
onDragStart={(e) => {
setDragging(originalIndex);
//no image for drag
e.dataTransfer.setDragImage(
document.createElement('div'),
0,
0,
);
}}
onDragEnd={(e) => {
if (dragging !== undefined) {
fields.move(dragging, currentIndex);
}
setDragging(undefined);
setDraggingOver(undefined);
}}
>
<FontAwesomeIcon
icon={faEllipsis}
className="me-1 mt-3 "
/>
</td>
) : (
<>
<td
style={{
width: 1,
verticalAlign: 'top',
}}
>
{originalIndex === 0 ? null : (
<Button
className="p-0 text-info"
variant="link"
onClick={() => {
fields.move(
originalIndex,
originalIndex - 1,
);
}}
disabled={
resolvedDescription.readonly
}
style={{
fontSize: '1.5em',
}}
>
<FontAwesomeIcon icon={faArrowUp} />
</Button>
)}
</td>
<td
style={{
width: 1,
verticalAlign: 'top',
}}
>
{fields.length &&
originalIndex ===
fields.length - 1 ? null : (
<Button
className="p-0 text-info"
variant="link"
onClick={() => {
fields.move(
originalIndex,
originalIndex + 1,
);
}}
disabled={
resolvedDescription.readonly
}
style={{
fontSize: '1.5em',
}}
>
<FontAwesomeIcon icon={faArrowDown} />
</Button>
)}
</td>
</>
)}
<td>
<Row className="g-2">
<RenderFormObject
description={resolvedDescription.item}
path={newPath}
/>
</Row>
</td>
<td
style={{
width: 1,
verticalAlign: enableDragNDrop
? 'middle'
: 'top',
}}
>
<Button
className="p-0 text-danger"
variant="link"
onClick={() => {
fields.remove(originalIndex);
}}
disabled={resolvedDescription.readonly}
style={{
fontSize: '1.5em',
}}
>
<FontAwesomeIcon icon={faRemove} />
</Button>
</td>
</tr>
);
},
)}
</tbody>
</Table>
</small>
) : null}
{resolvedDescription.newItem ? (
<Col xs={'auto'}>
<Button
......@@ -91,163 +257,7 @@ export function RenderFormArray({
Clear all {labelPlural}
</Button>
</Col>
{resolvedDescription.addFromPreset?.length ? (
<Col xs={'auto'}>
<ReactSelect
menuPortalTarget={document.body}
placeholder={`Select an ${labelSingular} to add...`}
isClearable={false}
value={null}
options={resolvedDescription.addFromPreset}
onChange={(v) => {
if (v?.value) {
fields.push(v.value);
}
}}
/>
</Col>
) : null}
</Row>
{fields?.length ? (
<small>
<Table size="sm" responsive hover borderless className="mt-2">
<tbody>
{reorderedIndexesWithDragState.map(
(originalIndex, currentIndex) => {
const newPath = `${path}.${originalIndex}`;
return (
<tr
key={originalIndex}
onDragOver={(e) => {
setDraggingOver(currentIndex);
}}
>
{enableDragNDrop ? (
<td
style={{
width: 1,
verticalAlign: 'middle',
cursor: 'move',
fontSize: '1.5em',
}}
draggable={enableDragNDrop}
//drag for desktops
onDragStart={(e) => {
setDragging(originalIndex);
//no image for drag
e.dataTransfer.setDragImage(
document.createElement('div'),
0,
0,
);
}}
onDragEnd={(e) => {
if (dragging !== undefined) {
fields.move(dragging, currentIndex);
}
setDragging(undefined);
setDraggingOver(undefined);
}}
>
<FontAwesomeIcon
icon={faBars}
className="me-1"
/>
</td>
) : (
<>
<td
style={{
width: 1,
verticalAlign: 'top',
}}
>
{originalIndex === 0 ? null : (
<Button
className="p-0 text-info"
variant="link"
onClick={() => {
fields.move(
originalIndex,
originalIndex - 1,
);
}}
disabled={resolvedDescription.readonly}
style={{
fontSize: '1.5em',
}}
>
<FontAwesomeIcon icon={faArrowUp} />
</Button>
)}
</td>
<td
style={{
width: 1,
verticalAlign: 'top',
}}
>
{fields.length &&
originalIndex ===
fields.length - 1 ? null : (
<Button
className="p-0 text-info"
variant="link"
onClick={() => {
fields.move(
originalIndex,
originalIndex + 1,
);
}}
disabled={resolvedDescription.readonly}
style={{
fontSize: '1.5em',
}}
>
<FontAwesomeIcon icon={faArrowDown} />
</Button>
)}
</td>
</>
)}
<td>
<Row className="g-2">
<RenderFormObject
description={resolvedDescription.item}
path={newPath}
/>
</Row>
</td>
<td
style={{
width: 1,
verticalAlign: enableDragNDrop
? 'middle'
: 'top',
}}
>
<Button
className="p-0 text-danger"
variant="link"
onClick={() => {
fields.remove(originalIndex);
}}
disabled={resolvedDescription.readonly}
style={{
fontSize: '1.5em',
}}
>
<FontAwesomeIcon icon={faRemove} />
</Button>
</td>
</tr>
);
},
)}
</tbody>
</Table>
</small>
) : null}
</Card.Body>
</Card>
);
......
......@@ -18,8 +18,10 @@ export interface UIConfig {
doi: {
link: string;
minimalAbstractLength: number;
minimalTitleLength: number;
facilityPrefix: string;
facilitySuffix: string;
referenceDoi: string;
};
fileBrowser: {
maxFileNb: number;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment