@manuscripts/body-editor 3.12.16 → 3.12.19

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.
Files changed (45) hide show
  1. package/dist/cjs/commands.js +3 -4
  2. package/dist/cjs/components/affiliations/AffiliationForm.js +5 -6
  3. package/dist/cjs/components/affiliations/AffiliationsModal.js +21 -57
  4. package/dist/cjs/components/affiliations/AffiliationsPanel.js +22 -0
  5. package/dist/cjs/components/authors/AuthorDetailsForm.js +3 -4
  6. package/dist/cjs/components/authors/AuthorsModal.js +15 -48
  7. package/dist/cjs/components/authors/AuthorsPanel.js +18 -0
  8. package/dist/cjs/components/authors/useManageAffiliations.js +6 -4
  9. package/dist/cjs/components/authors-affiliations/AuthorsAndAffiliationsModals.js +134 -0
  10. package/dist/cjs/components/authors-affiliations/GenericPanel.js +136 -0
  11. package/dist/cjs/components/form/ModalFormActions.js +11 -5
  12. package/dist/cjs/components/references/ReferenceForm/ReferenceForm.js +2 -2
  13. package/dist/cjs/versions.js +1 -1
  14. package/dist/cjs/views/affiliations.js +5 -11
  15. package/dist/cjs/views/contributors.js +4 -7
  16. package/dist/es/commands.js +3 -4
  17. package/dist/es/components/affiliations/AffiliationForm.js +5 -6
  18. package/dist/es/components/affiliations/AffiliationsModal.js +21 -53
  19. package/dist/es/components/affiliations/AffiliationsPanel.js +15 -0
  20. package/dist/es/components/authors/AuthorDetailsForm.js +3 -4
  21. package/dist/es/components/authors/AuthorsModal.js +15 -45
  22. package/dist/es/components/authors/AuthorsPanel.js +11 -0
  23. package/dist/es/components/authors/useManageAffiliations.js +7 -5
  24. package/dist/es/components/authors-affiliations/AuthorsAndAffiliationsModals.js +93 -0
  25. package/dist/es/components/authors-affiliations/GenericPanel.js +94 -0
  26. package/dist/es/components/form/ModalFormActions.js +11 -5
  27. package/dist/es/components/references/ReferenceForm/ReferenceForm.js +2 -2
  28. package/dist/es/versions.js +1 -1
  29. package/dist/es/views/affiliations.js +5 -11
  30. package/dist/es/views/contributors.js +5 -8
  31. package/dist/types/components/affiliations/AffiliationForm.d.ts +1 -0
  32. package/dist/types/components/affiliations/AffiliationsModal.d.ts +2 -5
  33. package/dist/types/components/affiliations/AffiliationsPanel.d.ts +11 -0
  34. package/dist/types/components/authors/AuthorDetailsForm.d.ts +1 -0
  35. package/dist/types/components/authors/AuthorsModal.d.ts +2 -4
  36. package/dist/types/components/authors/AuthorsPanel.d.ts +13 -0
  37. package/dist/types/components/authors/useManageAffiliations.d.ts +0 -2
  38. package/dist/types/components/authors-affiliations/AuthorsAndAffiliationsModals.d.ts +29 -0
  39. package/dist/types/components/authors-affiliations/GenericPanel.d.ts +48 -0
  40. package/dist/types/components/form/ModalFormActions.d.ts +1 -0
  41. package/dist/types/versions.d.ts +1 -1
  42. package/package.json +1 -1
  43. package/dist/cjs/components/authors/AffiliationDrawer.js +0 -24
  44. package/dist/es/components/authors/AffiliationDrawer.js +0 -17
  45. package/dist/types/components/authors/AffiliationDrawer.d.ts +0 -12
@@ -37,8 +37,7 @@ const editor_props_1 = require("./plugins/editor-props");
37
37
  const search_replace_1 = require("./plugins/search-replace");
38
38
  const autocompletion_1 = require("./plugins/section_title/autocompletion");
39
39
  const persistent_cursor_1 = require("./plugins/persistent-cursor");
