@manuscripts/body-editor 3.12.17 → 3.12.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/commands.js +16 -24
- package/dist/cjs/components/affiliations/AffiliationForm.js +5 -6
- package/dist/cjs/components/affiliations/AffiliationsModal.js +21 -57
- package/dist/cjs/components/affiliations/AffiliationsPanel.js +22 -0
- package/dist/cjs/components/authors/AuthorDetailsForm.js +3 -4
- package/dist/cjs/components/authors/AuthorsModal.js +15 -48
- package/dist/cjs/components/authors/AuthorsPanel.js +18 -0
- package/dist/cjs/components/authors/useManageAffiliations.js +6 -4
- package/dist/cjs/components/authors-affiliations/AuthorsAndAffiliationsModals.js +134 -0
- package/dist/cjs/components/authors-affiliations/GenericPanel.js +136 -0
- package/dist/cjs/components/form/ModalFormActions.js +11 -5
- package/dist/cjs/keys/title.js +24 -10
- package/dist/cjs/lib/__tests__/plugins.test.js +2 -2
- package/dist/cjs/lib/context-menu.js +8 -9
- package/dist/cjs/plugins/objects.js +24 -19
- package/dist/cjs/versions.js +1 -1
- package/dist/cjs/views/affiliations.js +5 -11
- package/dist/cjs/views/caption.js +1 -1
- package/dist/cjs/views/contributors.js +4 -7
- package/dist/cjs/views/figure.js +0 -1
- package/dist/es/commands.js +16 -24
- package/dist/es/components/affiliations/AffiliationForm.js +5 -6
- package/dist/es/components/affiliations/AffiliationsModal.js +21 -53
- package/dist/es/components/affiliations/AffiliationsPanel.js +15 -0
- package/dist/es/components/authors/AuthorDetailsForm.js +3 -4
- package/dist/es/components/authors/AuthorsModal.js +15 -45
- package/dist/es/components/authors/AuthorsPanel.js +11 -0
- package/dist/es/components/authors/useManageAffiliations.js +7 -5
- package/dist/es/components/authors-affiliations/AuthorsAndAffiliationsModals.js +93 -0
- package/dist/es/components/authors-affiliations/GenericPanel.js +94 -0
- package/dist/es/components/form/ModalFormActions.js +11 -5
- package/dist/es/keys/title.js +24 -10
- package/dist/es/lib/__tests__/plugins.test.js +2 -2
- package/dist/es/lib/context-menu.js +8 -9
- package/dist/es/plugins/objects.js +25 -20
- package/dist/es/versions.js +1 -1
- package/dist/es/views/affiliations.js +5 -11
- package/dist/es/views/caption.js +1 -1
- package/dist/es/views/contributors.js +5 -8
- package/dist/es/views/figure.js +0 -1
- package/dist/types/components/affiliations/AffiliationForm.d.ts +1 -0
- package/dist/types/components/affiliations/AffiliationsModal.d.ts +2 -5
- package/dist/types/components/affiliations/AffiliationsPanel.d.ts +11 -0
- package/dist/types/components/authors/AuthorDetailsForm.d.ts +1 -0
- package/dist/types/components/authors/AuthorsModal.d.ts +2 -4
- package/dist/types/components/authors/AuthorsPanel.d.ts +13 -0
- package/dist/types/components/authors/useManageAffiliations.d.ts +0 -2
- package/dist/types/components/authors-affiliations/AuthorsAndAffiliationsModals.d.ts +29 -0
- package/dist/types/components/authors-affiliations/GenericPanel.d.ts +48 -0
- package/dist/types/components/form/ModalFormActions.d.ts +1 -0
- package/dist/types/versions.d.ts +1 -1
- package/package.json +3 -3
- package/styles/AdvancedEditor.css +18 -48
- package/styles/Editor.css +28 -63
- package/dist/cjs/components/authors/AffiliationDrawer.js +0 -24
- package/dist/es/components/authors/AffiliationDrawer.js +0 -17
- package/dist/types/components/authors/AffiliationDrawer.d.ts +0 -12
package/dist/es/commands.js
CHANGED
|
@@ -33,8 +33,7 @@ import { getEditorProps } from './plugins/editor-props';
|
|
|
33
33
|
import { searchReplaceKey } from './plugins/search-replace';
|
|
34
34
|
import { checkForCompletion } from './plugins/section_title/autocompletion';
|
|
35
35
|
import { persistentCursor } from './plugins/persistent-cursor';
|
|
36
|
-
import {
|
|
37
|
-
import { openAuthorsModal } from './components/authors/AuthorsModal';
|
|
36
|
+
import { openAuthorsAndAffiliationsModals } from './components/authors-affiliations/AuthorsAndAffiliationsModals';
|
|
38
37
|
export const addToStart = (state, dispatch) => {
|
|
39
38
|
const { selection } = state;
|
|
40
39
|
const props = getEditorProps(state);
|
|
@@ -176,7 +175,7 @@ export const createBlock = (nodeType, position, state, dispatch, attrs) => {
|
|
|
176
175
|
case schema.nodes.listing_element:
|
|
177
176
|
node = schema.nodes.listing_element.create({}, [
|
|
178
177
|
schema.nodes.listing.create(),
|
|
179
|
-
|
|
178
|
+
...createAndFillCaption(),
|
|
180
179
|
]);
|
|
181
180
|
break;
|
|
182
181
|
case schema.nodes.equation_element:
|
|
@@ -244,10 +243,7 @@ export const insertFigure = (file, state, dispatch) => {
|
|
|
244
243
|
});
|
|
245
244
|
const element = state.schema.nodes.figure_element.createAndFill({}, [
|
|
246
245
|
figure,
|
|
247
|
-
|
|
248
|
-
state.schema.nodes.caption_title.create(),
|
|
249
|
-
state.schema.nodes.caption.create(),
|
|
250
|
-
]),
|
|
246
|
+
schema.nodes.caption.create(undefined, schema.nodes.text_block.create()),
|
|
251
247
|
]);
|
|
252
248
|
const tr = state.tr.insert(position, element);
|
|
253
249
|
dispatch(tr);
|
|
@@ -262,7 +258,7 @@ export const insertEmbed = (state, dispatch, attrs) => {
|
|
|
262
258
|
...attrs,
|
|
263
259
|
id: generateNodeID(schema.nodes.embed),
|
|
264
260
|
}, [
|
|
265
|
-
|
|
261
|
+
...createAndFillCaption(),
|
|
266
262
|
schema.nodes.alt_text.create(),
|
|
267
263
|
schema.nodes.long_desc.create(),
|
|
268
264
|
]);
|
|
@@ -286,12 +282,7 @@ export const insertSupplement = (file, view) => {
|
|
|
286
282
|
const supplement = schema.nodes.supplement.createAndFill({
|
|
287
283
|
id: generateNodeID(schema.nodes.supplement),
|
|
288
284
|
href: file.id,
|
|
289
|
-
},
|
|
290
|
-
schema.nodes.figcaption.create({}, [
|
|
291
|
-
schema.nodes.caption_title.create(),
|
|
292
|
-
schema.nodes.caption.create(),
|
|
293
|
-
]),
|
|
294
|
-
]);
|
|
285
|
+
}, createAndFillCaption());
|
|
295
286
|
const tr = view.state.tr;
|
|
296
287
|
const { pos } = upsertSupplementsSection(tr, supplement);
|
|
297
288
|
tr.setSelection(NodeSelection.create(tr.doc, pos));
|
|
@@ -560,7 +551,7 @@ export const insertBoxElement = (state, dispatch) => {
|
|
|
560
551
|
paragraph,
|
|
561
552
|
]);
|
|
562
553
|
const node = nodes.box_element.createAndFill({}, [
|
|
563
|
-
nodes.
|
|
554
|
+
nodes.caption_title.create(),
|
|
564
555
|
section,
|
|
565
556
|
]);
|
|
566
557
|
if (position && dispatch) {
|
|
@@ -713,7 +704,7 @@ export const insertContributors = (state, dispatch, view) => {
|
|
|
713
704
|
if (dispatch) {
|
|
714
705
|
const selection = NodeSelection.create(tr.doc, contributors.pos);
|
|
715
706
|
dispatch(tr.setSelection(selection).scrollIntoView());
|
|
716
|
-
|
|
707
|
+
openAuthorsAndAffiliationsModals(contributors.pos, view, 'authors');
|
|
717
708
|
}
|
|
718
709
|
return true;
|
|
719
710
|
};
|
|
@@ -734,7 +725,7 @@ export const insertAffiliation = (state, dispatch, view) => {
|
|
|
734
725
|
if (dispatch) {
|
|
735
726
|
const selection = NodeSelection.create(tr.doc, affiliations.pos);
|
|
736
727
|
dispatch(tr.setSelection(selection).scrollIntoView());
|
|
737
|
-
|
|
728
|
+
openAuthorsAndAffiliationsModals(affiliations.pos, view, 'affiliations');
|
|
738
729
|
}
|
|
739
730
|
return true;
|
|
740
731
|
};
|
|
@@ -1073,7 +1064,7 @@ export const createAndFillTableElement = (attrs, config = DEFAULT_TABLE_CONFIG)
|
|
|
1073
1064
|
...attrs,
|
|
1074
1065
|
id: generateNodeID(schema.nodes.table_element),
|
|
1075
1066
|
}, [
|
|
1076
|
-
|
|
1067
|
+
schema.nodes.caption_title.create(),
|
|
1077
1068
|
schema.nodes.table.create({}, tableRows),
|
|
1078
1069
|
schema.nodes.alt_text.create(),
|
|
1079
1070
|
schema.nodes.long_desc.create(),
|
|
@@ -1084,21 +1075,22 @@ const createAndFillFigureElement = (attrs) => schema.nodes.figure_element.create
|
|
|
1084
1075
|
...attrs,
|
|
1085
1076
|
id: generateNodeID(schema.nodes.figure_element),
|
|
1086
1077
|
}, [
|
|
1087
|
-
schema.nodes.figure.create(
|
|
1088
|
-
|
|
1078
|
+
schema.nodes.figure.create(),
|
|
1079
|
+
schema.nodes.caption.create(undefined, schema.nodes.text_block.create()),
|
|
1089
1080
|
schema.nodes.alt_text.create(),
|
|
1090
1081
|
schema.nodes.long_desc.create(),
|
|
1091
1082
|
schema.nodes.listing.create(),
|
|
1092
1083
|
]);
|
|
1093
|
-
const
|
|
1084
|
+
const createAndFillCaption = () => [
|
|
1094
1085
|
schema.nodes.caption_title.create(),
|
|
1095
|
-
schema.nodes.caption.create(),
|
|
1096
|
-
]
|
|
1086
|
+
schema.nodes.caption.create(undefined, schema.nodes.text_block.create()),
|
|
1087
|
+
];
|
|
1097
1088
|
const createImageElement = (attrs) => schema.nodes.image_element.create({
|
|
1098
1089
|
...attrs,
|
|
1099
1090
|
id: generateNodeID(schema.nodes.image_element),
|
|
1100
1091
|
}, [
|
|
1101
1092
|
schema.nodes.figure.create(),
|
|
1093
|
+
schema.nodes.caption.create(undefined, schema.nodes.text_block.create()),
|
|
1102
1094
|
schema.nodes.alt_text.create(),
|
|
1103
1095
|
schema.nodes.long_desc.create(),
|
|
1104
1096
|
]);
|
|
@@ -1106,7 +1098,7 @@ const createEmbedElement = (attrs) => schema.nodes.embed.create({
|
|
|
1106
1098
|
...attrs,
|
|
1107
1099
|
id: generateNodeID(schema.nodes.embed),
|
|
1108
1100
|
}, [
|
|
1109
|
-
|
|
1101
|
+
...createAndFillCaption(),
|
|
1110
1102
|
schema.nodes.alt_text.create(),
|
|
1111
1103
|
schema.nodes.long_desc.create(),
|
|
1112
1104
|
]);
|
|
@@ -3,14 +3,13 @@ import { Field, Formik } from 'formik';
|
|
|
3
3
|
import React, { useRef } from 'react';
|
|
4
4
|
import { ChangeHandlingForm } from '../ChangeHandlingForm';
|
|
5
5
|
export const AffiliationForm = ({ values, onSave, onChange, actionsRef, }) => {
|
|
6
|
-
|
|
6
|
+
const formRef = useRef(null);
|
|
7
|
+
if (actionsRef) {
|
|
7
8
|
actionsRef.current = {
|
|
8
|
-
reset: () =>
|
|
9
|
-
|
|
10
|
-
},
|
|
9
|
+
reset: () => formRef.current?.resetForm(),
|
|
10
|
+
submitForm: () => formRef.current?.submitForm(),
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
-
const formRef = useRef(null);
|
|
14
13
|
const validateAffiliation = (values) => {
|
|
15
14
|
const errors = {};
|
|
16
15
|
if (!values.institution?.trim()) {
|
|
@@ -18,7 +17,7 @@ export const AffiliationForm = ({ values, onSave, onChange, actionsRef, }) => {
|
|
|
18
17
|
}
|
|
19
18
|
return errors;
|
|
20
19
|
};
|
|
21
|
-
return (React.createElement(Formik, { initialValues: values, onSubmit: onSave, innerRef: formRef, enableReinitialize: true, validate: validateAffiliation }, (formik) => (React.createElement(ChangeHandlingForm, { onChange: onChange, id: "affiliation-form", noValidate: true },
|
|
20
|
+
return (React.createElement(Formik, { initialValues: values, onSubmit: (attrs) => onSave(attrs), innerRef: formRef, enableReinitialize: true, validate: validateAffiliation }, (formik) => (React.createElement(ChangeHandlingForm, { onChange: onChange, id: "affiliation-form", noValidate: true },
|
|
22
21
|
React.createElement(FormRow, null,
|
|
23
22
|
React.createElement(Field, { name: "institution" }, (props) => {
|
|
24
23
|
const hasError = formik.touched.institution && formik.errors.institution;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AddIcon,
|
|
1
|
+
import { AddIcon, AffiliationPlaceholderIcon, CloseButton, InspectorTab, InspectorTabList, InspectorTabPanel, InspectorTabPanels, InspectorTabs, outlineStyle, ModalBody, ModalContainer, ModalHeader, ModalSidebar, ModalSidebarHeader, ModalSidebarTitle, ScrollableModalContent, SidebarContent, StyledModal, } from '@manuscripts/style-guide';
|
|
2
2
|
import { generateNodeID, schema } from '@manuscripts/transform';
|
|
3
3
|
import { isEqual } from 'lodash';
|
|
4
4
|
import React, { useCallback, useEffect, useReducer, useRef, useState, } from 'react';
|
|
@@ -11,37 +11,45 @@ import { ConfirmationDialog, DialogType } from '../dialog/ConfirmationDialog';
|
|
|
11
11
|
import FormFooter from '../form/FormFooter';
|
|
12
12
|
import { FormPlaceholder } from '../form/FormPlaceholder';
|
|
13
13
|
import { ModalFormActions } from '../form/ModalFormActions';
|
|
14
|
-
import {
|
|
15
|
-
import { DrawerGroup } from '../modal-drawer/GenericDrawerGroup';
|
|
14
|
+
import { AuthorsPanel } from '../authors/AuthorsPanel';
|
|
16
15
|
import { AffiliationForm } from './AffiliationForm';
|
|
17
16
|
import { AffiliationList } from './AffiliationList';
|
|
18
|
-
import { getEditorProps } from '../../plugins/editor-props';
|
|
19
|
-
import ReactSubView from '../../views/ReactSubView';
|
|
20
|
-
import { deleteNode, findChildrenAttrsByType, updateNodeAttrs, } from '../../lib/view';
|
|
21
17
|
function makeAuthorItems(authors) {
|
|
22
18
|
return authors.map((author) => ({
|
|
23
19
|
id: author.id,
|
|
24
20
|
label: `${author.given} ${author.family}`,
|
|
25
21
|
}));
|
|
26
22
|
}
|
|
27
|
-
export const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, affiliation, onSaveAffiliation, onDeleteAffiliation, onUpdateAuthors, addNewAffiliation = false, }) => {
|
|
23
|
+
export const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, affiliation, onSaveAffiliation, onDeleteAffiliation, onUpdateAuthors, addNewAffiliation = false, onClose, onOpenAuthorsModal, }) => {
|
|
28
24
|
const [isOpen, setIsOpen] = useState(true);
|
|
29
25
|
const [selection, setSelection] = useState(affiliation);
|
|
30
26
|
const [showingDeleteDialog, setShowDeleteDialog] = useState(false);
|
|
31
27
|
const valuesRef = useRef(undefined);
|
|
32
28
|
const actionsRef = useRef(undefined);
|
|
33
29
|
const [authors, dispatchAuthors] = useReducer(authorsReducer, $authors.sort(authorComparator));
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
dispatchAuthors({
|
|
32
|
+
type: 'set',
|
|
33
|
+
state: [...$authors].sort(authorComparator),
|
|
34
|
+
});
|
|
35
|
+
}, [$authors]);
|
|
34
36
|
const [affiliations, dispatchAffiliations] = useReducer(affiliationsReducer, $affiliations);
|
|
35
37
|
const [isDisableSave, setIsDisableSave] = useState(true);
|
|
36
38
|
const [newAffiliation, setNewAffiliation] = useState(false);
|
|
37
39
|
const [showRequiredFieldConfirmationDialog, setShowRequiredFieldConfirmationDialog,] = useState(false);
|
|
38
40
|
const [showConfirmationDialog, setShowConfirmationDialog] = useState(false);
|
|
39
|
-
const [showAuthorDrawer, setShowAuthorDrawer] = useState(false);
|
|
40
41
|
const [selectedAuthorIds, setSelectedAuthorIds] = useState([]);
|
|
41
42
|
const [pendingSelection, setPendingSelection] = useState(null);
|
|
42
43
|
const [pendingAction, setPendingAction] = useState(null);
|
|
43
44
|
const [savedAffiliationId, setSavedAffiliationId] = useState(undefined);
|
|
44
45
|
const [affiliationAuthorMap, setAffiliationAuthorMap] = useState(new Map());
|
|
46
|
+
const prevIsOpenRef = useRef(isOpen);
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (prevIsOpenRef.current && !isOpen) {
|
|
49
|
+
onClose?.();
|
|
50
|
+
}
|
|
51
|
+
prevIsOpenRef.current = isOpen;
|
|
52
|
+
}, [isOpen, onClose]);
|
|
45
53
|
useEffect(() => {
|
|
46
54
|
if (!selection) {
|
|
47
55
|
return;
|
|
@@ -106,7 +114,6 @@ export const AffiliationsModal = ({ authors: $authors, affiliations: $affiliatio
|
|
|
106
114
|
setNewAffiliation(false);
|
|
107
115
|
setSelection(affiliation);
|
|
108
116
|
setSelectedAuthorIds(affiliatedAuthorIds);
|
|
109
|
-
setShowAuthorDrawer(false);
|
|
110
117
|
setAffiliationAuthorMap((prevMap) => {
|
|
111
118
|
const newMap = new Map(prevMap);
|
|
112
119
|
newMap.set(affiliation.id, affiliatedAuthorIds);
|
|
@@ -146,7 +153,6 @@ export const AffiliationsModal = ({ authors: $authors, affiliations: $affiliatio
|
|
|
146
153
|
newMap.set(affiliation.id, selectedAuthorIds);
|
|
147
154
|
return newMap;
|
|
148
155
|
});
|
|
149
|
-
setShowAuthorDrawer(false);
|
|
150
156
|
setSavedAffiliationId(affiliation.id);
|
|
151
157
|
setTimeout(() => {
|
|
152
158
|
setSavedAffiliationId(undefined);
|
|
@@ -240,7 +246,6 @@ export const AffiliationsModal = ({ authors: $authors, affiliations: $affiliatio
|
|
|
240
246
|
setNewAffiliation(true);
|
|
241
247
|
setSelection(emptyAffiliation);
|
|
242
248
|
setSelectedAuthorIds([]);
|
|
243
|
-
setShowAuthorDrawer(false);
|
|
244
249
|
};
|
|
245
250
|
useEffect(() => {
|
|
246
251
|
if (addNewAffiliation) {
|
|
@@ -288,7 +293,6 @@ export const AffiliationsModal = ({ authors: $authors, affiliations: $affiliatio
|
|
|
288
293
|
const handleConfirmationCancel = () => {
|
|
289
294
|
setShowConfirmationDialog(false);
|
|
290
295
|
setShowRequiredFieldConfirmationDialog(false);
|
|
291
|
-
setShowAuthorDrawer(false);
|
|
292
296
|
if (pendingAction === 'select' && pendingSelection) {
|
|
293
297
|
setSelection(pendingSelection);
|
|
294
298
|
setNewAffiliation(false);
|
|
@@ -329,19 +333,17 @@ export const AffiliationsModal = ({ authors: $authors, affiliations: $affiliatio
|
|
|
329
333
|
React.createElement(AffiliationList, { affiliation: selection, affiliations: affiliations, onSelect: handleSelect, onDelete: handleShowDeleteDialog, lastSavedAffiliationId: savedAffiliationId }))),
|
|
330
334
|
React.createElement(ScrollableModalContent, { "data-cy": "affiliations-modal-content" }, selection ? (React.createElement(React.Fragment, null,
|
|
331
335
|
React.createElement(AffiliationTabs, null,
|
|
332
|
-
React.createElement(ModalFormActions, { type: 'affiliation', form: 'affiliation-form', onDelete: handleDeleteAffiliation, showingDeleteDialog: showingDeleteDialog &&
|
|
336
|
+
React.createElement(ModalFormActions, { type: 'affiliation', form: 'affiliation-form', onSubmitForm: () => actionsRef.current?.submitForm?.(), onDelete: handleDeleteAffiliation, showingDeleteDialog: showingDeleteDialog &&
|
|
333
337
|
!(showConfirmationDialog ||
|
|
334
338
|
showRequiredFieldConfirmationDialog), showDeleteDialog: handleShowDeleteDialog, newEntity: newAffiliation, isDisableSave: isDisableSave }),
|
|
335
339
|
React.createElement(InspectorTabList, null,
|
|
336
340
|
React.createElement(InspectorTab, null, "Details"),
|
|
337
|
-
React.createElement(InspectorTab, null, "Authors")),
|
|
341
|
+
onOpenAuthorsModal && React.createElement(InspectorTab, null, "Authors")),
|
|
338
342
|
React.createElement(InspectorTabPanels, null,
|
|
339
343
|
React.createElement(AffiliationTabPanel, null,
|
|
340
|
-
React.createElement(AffiliationForm, { values: checkID(selection, 'affiliation'), onSave: () => handleSaveAffiliation(
|
|
341
|
-
React.createElement(AffiliationTabPanel, null,
|
|
342
|
-
React.createElement(
|
|
343
|
-
setSelectedAuthorIds((prev) => prev.filter((authorId) => authorId !== id));
|
|
344
|
-
}, selectedItems: selectedAuthors, onSelect: selectAuthor, items: makeAuthorItems(authors), showDrawer: showAuthorDrawer, setShowDrawer: setShowAuthorDrawer, title: "Authors", cy: "affiliations", labelField: "label", buttonText: "Affiliate Authors", Icon: React.createElement(AddUserIcon, { width: 16, height: 16 }) })))),
|
|
344
|
+
React.createElement(AffiliationForm, { values: checkID(selection, 'affiliation'), onSave: (attrs) => handleSaveAffiliation(attrs), onChange: handleAffiliationChange, actionsRef: actionsRef })),
|
|
345
|
+
onOpenAuthorsModal && (React.createElement(AffiliationTabPanel, null,
|
|
346
|
+
React.createElement(AuthorsPanel, { items: makeAuthorItems(authors), selectedItems: selectedAuthors, onSelect: selectAuthor, onOpenAuthorsModal: onOpenAuthorsModal }))))),
|
|
345
347
|
React.createElement(ConfirmationDialog, { isOpen: showRequiredFieldConfirmationDialog, onPrimary: () => setShowRequiredFieldConfirmationDialog(false), onSecondary: handleConfirmationCancel, type: DialogType.REQUIRED, entityType: "affiliation" }),
|
|
346
348
|
React.createElement(ConfirmationDialog, { isOpen: showConfirmationDialog, onPrimary: handleConfirmationSave, onSecondary: handleConfirmationCancel, type: DialogType.SAVE, entityType: "affiliation" }))) : (React.createElement(FormPlaceholder, { type: "affiliation", title: "Affiliation Details", message: "Select an affiliation from the list to display it's details here.", placeholderIcon: React.createElement(AffiliationPlaceholderIcon, null) })))),
|
|
347
349
|
React.createElement(FormFooter, { onCancel: handleClose }))));
|
|
@@ -407,37 +409,3 @@ const StyledModalSidebarHeader = styled(ModalSidebarHeader) `
|
|
|
407
409
|
margin-top: 8px;
|
|
408
410
|
margin-bottom: 16px;
|
|
409
411
|
`;
|
|
410
|
-
export const openAffiliationsModal = (pos, view) => {
|
|
411
|
-
if (!view) {
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
const { state } = view;
|
|
415
|
-
const props = getEditorProps(state);
|
|
416
|
-
const contributors = findChildrenAttrsByType(view, schema.nodes.contributor);
|
|
417
|
-
const componentProps = {
|
|
418
|
-
affiliations: [],
|
|
419
|
-
authors: contributors,
|
|
420
|
-
onSaveAffiliation: (affiliation) => handleSaveAffiliation(view, affiliation, pos),
|
|
421
|
-
onDeleteAffiliation: (affiliation) => handleDeleteAffiliation(view, affiliation),
|
|
422
|
-
onUpdateAuthors: (authors) => handleUpdateAuthors(view, authors),
|
|
423
|
-
addNewAffiliation: true,
|
|
424
|
-
};
|
|
425
|
-
const dialog = ReactSubView(props, AffiliationsModal, componentProps, state.doc, () => pos, view);
|
|
426
|
-
view.focus();
|
|
427
|
-
document.body.appendChild(dialog);
|
|
428
|
-
};
|
|
429
|
-
export const handleSaveAffiliation = (view, affiliation, affiliationsPos) => {
|
|
430
|
-
const update = updateNodeAttrs(view, schema.nodes.affiliation, affiliation);
|
|
431
|
-
if (!update) {
|
|
432
|
-
const node = schema.nodes.affiliation.create(affiliation);
|
|
433
|
-
view.dispatch(view.state.tr.insert(affiliationsPos + 1, node));
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
|
-
export const handleDeleteAffiliation = (view, affiliation) => {
|
|
437
|
-
deleteNode(view, affiliation.id);
|
|
438
|
-
};
|
|
439
|
-
export const handleUpdateAuthors = (view, authors) => {
|
|
440
|
-
authors.forEach((author) => {
|
|
441
|
-
updateNodeAttrs(view, schema.nodes.contributor, author);
|
|
442
|
-
});
|
|
443
|
-
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AffiliationPlaceholderIcon } from '@manuscripts/style-guide';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { GenericPanel, ListItem, ListItems, useListSelectedIds, } from '../authors-affiliations/GenericPanel';
|
|
4
|
+
function affiliationSecondaryLine(item) {
|
|
5
|
+
const line = [item.city, item.county, item.country].filter(Boolean).join(', ');
|
|
6
|
+
return line || undefined;
|
|
7
|
+
}
|
|
8
|
+
export const AffiliationsPanel = ({ items, selectedItems = [], onSelect, onOpenAffiliationsModal, }) => {
|
|
9
|
+
const selectedIds = useListSelectedIds(selectedItems);
|
|
10
|
+
return (React.createElement(GenericPanel, { title: "Institutional Affiliations", createLabel: "Create New Affiliation", onCreate: onOpenAffiliationsModal, createDataCy: "add-affiliations-link", emptyDataCy: "affiliations-panel-empty", isEmpty: items.length === 0, emptyIcon: React.createElement(AffiliationPlaceholderIcon, null), emptyMessage: React.createElement(React.Fragment, null,
|
|
11
|
+
"There are no affiliations attributed yet!",
|
|
12
|
+
React.createElement("br", null),
|
|
13
|
+
"Click \u2018Create New Affiliation\u2019") },
|
|
14
|
+
React.createElement(ListItems, { "data-cy": "affiliations-panel" }, items.map((item) => (React.createElement(ListItem, { key: item.id, selected: selectedIds.has(item.id), onClick: () => onSelect(item.id), primary: item.institution, secondary: affiliationSecondaryLine(item) }))))));
|
|
15
|
+
};
|
|
@@ -34,11 +34,10 @@ export const AuthorDetailsForm = ({ values, onChange, onSave, actionsRef, isEmai
|
|
|
34
34
|
formRef.current.setFieldValue('creditRoles', selectedCreditRoles);
|
|
35
35
|
}
|
|
36
36
|
}, [selectedCreditRoles]);
|
|
37
|
-
if (actionsRef
|
|
37
|
+
if (actionsRef) {
|
|
38
38
|
actionsRef.current = {
|
|
39
|
-
reset: () =>
|
|
40
|
-
|
|
41
|
-
},
|
|
39
|
+
reset: () => formRef.current?.resetForm(),
|
|
40
|
+
submitForm: () => formRef.current?.submitForm(),
|
|
42
41
|
};
|
|
43
42
|
}
|
|
44
43
|
const validateAuthor = (values) => {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import { AddIcon,
|
|
16
|
+
import { AddIcon, AddRoleIcon, AuthorPlaceholderIcon, CloseButton, ModalBody, ModalContainer, ModalHeader, ModalSidebar, ModalSidebarHeader, ModalSidebarTitle, outlineStyle, ScrollableModalContent, SidebarContent, StyledModal, InspectorTabs, InspectorTabPanel, InspectorTabList, InspectorTab, InspectorTabPanels, } from '@manuscripts/style-guide';
|
|
17
17
|
import { generateNodeID, schema } from '@manuscripts/transform';
|
|
18
18
|
import { cloneDeep, isEqual, omit } from 'lodash';
|
|
19
19
|
import React, { useCallback, useEffect, useReducer, useRef, useState, } from 'react';
|
|
@@ -26,18 +26,22 @@ import FormFooter from '../form/FormFooter';
|
|
|
26
26
|
import { FormPlaceholder } from '../form/FormPlaceholder';
|
|
27
27
|
import { ModalFormActions } from '../form/ModalFormActions';
|
|
28
28
|
import { DrawerGroup } from '../modal-drawer/GenericDrawerGroup';
|
|
29
|
-
import {
|
|
29
|
+
import { AffiliationsPanel } from '../affiliations/AffiliationsPanel';
|
|
30
30
|
import { AuthorDetailsForm } from './AuthorDetailsForm';
|
|
31
31
|
import { AuthorList } from './AuthorList';
|
|
32
32
|
import { CreditDrawer } from './CreditDrawer';
|
|
33
33
|
import { useManageAffiliations } from './useManageAffiliations';
|
|
34
34
|
import { useManageCredit } from './useManageCredit';
|
|
35
|
-
import { getEditorProps } from '../../plugins/editor-props';
|
|
36
|
-
import ReactSubView from '../../views/ReactSubView';
|
|
37
|
-
import { deleteNode, findChildrenAttrsByType, updateNodeAttrs, } from '../../lib/view';
|
|
38
35
|
export const authorsReducer = arrayReducer((a, b) => a.id === b.id);
|
|
39
|
-
export const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author, onSaveAuthor, onDeleteAuthor, addNewAuthor = false, }) => {
|
|
36
|
+
export const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author, onSaveAuthor, onDeleteAuthor, addNewAuthor = false, onOpenAffiliationsModal, onClose, }) => {
|
|
40
37
|
const [isOpen, setOpen] = useState(true);
|
|
38
|
+
const prevIsOpenRef = useRef(true);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (prevIsOpenRef.current && !isOpen) {
|
|
41
|
+
onClose?.();
|
|
42
|
+
}
|
|
43
|
+
prevIsOpenRef.current = isOpen;
|
|
44
|
+
}, [isOpen, onClose]);
|
|
41
45
|
const [isDisableSave, setDisableSave] = useState(true);
|
|
42
46
|
const [isEmailRequired, setEmailRequired] = useState(false);
|
|
43
47
|
const [showConfirmationDialog, setShowConfirmationDialog] = useState(false);
|
|
@@ -60,7 +64,7 @@ export const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, a
|
|
|
60
64
|
}
|
|
61
65
|
}, [addNewAuthor]);
|
|
62
66
|
const [selection, setSelection] = useState(author);
|
|
63
|
-
const {
|
|
67
|
+
const { selectedAffiliations, setSelectedAffiliations, selectAffiliation, affiliations, } = useManageAffiliations(selection, $affiliations);
|
|
64
68
|
useEffect(() => {
|
|
65
69
|
const currentAuthor = selection;
|
|
66
70
|
const relevantAffiliations = affiliations.filter((item) => currentAuthor?.affiliationIDs?.includes(item.id));
|
|
@@ -87,12 +91,10 @@ export const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, a
|
|
|
87
91
|
else {
|
|
88
92
|
updateAffiliationSelection(author);
|
|
89
93
|
setSelection(author);
|
|
90
|
-
setShowAffiliationDrawer(false);
|
|
91
94
|
setNewAuthor(false);
|
|
92
95
|
}
|
|
93
96
|
}
|
|
94
97
|
else {
|
|
95
|
-
setShowAffiliationDrawer(false);
|
|
96
98
|
updateAffiliationSelection(author);
|
|
97
99
|
setSelection(author);
|
|
98
100
|
setNewAuthor(false);
|
|
@@ -133,7 +135,6 @@ export const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, a
|
|
|
133
135
|
setSelection(nextAuthor);
|
|
134
136
|
setNextAuthor(null);
|
|
135
137
|
setNewAuthor(false);
|
|
136
|
-
setShowAffiliationDrawer(false);
|
|
137
138
|
updateAffiliationSelection(nextAuthor);
|
|
138
139
|
setIsCreatingNewAuthor(false);
|
|
139
140
|
}
|
|
@@ -166,7 +167,6 @@ export const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, a
|
|
|
166
167
|
}
|
|
167
168
|
setShowConfirmationDialog(false);
|
|
168
169
|
setShowRequiredFieldConfirmationDialog(false);
|
|
169
|
-
setShowAffiliationDrawer(false);
|
|
170
170
|
};
|
|
171
171
|
const saveAuthor = (values) => {
|
|
172
172
|
if (!values || !selection) {
|
|
@@ -185,7 +185,6 @@ export const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, a
|
|
|
185
185
|
setSelection(author);
|
|
186
186
|
setShowConfirmationDialog(false);
|
|
187
187
|
setNewAuthor(false);
|
|
188
|
-
setShowAffiliationDrawer(false);
|
|
189
188
|
setIsCreatingNewAuthor(false);
|
|
190
189
|
dispatchAuthors({
|
|
191
190
|
type: 'update',
|
|
@@ -242,7 +241,6 @@ export const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, a
|
|
|
242
241
|
}
|
|
243
242
|
else {
|
|
244
243
|
createNewAuthor();
|
|
245
|
-
setShowAffiliationDrawer(false);
|
|
246
244
|
}
|
|
247
245
|
};
|
|
248
246
|
const deleteAuthor = () => {
|
|
@@ -311,19 +309,19 @@ export const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, a
|
|
|
311
309
|
React.createElement(AuthorList, { author: selection, authors: authors, onSelect: selectAuthor, onDelete: () => setShowDeleteDialog((prev) => !prev), moveAuthor: moveAuthor, lastSavedAuthor: lastSavedAuthor }))),
|
|
312
310
|
React.createElement(ScrollableModalContent, { "data-cy": "author-modal-content" }, selection ? (React.createElement(React.Fragment, null,
|
|
313
311
|
React.createElement(AuthorTabs, null,
|
|
314
|
-
React.createElement(ModalFormActions, { form: 'author-details-form', type: "author", onDelete: deleteAuthor, showingDeleteDialog: showingDeleteDialog, showDeleteDialog: () => setShowDeleteDialog((prev) => !prev), newEntity: newAuthor ||
|
|
312
|
+
React.createElement(ModalFormActions, { form: 'author-details-form', onSubmitForm: () => actionsRef.current?.submitForm?.(), type: "author", onDelete: deleteAuthor, showingDeleteDialog: showingDeleteDialog, showDeleteDialog: () => setShowDeleteDialog((prev) => !prev), newEntity: newAuthor ||
|
|
315
313
|
(isCreatingNewAuthor &&
|
|
316
314
|
!showConfirmationDialog &&
|
|
317
315
|
!showRequiredFieldConfirmationDialog), isDisableSave: isDisableSave }),
|
|
318
316
|
React.createElement(InspectorTabList, null,
|
|
319
317
|
React.createElement(InspectorTab, null, "Details"),
|
|
320
|
-
React.createElement(InspectorTab, null, "Affiliations"),
|
|
318
|
+
onOpenAffiliationsModal && (React.createElement(InspectorTab, null, "Affiliations")),
|
|
321
319
|
React.createElement(InspectorTab, null, "Contributions (CRediT)")),
|
|
322
320
|
React.createElement(InspectorTabPanels, null,
|
|
323
321
|
React.createElement(AuthorTabPanel, null,
|
|
324
322
|
React.createElement(AuthorDetailsForm, { values: normalizeAuthor(selection), onChange: changeAuthor, onSave: saveAuthor, actionsRef: actionsRef, isEmailRequired: isEmailRequired, selectedAffiliations: selectedAffiliations.map((a) => a.id), authorFormRef: authorFormRef, selectedCreditRoles: selectedCreditRoles })),
|
|
325
|
-
React.createElement(AuthorTabPanel, null,
|
|
326
|
-
React.createElement(
|
|
323
|
+
onOpenAffiliationsModal && (React.createElement(AuthorTabPanel, null,
|
|
324
|
+
React.createElement(AffiliationsPanel, { items: affiliations, selectedItems: selectedAffiliations, onSelect: selectAffiliation, onOpenAffiliationsModal: onOpenAffiliationsModal }))),
|
|
327
325
|
React.createElement(AuthorTabPanel, null,
|
|
328
326
|
React.createElement(DrawerGroup, { Drawer: CreditDrawer, removeItem: removeCreditRole, selectedItems: selectedCreditRoles.map((r) => ({
|
|
329
327
|
id: r.vocabTerm,
|
|
@@ -391,31 +389,3 @@ const StyledModalBody = styled(ModalBody) `
|
|
|
391
389
|
const StyledModalSidebarHeader = styled(ModalSidebarHeader) `
|
|
392
390
|
margin-bottom: 16px;
|
|
393
391
|
`;
|
|
394
|
-
export const openAuthorsModal = (pos, view) => {
|
|
395
|
-
if (!view) {
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
const { state } = view;
|
|
399
|
-
const props = getEditorProps(state);
|
|
400
|
-
const affiliations = findChildrenAttrsByType(view, schema.nodes.affiliation);
|
|
401
|
-
const componentProps = {
|
|
402
|
-
authors: [],
|
|
403
|
-
affiliations,
|
|
404
|
-
onSaveAuthor: (contributor) => handleSaveContributor(view, contributor, pos),
|
|
405
|
-
onDeleteAuthor: (contributor) => handleDeleteContributor(view, contributor),
|
|
406
|
-
addNewAuthor: true,
|
|
407
|
-
};
|
|
408
|
-
const dialog = ReactSubView(props, AuthorsModal, componentProps, state.doc, () => pos, view);
|
|
409
|
-
view.focus();
|
|
410
|
-
document.body.appendChild(dialog);
|
|
411
|
-
};
|
|
412
|
-
export const handleSaveContributor = (view, contributor, contributorsPos) => {
|
|
413
|
-
const update = updateNodeAttrs(view, schema.nodes.contributor, contributor);
|
|
414
|
-
if (!update) {
|
|
415
|
-
const node = schema.nodes.contributor.create(contributor);
|
|
416
|
-
view.dispatch(view.state.tr.insert(contributorsPos + 1, node));
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
|
-
export const handleDeleteContributor = (view, contributor) => {
|
|
420
|
-
deleteNode(view, contributor.id);
|
|
421
|
-
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AuthorPlaceholderIcon } from '@manuscripts/style-guide';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { GenericPanel, ListItem, ListItems, useListSelectedIds, } from '../authors-affiliations/GenericPanel';
|
|
4
|
+
export const AuthorsPanel = ({ items, selectedItems = [], onSelect, onOpenAuthorsModal, }) => {
|
|
5
|
+
const selectedIds = useListSelectedIds(selectedItems);
|
|
6
|
+
return (React.createElement(GenericPanel, { title: "Authors", createLabel: "Add New Author", onCreate: onOpenAuthorsModal, createDataCy: "add-authors-link", emptyDataCy: "authors-panel-empty", isEmpty: items.length === 0, emptyIcon: React.createElement(AuthorPlaceholderIcon, null), emptyMessage: React.createElement(React.Fragment, null,
|
|
7
|
+
"There are no authors attributed yet!",
|
|
8
|
+
React.createElement("br", null),
|
|
9
|
+
"Click \u2018Add New Author\u2019") },
|
|
10
|
+
React.createElement(ListItems, { "data-cy": "authors-panel" }, items.map((item) => (React.createElement(ListItem, { key: item.id, selected: selectedIds.has(item.id), onClick: () => onSelect(item.id), primary: item.label }))))));
|
|
11
|
+
};
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { useReducer, useState } from 'react';
|
|
1
|
+
import { useEffect, useReducer, useState } from 'react';
|
|
2
2
|
import { arrayReducer } from '../../lib/array-reducer';
|
|
3
3
|
export const affiliationsReducer = arrayReducer((a, b) => a.id === b.id);
|
|
4
4
|
export const useManageAffiliations = (selection, $affiliations) => {
|
|
5
|
-
const [affiliations] = useReducer(affiliationsReducer,
|
|
6
|
-
|
|
5
|
+
const [affiliations, dispatchAffiliations] = useReducer(affiliationsReducer, [
|
|
6
|
+
...$affiliations,
|
|
7
|
+
]);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
dispatchAffiliations({ type: 'set', state: [...$affiliations] });
|
|
10
|
+
}, [$affiliations]);
|
|
7
11
|
const [selectedAffiliations, setSelectedAffiliations] = useState([]);
|
|
8
12
|
const removeAffiliation = (affId) => {
|
|
9
13
|
if (!selection) {
|
|
@@ -26,8 +30,6 @@ export const useManageAffiliations = (selection, $affiliations) => {
|
|
|
26
30
|
setSelectedAffiliations(affiliations.filter((item) => newAffiliations.includes(item.id)));
|
|
27
31
|
};
|
|
28
32
|
return {
|
|
29
|
-
showAffiliationDrawer,
|
|
30
|
-
setShowAffiliationDrawer,
|
|
31
33
|
selectedAffiliations,
|
|
32
34
|
setSelectedAffiliations,
|
|
33
35
|
removeAffiliation,
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2026 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { schema, } from '@manuscripts/transform';
|
|
17
|
+
import React, { useState } from 'react';
|
|
18
|
+
import { getEditorProps } from '../../plugins/editor-props';
|
|
19
|
+
import ReactSubView from '../../views/ReactSubView';
|
|
20
|
+
import { deleteNode, findChildByType, findChildrenAttrsByType, updateNodeAttrs, } from '../../lib/view';
|
|
21
|
+
import { AffiliationsModal, } from '../affiliations/AffiliationsModal';
|
|
22
|
+
import { AuthorsModal } from '../authors/AuthorsModal';
|
|
23
|
+
function insertNode(parentType, childType) {
|
|
24
|
+
return (view, attrs) => {
|
|
25
|
+
const parent = findChildByType(view, parentType);
|
|
26
|
+
if (parent) {
|
|
27
|
+
view.dispatch(view.state.tr.insert(parent.pos + 1, childType.create(attrs)));
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function upsertNode(nodeType, insertFn) {
|
|
32
|
+
return (view, attrs) => {
|
|
33
|
+
if (!updateNodeAttrs(view, nodeType, attrs)) {
|
|
34
|
+
insertFn(view, attrs);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const insertAuthorNode = insertNode(schema.nodes.contributors, schema.nodes.contributor);
|
|
39
|
+
const insertAffiliationNode = insertNode(schema.nodes.affiliations, schema.nodes.affiliation);
|
|
40
|
+
const upsertAuthor = upsertNode(schema.nodes.contributor, insertAuthorNode);
|
|
41
|
+
const upsertAffiliation = upsertNode(schema.nodes.affiliation, insertAffiliationNode);
|
|
42
|
+
export const AuthorsAndAffiliationsModals = ({ initialModal, view, author, affiliation, addNewAuthor, addNewAffiliation, }) => {
|
|
43
|
+
const [showOverlay, setShowOverlay] = useState(false);
|
|
44
|
+
const [authors, setAuthors] = useState(() => findChildrenAttrsByType(view, schema.nodes.contributor));
|
|
45
|
+
const [affiliations, setAffiliations] = useState(() => findChildrenAttrsByType(view, schema.nodes.affiliation));
|
|
46
|
+
const handleOpenOverlay = () => setShowOverlay(true);
|
|
47
|
+
const handleOverlayClose = () => {
|
|
48
|
+
setShowOverlay(false);
|
|
49
|
+
setAuthors(findChildrenAttrsByType(view, schema.nodes.contributor));
|
|
50
|
+
setAffiliations(findChildrenAttrsByType(view, schema.nodes.affiliation));
|
|
51
|
+
};
|
|
52
|
+
const authorsProps = {
|
|
53
|
+
author,
|
|
54
|
+
authors,
|
|
55
|
+
affiliations,
|
|
56
|
+
addNewAuthor,
|
|
57
|
+
onSaveAuthor: (a) => upsertAuthor(view, a),
|
|
58
|
+
onDeleteAuthor: (a) => deleteNode(view, a.id),
|
|
59
|
+
};
|
|
60
|
+
const affiliationsProps = {
|
|
61
|
+
affiliation,
|
|
62
|
+
authors,
|
|
63
|
+
affiliations,
|
|
64
|
+
addNewAffiliation,
|
|
65
|
+
onSaveAffiliation: (a) => upsertAffiliation(view, a),
|
|
66
|
+
onDeleteAffiliation: (a) => deleteNode(view, a.id),
|
|
67
|
+
onUpdateAuthors: (updated) => updated.forEach((a) => updateNodeAttrs(view, schema.nodes.contributor, a)),
|
|
68
|
+
};
|
|
69
|
+
if (initialModal === 'authors') {
|
|
70
|
+
return (React.createElement(React.Fragment, null,
|
|
71
|
+
React.createElement(AuthorsModal, { ...authorsProps, onOpenAffiliationsModal: handleOpenOverlay }),
|
|
72
|
+
showOverlay && (React.createElement(AffiliationsModal, { ...affiliationsProps, addNewAffiliation: true, onClose: handleOverlayClose }))));
|
|
73
|
+
}
|
|
74
|
+
return (React.createElement(React.Fragment, null,
|
|
75
|
+
React.createElement(AffiliationsModal, { ...affiliationsProps, onOpenAuthorsModal: handleOpenOverlay }),
|
|
76
|
+
showOverlay && (React.createElement(AuthorsModal, { ...authorsProps, addNewAuthor: true, onClose: handleOverlayClose }))));
|
|
77
|
+
};
|
|
78
|
+
export const openAuthorsAndAffiliationsModals = (pos, view, initialModal) => {
|
|
79
|
+
if (!view) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const { state } = view;
|
|
83
|
+
const props = getEditorProps(state);
|
|
84
|
+
const componentProps = {
|
|
85
|
+
initialModal,
|
|
86
|
+
view: view,
|
|
87
|
+
addNewAuthor: initialModal === 'authors',
|
|
88
|
+
addNewAffiliation: initialModal === 'affiliations',
|
|
89
|
+
};
|
|
90
|
+
const dialog = ReactSubView(props, AuthorsAndAffiliationsModals, componentProps, state.doc, () => pos, view);
|
|
91
|
+
view.focus();
|
|
92
|
+
document.body.appendChild(dialog);
|
|
93
|
+
};
|