40
- const AffiliationsModal_1 = require("./components/affiliations/AffiliationsModal");
41
- const AuthorsModal_1 = require("./components/authors/AuthorsModal");
40
+ const AuthorsAndAffiliationsModals_1 = require("./components/authors-affiliations/AuthorsAndAffiliationsModals");
42
41
  const addToStart = (state, dispatch) => {
43
42
  const { selection } = state;
44
43
  const props = (0, editor_props_1.getEditorProps)(state);
@@ -748,7 +747,7 @@ const insertContributors = (state, dispatch, view) => {
748
747
  if (dispatch) {
749
748
  const selection = prosemirror_state_1.NodeSelection.create(tr.doc, contributors.pos);
750
749
  dispatch(tr.setSelection(selection).scrollIntoView());
751
- (0, AuthorsModal_1.openAuthorsModal)(contributors.pos, view);
750
+ (0, AuthorsAndAffiliationsModals_1.openAuthorsAndAffiliationsModals)(contributors.pos, view, 'authors');
752
751
  }
753
752
  return true;
754
753
  };
@@ -770,7 +769,7 @@ const insertAffiliation = (state, dispatch, view) => {
770
769
  if (dispatch) {
771
770
  const selection = prosemirror_state_1.NodeSelection.create(tr.doc, affiliations.pos);
772
771
  dispatch(tr.setSelection(selection).scrollIntoView());
773
- (0, AffiliationsModal_1.openAffiliationsModal)(affiliations.pos, view);
772
+ (0, AuthorsAndAffiliationsModals_1.openAuthorsAndAffiliationsModals)(affiliations.pos, view, 'affiliations');
774
773
  }
775
774
  return true;
776
775
  };
@@ -39,14 +39,13 @@ const formik_1 = require("formik");
39
39
  const react_1 = __importStar(require("react"));
40
40
  const ChangeHandlingForm_1 = require("../ChangeHandlingForm");
41
41
  const AffiliationForm = ({ values, onSave, onChange, actionsRef, }) => {
42
- if (actionsRef && !actionsRef.current) {
42
+ const formRef = (0, react_1.useRef)(null);
43
+ if (actionsRef) {
43
44
  actionsRef.current = {
44
- reset: () => {
45
- formRef.current?.resetForm();
46
- },
45
+ reset: () => formRef.current?.resetForm(),
46
+ submitForm: () => formRef.current?.submitForm(),
47
47
  };
48
48
  }
49
- const formRef = (0, react_1.useRef)(null);
50
49
  const validateAffiliation = (values) => {
51
50
  const errors = {};
52
51
  if (!values.institution?.trim()) {
@@ -54,7 +53,7 @@ const AffiliationForm = ({ values, onSave, onChange, actionsRef, }) => {
54
53
  }
55
54
  return errors;
56
55
  };
57
- return (react_1.default.createElement(formik_1.Formik, { initialValues: values, onSubmit: onSave, innerRef: formRef, enableReinitialize: true, validate: validateAffiliation }, (formik) => (react_1.default.createElement(ChangeHandlingForm_1.ChangeHandlingForm, { onChange: onChange, id: "affiliation-form", noValidate: true },
56
+ return (react_1.default.createElement(formik_1.Formik, { initialValues: values, onSubmit: (attrs) => onSave(attrs), innerRef: formRef, enableReinitialize: true, validate: validateAffiliation }, (formik) => (react_1.default.createElement(ChangeHandlingForm_1.ChangeHandlingForm, { onChange: onChange, id: "affiliation-form", noValidate: true },
58
57
  react_1.default.createElement(style_guide_1.FormRow, null,
59
58
  react_1.default.createElement(formik_1.Field, { name: "institution" }, (props) => {
60
59
  const hasError = formik.touched.institution && formik.errors.institution;
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.handleUpdateAuthors = exports.handleDeleteAffiliation = exports.handleSaveAffiliation = exports.openAffiliationsModal = exports.AffiliationsModal = void 0;
39
+ exports.AffiliationsModal = void 0;
40
40
  const style_guide_1 = require("@manuscripts/style-guide");
41
41
  const transform_1 = require("@manuscripts/transform");
42
42
  const lodash_1 = require("lodash");
@@ -50,37 +50,45 @@ const ConfirmationDialog_1 = require("../dialog/ConfirmationDialog");
50
50
  const FormFooter_1 = __importDefault(require("../form/FormFooter"));
51
51
  const FormPlaceholder_1 = require("../form/FormPlaceholder");
52
52
  const ModalFormActions_1 = require("../form/ModalFormActions");
53
- const GenericDrawer_1 = require("../modal-drawer/GenericDrawer");
54
- const GenericDrawerGroup_1 = require("../modal-drawer/GenericDrawerGroup");
53
+ const AuthorsPanel_1 = require("../authors/AuthorsPanel");
55
54
  const AffiliationForm_1 = require("./AffiliationForm");
56
55
  const AffiliationList_1 = require("./AffiliationList");
57
- const editor_props_1 = require("../../plugins/editor-props");
58
- const ReactSubView_1 = __importDefault(require("../../views/ReactSubView"));
59
- const view_1 = require("../../lib/view");
60
56
  function makeAuthorItems(authors) {
61
57
  return authors.map((author) => ({
62
58
  id: author.id,
63
59
  label: `${author.given} ${author.family}`,
64
60
  }));
65
61
  }
66
- const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, affiliation, onSaveAffiliation, onDeleteAffiliation, onUpdateAuthors, addNewAffiliation = false, }) => {
62
+ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, affiliation, onSaveAffiliation, onDeleteAffiliation, onUpdateAuthors, addNewAffiliation = false, onClose, onOpenAuthorsModal, }) => {
67
63
  const [isOpen, setIsOpen] = (0, react_1.useState)(true);
68
64
  const [selection, setSelection] = (0, react_1.useState)(affiliation);
69
65
  const [showingDeleteDialog, setShowDeleteDialog] = (0, react_1.useState)(false);
70
66
  const valuesRef = (0, react_1.useRef)(undefined);
71
67
  const actionsRef = (0, react_1.useRef)(undefined);
72
68
  const [authors, dispatchAuthors] = (0, react_1.useReducer)(AuthorsModal_1.authorsReducer, $authors.sort(authors_1.authorComparator));
69
+ (0, react_1.useEffect)(() => {
70
+ dispatchAuthors({
71
+ type: 'set',
72
+ state: [...$authors].sort(authors_1.authorComparator),
73
+ });
74
+ }, [$authors]);
73
75
  const [affiliations, dispatchAffiliations] = (0, react_1.useReducer)(useManageAffiliations_1.affiliationsReducer, $affiliations);
74
76
  const [isDisableSave, setIsDisableSave] = (0, react_1.useState)(true);
75
77
  const [newAffiliation, setNewAffiliation] = (0, react_1.useState)(false);
76
78
  const [showRequiredFieldConfirmationDialog, setShowRequiredFieldConfirmationDialog,] = (0, react_1.useState)(false);
77
79
  const [showConfirmationDialog, setShowConfirmationDialog] = (0, react_1.useState)(false);
78
- const [showAuthorDrawer, setShowAuthorDrawer] = (0, react_1.useState)(false);
79
80
  const [selectedAuthorIds, setSelectedAuthorIds] = (0, react_1.useState)([]);
80
81
  const [pendingSelection, setPendingSelection] = (0, react_1.useState)(null);
81
82
  const [pendingAction, setPendingAction] = (0, react_1.useState)(null);
82
83
  const [savedAffiliationId, setSavedAffiliationId] = (0, react_1.useState)(undefined);
83
84
  const [affiliationAuthorMap, setAffiliationAuthorMap] = (0, react_1.useState)(new Map());
85
+ const prevIsOpenRef = (0, react_1.useRef)(isOpen);
86
+ (0, react_1.useEffect)(() => {
87
+ if (prevIsOpenRef.current && !isOpen) {
88
+ onClose?.();
89
+ }
90
+ prevIsOpenRef.current = isOpen;
91
+ }, [isOpen, onClose]);
84
92
  (0, react_1.useEffect)(() => {
85
93
  if (!selection) {
86
94
  return;
@@ -145,7 +153,6 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, aff
145
153
  setNewAffiliation(false);
146
154
  setSelection(affiliation);
147
155
  setSelectedAuthorIds(affiliatedAuthorIds);
148
- setShowAuthorDrawer(false);
149
156
  setAffiliationAuthorMap((prevMap) => {
150
157
  const newMap = new Map(prevMap);
151
158
  newMap.set(affiliation.id, affiliatedAuthorIds);
@@ -185,7 +192,6 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, aff
185
192
  newMap.set(affiliation.id, selectedAuthorIds);
186
193
  return newMap;
187
194
  });
188
- setShowAuthorDrawer(false);
189
195
  setSavedAffiliationId(affiliation.id);
190
196
  setTimeout(() => {
191
197
  setSavedAffiliationId(undefined);
@@ -279,7 +285,6 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, aff
279
285
  setNewAffiliation(true);
280
286
  setSelection(emptyAffiliation);
281
287
  setSelectedAuthorIds([]);
282
- setShowAuthorDrawer(false);
283
288
  };
284
289
  (0, react_1.useEffect)(() => {
285
290
  if (addNewAffiliation) {
@@ -327,7 +332,6 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, aff
327
332
  const handleConfirmationCancel = () => {
328
333
  setShowConfirmationDialog(false);
329
334
  setShowRequiredFieldConfirmationDialog(false);
330
- setShowAuthorDrawer(false);
331
335
  if (pendingAction === 'select' && pendingSelection) {
332
336
  setSelection(pendingSelection);
333
337
  setNewAffiliation(false);
@@ -368,19 +372,17 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, aff
368
372
  react_1.default.createElement(AffiliationList_1.AffiliationList, { affiliation: selection, affiliations: affiliations, onSelect: handleSelect, onDelete: handleShowDeleteDialog, lastSavedAffiliationId: savedAffiliationId }))),
369
373
  react_1.default.createElement(style_guide_1.ScrollableModalContent, { "data-cy": "affiliations-modal-content" }, selection ? (react_1.default.createElement(react_1.default.Fragment, null,
370
374
  react_1.default.createElement(AffiliationTabs, null,
371
- react_1.default.createElement(ModalFormActions_1.ModalFormActions, { type: 'affiliation', form: 'affiliation-form', onDelete: handleDeleteAffiliation, showingDeleteDialog: showingDeleteDialog &&
375
+ react_1.default.createElement(ModalFormActions_1.ModalFormActions, { type: 'affiliation', form: 'affiliation-form', onSubmitForm: () => actionsRef.current?.submitForm?.(), onDelete: handleDeleteAffiliation, showingDeleteDialog: showingDeleteDialog &&
372
376
  !(showConfirmationDialog ||
373
377
  showRequiredFieldConfirmationDialog), showDeleteDialog: handleShowDeleteDialog, newEntity: newAffiliation, isDisableSave: isDisableSave }),
374
378
  react_1.default.createElement(style_guide_1.InspectorTabList, null,
375
379
  react_1.default.createElement(style_guide_1.InspectorTab, null, "Details"),
376
- react_1.default.createElement(style_guide_1.InspectorTab, null, "Authors")),
380
+ onOpenAuthorsModal && react_1.default.createElement(style_guide_1.InspectorTab, null, "Authors")),
377
381
  react_1.default.createElement(style_guide_1.InspectorTabPanels, null,
378
382
  react_1.default.createElement(AffiliationTabPanel, null,
379
- react_1.default.createElement(AffiliationForm_1.AffiliationForm, { values: (0, normalize_1.checkID)(selection, 'affiliation'), onSave: () => handleSaveAffiliation(valuesRef.current), onChange: handleAffiliationChange, actionsRef: actionsRef })),
380
- react_1.default.createElement(AffiliationTabPanel, null,
381
- react_1.default.createElement(GenericDrawerGroup_1.DrawerGroup, { Drawer: GenericDrawer_1.GenericDrawer, removeItem: (id) => {
382
- setSelectedAuthorIds((prev) => prev.filter((authorId) => authorId !== id));
383
- }, selectedItems: selectedAuthors, onSelect: selectAuthor, items: makeAuthorItems(authors), showDrawer: showAuthorDrawer, setShowDrawer: setShowAuthorDrawer, title: "Authors", cy: "affiliations", labelField: "label", buttonText: "Affiliate Authors", Icon: react_1.default.createElement(style_guide_1.AddUserIcon, { width: 16, height: 16 }) })))),
383
+ react_1.default.createElement(AffiliationForm_1.AffiliationForm, { values: (0, normalize_1.checkID)(selection, 'affiliation'), onSave: (attrs) => handleSaveAffiliation(attrs), onChange: handleAffiliationChange, actionsRef: actionsRef })),
384
+ onOpenAuthorsModal && (react_1.default.createElement(AffiliationTabPanel, null,
385
+ react_1.default.createElement(AuthorsPanel_1.AuthorsPanel, { items: makeAuthorItems(authors), selectedItems: selectedAuthors, onSelect: selectAuthor, onOpenAuthorsModal: onOpenAuthorsModal }))))),
384
386
  react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showRequiredFieldConfirmationDialog, onPrimary: () => setShowRequiredFieldConfirmationDialog(false), onSecondary: handleConfirmationCancel, type: ConfirmationDialog_1.DialogType.REQUIRED, entityType: "affiliation" }),
385
387
  react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showConfirmationDialog, onPrimary: handleConfirmationSave, onSecondary: handleConfirmationCancel, type: ConfirmationDialog_1.DialogType.SAVE, entityType: "affiliation" }))) : (react_1.default.createElement(FormPlaceholder_1.FormPlaceholder, { type: "affiliation", title: "Affiliation Details", message: "Select an affiliation from the list to display it's details here.", placeholderIcon: react_1.default.createElement(style_guide_1.AffiliationPlaceholderIcon, null) })))),
386
388
  react_1.default.createElement(FormFooter_1.default, { onCancel: handleClose }))));
@@ -447,41 +449,3 @@ const StyledModalSidebarHeader = (0, styled_components_1.default)(style_guide_1.
447
449
  margin-top: 8px;
448
450
  margin-bottom: 16px;
449
451
  `;
450
- const openAffiliationsModal = (pos, view) => {
451
- if (!view) {
452
- return;
453
- }
454
- const { state } = view;
455
- const props = (0, editor_props_1.getEditorProps)(state);
456
- const contributors = (0, view_1.findChildrenAttrsByType)(view, transform_1.schema.nodes.contributor);
457
- const componentProps = {
458
- affiliations: [],
459
- authors: contributors,
460
- onSaveAffiliation: (affiliation) => (0, exports.handleSaveAffiliation)(view, affiliation, pos),
461
- onDeleteAffiliation: (affiliation) => (0, exports.handleDeleteAffiliation)(view, affiliation),
462
- onUpdateAuthors: (authors) => (0, exports.handleUpdateAuthors)(view, authors),
463
- addNewAffiliation: true,
464
- };
465
- const dialog = (0, ReactSubView_1.default)(props, exports.AffiliationsModal, componentProps, state.doc, () => pos, view);
466
- view.focus();
467
- document.body.appendChild(dialog);
468
- };
469
- exports.openAffiliationsModal = openAffiliationsModal;
470
- const handleSaveAffiliation = (view, affiliation, affiliationsPos) => {
471
- const update = (0, view_1.updateNodeAttrs)(view, transform_1.schema.nodes.affiliation, affiliation);
472
- if (!update) {
473
- const node = transform_1.schema.nodes.affiliation.create(affiliation);
474
- view.dispatch(view.state.tr.insert(affiliationsPos + 1, node));
475
- }
476
- };
477
- exports.handleSaveAffiliation = handleSaveAffiliation;
478
- const handleDeleteAffiliation = (view, affiliation) => {
479
- (0, view_1.deleteNode)(view, affiliation.id);
480
- };
481
- exports.handleDeleteAffiliation = handleDeleteAffiliation;
482
- const handleUpdateAuthors = (view, authors) => {
483
- authors.forEach((author) => {
484
- (0, view_1.updateNodeAttrs)(view, transform_1.schema.nodes.contributor, author);
485
- });
486
- };
487
- exports.handleUpdateAuthors = handleUpdateAuthors;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AffiliationsPanel = void 0;
7
+ const style_guide_1 = require("@manuscripts/style-guide");
8
+ const react_1 = __importDefault(require("react"));
9
+ const GenericPanel_1 = require("../authors-affiliations/GenericPanel");
10
+ function affiliationSecondaryLine(item) {
11
+ const line = [item.city, item.county, item.country].filter(Boolean).join(', ');
12
+ return line || undefined;
13
+ }
14
+ const AffiliationsPanel = ({ items, selectedItems = [], onSelect, onOpenAffiliationsModal, }) => {
15
+ const selectedIds = (0, GenericPanel_1.useListSelectedIds)(selectedItems);
16
+ return (react_1.default.createElement(GenericPanel_1.GenericPanel, { title: "Institutional Affiliations", createLabel: "Create New Affiliation", onCreate: onOpenAffiliationsModal, createDataCy: "add-affiliations-link", emptyDataCy: "affiliations-panel-empty", isEmpty: items.length === 0, emptyIcon: react_1.default.createElement(style_guide_1.AffiliationPlaceholderIcon, null), emptyMessage: react_1.default.createElement(react_1.default.Fragment, null,
17
+ "There are no affiliations attributed yet!",
18
+ react_1.default.createElement("br", null),
19
+ "Click \u2018Create New Affiliation\u2019") },
20
+ react_1.default.createElement(GenericPanel_1.ListItems, { "data-cy": "affiliations-panel" }, items.map((item) => (react_1.default.createElement(GenericPanel_1.ListItem, { key: item.id, selected: selectedIds.has(item.id), onClick: () => onSelect(item.id), primary: item.institution, secondary: affiliationSecondaryLine(item) }))))));
21
+ };
22
+ exports.AffiliationsPanel = AffiliationsPanel;
@@ -73,11 +73,10 @@ const AuthorDetailsForm = ({ values, onChange, onSave, actionsRef, isEmailRequir
73
73
  formRef.current.setFieldValue('creditRoles', selectedCreditRoles);
74
74
  }
75
75
  }, [selectedCreditRoles]);
76
- if (actionsRef && !actionsRef.current) {
76
+ if (actionsRef) {
77
77
  actionsRef.current = {
78
- reset: () => {
79
- formRef.current?.resetForm();
80
- },
78
+ reset: () => formRef.current?.resetForm(),
79
+ submitForm: () => formRef.current?.submitForm(),
81
80
  };
82
81
  }
83
82
  const validateAuthor = (values) => {
@@ -51,7 +51,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
51
51
  return (mod && mod.__esModule) ? mod : { "default": mod };
52
52
  };
53
53
  Object.defineProperty(exports, "__esModule", { value: true });
54
- exports.handleDeleteContributor = exports.handleSaveContributor = exports.openAuthorsModal = exports.AuthorsModal = exports.authorsReducer = void 0;
54
+ exports.AuthorsModal = exports.authorsReducer = void 0;
55
55
  const style_guide_1 = require("@manuscripts/style-guide");
56
56
  const transform_1 = require("@manuscripts/transform");
57
57
  const lodash_1 = require("lodash");
@@ -65,18 +65,22 @@ const FormFooter_1 = __importDefault(require("../form/FormFooter"));
65
65
  const FormPlaceholder_1 = require("../form/FormPlaceholder");
66
66
  const ModalFormActions_1 = require("../form/ModalFormActions");
67
67
  const GenericDrawerGroup_1 = require("../modal-drawer/GenericDrawerGroup");
68
- const AffiliationDrawer_1 = require("./AffiliationDrawer");
68
+ const AffiliationsPanel_1 = require("../affiliations/AffiliationsPanel");
69
69
  const AuthorDetailsForm_1 = require("./AuthorDetailsForm");
70
70
  const AuthorList_1 = require("./AuthorList");
71
71
  const CreditDrawer_1 = require("./CreditDrawer");
72
72
  const useManageAffiliations_1 = require("./useManageAffiliations");
73
73
  const useManageCredit_1 = require("./useManageCredit");
74
- const editor_props_1 = require("../../plugins/editor-props");
75
- const ReactSubView_1 = __importDefault(require("../../views/ReactSubView"));
76
- const view_1 = require("../../lib/view");
77
74
  exports.authorsReducer = (0, array_reducer_1.arrayReducer)((a, b) => a.id === b.id);
78
- const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author, onSaveAuthor, onDeleteAuthor, addNewAuthor = false, }) => {
75
+ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author, onSaveAuthor, onDeleteAuthor, addNewAuthor = false, onOpenAffiliationsModal, onClose, }) => {
79
76
  const [isOpen, setOpen] = (0, react_1.useState)(true);
77
+ const prevIsOpenRef = (0, react_1.useRef)(true);
78
+ (0, react_1.useEffect)(() => {
79
+ if (prevIsOpenRef.current && !isOpen) {
80
+ onClose?.();
81
+ }
82
+ prevIsOpenRef.current = isOpen;
83
+ }, [isOpen, onClose]);
80
84
  const [isDisableSave, setDisableSave] = (0, react_1.useState)(true);
81
85
  const [isEmailRequired, setEmailRequired] = (0, react_1.useState)(false);
82
86
  const [showConfirmationDialog, setShowConfirmationDialog] = (0, react_1.useState)(false);
@@ -99,7 +103,7 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
99
103
  }
100
104
  }, [addNewAuthor]);
101
105
  const [selection, setSelection] = (0, react_1.useState)(author);
102
- const { showAffiliationDrawer, setShowAffiliationDrawer, selectedAffiliations, setSelectedAffiliations, removeAffiliation, selectAffiliation, affiliations, } = (0, useManageAffiliations_1.useManageAffiliations)(selection, $affiliations);
106
+ const { selectedAffiliations, setSelectedAffiliations, selectAffiliation, affiliations, } = (0, useManageAffiliations_1.useManageAffiliations)(selection, $affiliations);
103
107
  (0, react_1.useEffect)(() => {
104
108
  const currentAuthor = selection;
105
109
  const relevantAffiliations = affiliations.filter((item) => currentAuthor?.affiliationIDs?.includes(item.id));
@@ -126,12 +130,10 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
126
130
  else {
127
131
  updateAffiliationSelection(author);
128
132
  setSelection(author);
129
- setShowAffiliationDrawer(false);
130
133
  setNewAuthor(false);
131
134
  }
132
135
  }
133
136
  else {
134
- setShowAffiliationDrawer(false);
135
137
  updateAffiliationSelection(author);
136
138
  setSelection(author);
137
139
  setNewAuthor(false);
@@ -172,7 +174,6 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
172
174
  setSelection(nextAuthor);
173
175
  setNextAuthor(null);
174
176
  setNewAuthor(false);
175
- setShowAffiliationDrawer(false);
176
177
  updateAffiliationSelection(nextAuthor);
177
178
  setIsCreatingNewAuthor(false);
178
179
  }
@@ -205,7 +206,6 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
205
206
  }
206
207
  setShowConfirmationDialog(false);
207
208
  setShowRequiredFieldConfirmationDialog(false);
208
- setShowAffiliationDrawer(false);
209
209
  };
210
210
  const saveAuthor = (values) => {
211
211
  if (!values || !selection) {
@@ -224,7 +224,6 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
224
224
  setSelection(author);
225
225
  setShowConfirmationDialog(false);
226
226
  setNewAuthor(false);
227
- setShowAffiliationDrawer(false);
228
227
  setIsCreatingNewAuthor(false);
229
228
  dispatchAuthors({
230
229
  type: 'update',
@@ -281,7 +280,6 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
281
280
  }
282
281
  else {
283
282
  createNewAuthor();
284
- setShowAffiliationDrawer(false);
285
283
  }
286
284
  };
287
285
  const deleteAuthor = () => {
@@ -350,19 +348,19 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
350
348
  react_1.default.createElement(AuthorList_1.AuthorList, { author: selection, authors: authors, onSelect: selectAuthor, onDelete: () => setShowDeleteDialog((prev) => !prev), moveAuthor: moveAuthor, lastSavedAuthor: lastSavedAuthor }))),
351
349
  react_1.default.createElement(style_guide_1.ScrollableModalContent, { "data-cy": "author-modal-content" }, selection ? (react_1.default.createElement(react_1.default.Fragment, null,
352
350
  react_1.default.createElement(AuthorTabs, null,
353
- react_1.default.createElement(ModalFormActions_1.ModalFormActions, { form: 'author-details-form', type: "author", onDelete: deleteAuthor, showingDeleteDialog: showingDeleteDialog, showDeleteDialog: () => setShowDeleteDialog((prev) => !prev), newEntity: newAuthor ||
351
+ react_1.default.createElement(ModalFormActions_1.ModalFormActions, { form: 'author-details-form', onSubmitForm: () => actionsRef.current?.submitForm?.(), type: "author", onDelete: deleteAuthor, showingDeleteDialog: showingDeleteDialog, showDeleteDialog: () => setShowDeleteDialog((prev) => !prev), newEntity: newAuthor ||
354
352
  (isCreatingNewAuthor &&
355
353
  !showConfirmationDialog &&
356
354
  !showRequiredFieldConfirmationDialog), isDisableSave: isDisableSave }),
357
355
  react_1.default.createElement(style_guide_1.InspectorTabList, null,
358
356
  react_1.default.createElement(style_guide_1.InspectorTab, null, "Details"),
359
- react_1.default.createElement(style_guide_1.InspectorTab, null, "Affiliations"),
357
+ onOpenAffiliationsModal && (react_1.default.createElement(style_guide_1.InspectorTab, null, "Affiliations")),
360
358
  react_1.default.createElement(style_guide_1.InspectorTab, null, "Contributions (CRediT)")),
361
359
  react_1.default.createElement(style_guide_1.InspectorTabPanels, null,
362
360
  react_1.default.createElement(AuthorTabPanel, null,
363
361
  react_1.default.createElement(AuthorDetailsForm_1.AuthorDetailsForm, { values: (0, normalize_1.normalizeAuthor)(selection), onChange: changeAuthor, onSave: saveAuthor, actionsRef: actionsRef, isEmailRequired: isEmailRequired, selectedAffiliations: selectedAffiliations.map((a) => a.id), authorFormRef: authorFormRef, selectedCreditRoles: selectedCreditRoles })),
364
- react_1.default.createElement(AuthorTabPanel, null,
365
- react_1.default.createElement(GenericDrawerGroup_1.DrawerGroup, { Drawer: AffiliationDrawer_1.AffiliationsDrawer, removeItem: removeAffiliation, selectedItems: selectedAffiliations, onSelect: selectAffiliation, items: affiliations, showDrawer: showAffiliationDrawer, setShowDrawer: setShowAffiliationDrawer, title: "Affiliations", buttonText: "Assign Institutions", cy: "affiliations", labelField: "institution", Icon: react_1.default.createElement(style_guide_1.AddInstitutionIcon, { width: 16, height: 16 }) })),
362
+ onOpenAffiliationsModal && (react_1.default.createElement(AuthorTabPanel, null,
363
+ react_1.default.createElement(AffiliationsPanel_1.AffiliationsPanel, { items: affiliations, selectedItems: selectedAffiliations, onSelect: selectAffiliation, onOpenAffiliationsModal: onOpenAffiliationsModal }))),
366
364
  react_1.default.createElement(AuthorTabPanel, null,
367
365
  react_1.default.createElement(GenericDrawerGroup_1.DrawerGroup, { Drawer: CreditDrawer_1.CreditDrawer, removeItem: removeCreditRole, selectedItems: selectedCreditRoles.map((r) => ({
368
366
  id: r.vocabTerm,
@@ -431,34 +429,3 @@ const StyledModalBody = (0, styled_components_1.default)(style_guide_1.ModalBody
431
429
  const StyledModalSidebarHeader = (0, styled_components_1.default)(style_guide_1.ModalSidebarHeader) `
432
430
  margin-bottom: 16px;
433
431
  `;
434
- const openAuthorsModal = (pos, view) => {
435
- if (!view) {
436
- return;
437
- }
438
- const { state } = view;
439
- const props = (0, editor_props_1.getEditorProps)(state);
440
- const affiliations = (0, view_1.findChildrenAttrsByType)(view, transform_1.schema.nodes.affiliation);
441
- const componentProps = {
442
- authors: [],
443
- affiliations,
444
- onSaveAuthor: (contributor) => (0, exports.handleSaveContributor)(view, contributor, pos),
445
- onDeleteAuthor: (contributor) => (0, exports.handleDeleteContributor)(view, contributor),
446
- addNewAuthor: true,
447
- };
448
- const dialog = (0, ReactSubView_1.default)(props, exports.AuthorsModal, componentProps, state.doc, () => pos, view);
449
- view.focus();
450
- document.body.appendChild(dialog);
451
- };
452
- exports.openAuthorsModal = openAuthorsModal;
453
- const handleSaveContributor = (view, contributor, contributorsPos) => {
454
- const update = (0, view_1.updateNodeAttrs)(view, transform_1.schema.nodes.contributor, contributor);
455
- if (!update) {
456
- const node = transform_1.schema.nodes.contributor.create(contributor);
457
- view.dispatch(view.state.tr.insert(contributorsPos + 1, node));
458
- }
459
- };
460
- exports.handleSaveContributor = handleSaveContributor;
461
- const handleDeleteContributor = (view, contributor) => {
462
- (0, view_1.deleteNode)(view, contributor.id);
463
- };
464
- exports.handleDeleteContributor = handleDeleteContributor;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AuthorsPanel = void 0;
7
+ const style_guide_1 = require("@manuscripts/style-guide");
8
+ const react_1 = __importDefault(require("react"));
9
+ const GenericPanel_1 = require("../authors-affiliations/GenericPanel");
10
+ const AuthorsPanel = ({ items, selectedItems = [], onSelect, onOpenAuthorsModal, }) => {
11
+ const selectedIds = (0, GenericPanel_1.useListSelectedIds)(selectedItems);
12
+ return (react_1.default.createElement(GenericPanel_1.GenericPanel, { title: "Authors", createLabel: "Add New Author", onCreate: onOpenAuthorsModal, createDataCy: "add-authors-link", emptyDataCy: "authors-panel-empty", isEmpty: items.length === 0, emptyIcon: react_1.default.createElement(style_guide_1.AuthorPlaceholderIcon, null), emptyMessage: react_1.default.createElement(react_1.default.Fragment, null,
13
+ "There are no authors attributed yet!",
14
+ react_1.default.createElement("br", null),
15
+ "Click \u2018Add New Author\u2019") },
16
+ react_1.default.createElement(GenericPanel_1.ListItems, { "data-cy": "authors-panel" }, items.map((item) => (react_1.default.createElement(GenericPanel_1.ListItem, { key: item.id, selected: selectedIds.has(item.id), onClick: () => onSelect(item.id), primary: item.label }))))));
17
+ };
18
+ exports.AuthorsPanel = AuthorsPanel;
@@ -5,8 +5,12 @@ const react_1 = require("react");
5
5
  const array_reducer_1 = require("../../lib/array-reducer");
6
6
  exports.affiliationsReducer = (0, array_reducer_1.arrayReducer)((a, b) => a.id === b.id);
7
7
  const useManageAffiliations = (selection, $affiliations) => {
8
- const [affiliations] = (0, react_1.useReducer)(exports.affiliationsReducer, $affiliations);
9
- const [showAffiliationDrawer, setShowAffiliationDrawer] = (0, react_1.useState)(false);
8
+ const [affiliations, dispatchAffiliations] = (0, react_1.useReducer)(exports.affiliationsReducer, [
9
+ ...$affiliations,
10
+ ]);
11
+ (0, react_1.useEffect)(() => {
12
+ dispatchAffiliations({ type: 'set', state: [...$affiliations] });
13
+ }, [$affiliations]);
10
14
  const [selectedAffiliations, setSelectedAffiliations] = (0, react_1.useState)([]);
11
15
  const removeAffiliation = (affId) => {
12
16
  if (!selection) {
@@ -29,8 +33,6 @@ const useManageAffiliations = (selection, $affiliations) => {
29
33
  setSelectedAffiliations(affiliations.filter((item) => newAffiliations.includes(item.id)));
30
34
  };
31
35
  return {
32
- showAffiliationDrawer,
33
- setShowAffiliationDrawer,
34
36
  selectedAffiliations,
35
37
  setSelectedAffiliations,
36
38
  removeAffiliation,
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ /*!
3
+ * © 2026 Atypon Systems LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ var desc = Object.getOwnPropertyDescriptor(m, k);
20
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
21
+ desc = { enumerable: true, get: function() { return m[k]; } };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ }) : (function(o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ }));
28
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }) : function(o, v) {
31
+ o["default"] = v;
32
+ });
33
+ var __importStar = (this && this.__importStar) || (function () {
34
+ var ownKeys = function(o) {
35
+ ownKeys = Object.getOwnPropertyNames || function (o) {
36
+ var ar = [];
37
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
38
+ return ar;
39
+ };
40
+ return ownKeys(o);
41
+ };
42
+ return function (mod) {
43
+ if (mod && mod.__esModule) return mod;
44
+ var result = {};
45
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
46
+ __setModuleDefault(result, mod);
47
+ return result;
48
+ };
49
+ })();
50
+ var __importDefault = (this && this.__importDefault) || function (mod) {
51
+ return (mod && mod.__esModule) ? mod : { "default": mod };
52
+ };
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.openAuthorsAndAffiliationsModals = exports.AuthorsAndAffiliationsModals = void 0;
55
+ const transform_1 = require("@manuscripts/transform");
56
+ const react_1 = __importStar(require("react"));
57
+ const editor_props_1 = require("../../plugins/editor-props");
58
+ const ReactSubView_1 = __importDefault(require("../../views/ReactSubView"));
59
+ const view_1 = require("../../lib/view");
60
+ const AffiliationsModal_1 = require("../affiliations/AffiliationsModal");
61
+ const AuthorsModal_1 = require("../authors/AuthorsModal");
62
+ function insertNode(parentType, childType) {
63
+ return (view, attrs) => {
64
+ const parent = (0, view_1.findChildByType)(view, parentType);
65
+ if (parent) {
66
+ view.dispatch(view.state.tr.insert(parent.pos + 1, childType.create(attrs)));
67
+ }
68
+ };
69
+ }
70
+ function upsertNode(nodeType, insertFn) {
71
+ return (view, attrs) => {
72
+ if (!(0, view_1.updateNodeAttrs)(view, nodeType, attrs)) {
73
+ insertFn(view, attrs);
74
+ }
75
+ };
76
+ }
77
+ const insertAuthorNode = insertNode(transform_1.schema.nodes.contributors, transform_1.schema.nodes.contributor);
78
+ const insertAffiliationNode = insertNode(transform_1.schema.nodes.affiliations, transform_1.schema.nodes.affiliation);
79
+ const upsertAuthor = upsertNode(transform_1.schema.nodes.contributor, insertAuthorNode);
80
+ const upsertAffiliation = upsertNode(transform_1.schema.nodes.affiliation, insertAffiliationNode);
81
+ const AuthorsAndAffiliationsModals = ({ initialModal, view, author, affiliation, addNewAuthor, addNewAffiliation, }) => {
82
+ const [showOverlay, setShowOverlay] = (0, react_1.useState)(false);
83
+ const [authors, setAuthors] = (0, react_1.useState)(() => (0, view_1.findChildrenAttrsByType)(view, transform_1.schema.nodes.contributor));
84
+ const [affiliations, setAffiliations] = (0, react_1.useState)(() => (0, view_1.findChildrenAttrsByType)(view, transform_1.schema.nodes.affiliation));
85
+ const handleOpenOverlay = () => setShowOverlay(true);
86
+ const handleOverlayClose = () => {
87
+ setShowOverlay(false);
88
+ setAuthors((0, view_1.findChildrenAttrsByType)(view, transform_1.schema.nodes.contributor));
89
+ setAffiliations((0, view_1.findChildrenAttrsByType)(view, transform_1.schema.nodes.affiliation));
90
+ };
91
+ const authorsProps = {
92
+ author,
93
+ authors,
94
+ affiliations,
95
+ addNewAuthor,
96
+ onSaveAuthor: (a) => upsertAuthor(view, a),
97
+ onDeleteAuthor: (a) => (0, view_1.deleteNode)(view, a.id),
98
+ };
99
+ const affiliationsProps = {
100
+ affiliation,
101
+ authors,
102
+ affiliations,
103
+ addNewAffiliation,
104
+ onSaveAffiliation: (a) => upsertAffiliation(view, a),
105
+ onDeleteAffiliation: (a) => (0, view_1.deleteNode)(view, a.id),
106
+ onUpdateAuthors: (updated) => updated.forEach((a) => (0, view_1.updateNodeAttrs)(view, transform_1.schema.nodes.contributor, a)),
107
+ };
108
+ if (initialModal === 'authors') {
109
+ return (react_1.default.createElement(react_1.default.Fragment, null,
110
+ react_1.default.createElement(AuthorsModal_1.AuthorsModal, { ...authorsProps, onOpenAffiliationsModal: handleOpenOverlay }),
111
+ showOverlay && (react_1.default.createElement(AffiliationsModal_1.AffiliationsModal, { ...affiliationsProps, addNewAffiliation: true, onClose: handleOverlayClose }))));
112
+ }
113
+ return (react_1.default.createElement(react_1.default.Fragment, null,
114
+ react_1.default.createElement(AffiliationsModal_1.AffiliationsModal, { ...affiliationsProps, onOpenAuthorsModal: handleOpenOverlay }),
115
+ showOverlay && (react_1.default.createElement(AuthorsModal_1.AuthorsModal, { ...authorsProps, addNewAuthor: true, onClose: handleOverlayClose }))));
116
+ };
117
+ exports.AuthorsAndAffiliationsModals = AuthorsAndAffiliationsModals;
118
+ const openAuthorsAndAffiliationsModals = (pos, view, initialModal) => {
119
+ if (!view) {
120
+ return;
121
+ }
122
+ const { state } = view;
123
+ const props = (0, editor_props_1.getEditorProps)(state);
124
+ const componentProps = {
125
+ initialModal,
126
+ view: view,
127
+ addNewAuthor: initialModal === 'authors',
128
+ addNewAffiliation: initialModal === 'affiliations',
129
+ };
130
+ const dialog = (0, ReactSubView_1.default)(props, exports.AuthorsAndAffiliationsModals, componentProps, state.doc, () => pos, view);
131
+ view.focus();
132
+ document.body.appendChild(dialog);
133
+ };
134
+ exports.openAuthorsAndAffiliationsModals = openAuthorsAndAffiliationsModals;