@manuscripts/body-editor 3.0.2 → 3.0.3-LEAN-4579.1

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 (39) hide show
  1. package/dist/cjs/components/affiliations/AffiliationsModal.js +79 -126
  2. package/dist/cjs/components/authors/AffiliationDrawer.js +24 -0
  3. package/dist/cjs/components/authors/AuthorDetailsForm.js +11 -9
  4. package/dist/cjs/components/authors/AuthorsModal.js +121 -204
  5. package/dist/cjs/components/authors/CreditDrawer.js +37 -0
  6. package/dist/cjs/components/authors/useManageAffiliations.js +41 -0
  7. package/dist/cjs/components/authors/useManageCredit.js +43 -0
  8. package/dist/cjs/components/form/FormFooter.js +2 -0
  9. package/dist/cjs/components/form/ModalFormActions.js +4 -4
  10. package/dist/cjs/components/modal-drawer/GenericDrawer.js +16 -0
  11. package/dist/cjs/components/modal-drawer/GenericDrawerGroup.js +75 -0
  12. package/dist/cjs/lib/normalize.js +49 -0
  13. package/dist/cjs/versions.js +1 -1
  14. package/dist/es/components/affiliations/AffiliationsModal.js +80 -127
  15. package/dist/es/components/authors/AffiliationDrawer.js +17 -0
  16. package/dist/es/components/authors/AuthorDetailsForm.js +9 -7
  17. package/dist/es/components/authors/AuthorsModal.js +123 -206
  18. package/dist/es/components/authors/CreditDrawer.js +30 -0
  19. package/dist/es/components/authors/useManageAffiliations.js +37 -0
  20. package/dist/es/components/authors/useManageCredit.js +39 -0
  21. package/dist/es/components/form/FormFooter.js +2 -0
  22. package/dist/es/components/form/ModalFormActions.js +4 -4
  23. package/dist/es/components/modal-drawer/GenericDrawer.js +9 -0
  24. package/dist/es/components/modal-drawer/GenericDrawerGroup.js +68 -0
  25. package/dist/es/lib/normalize.js +44 -0
  26. package/dist/es/versions.js +1 -1
  27. package/dist/types/components/authors/AffiliationDrawer.d.ts +12 -0
  28. package/dist/types/components/authors/AuthorDetailsForm.d.ts +4 -1
  29. package/dist/types/components/authors/AuthorsModal.d.ts +1 -2
  30. package/dist/types/components/authors/CreditDrawer.d.ts +14 -0
  31. package/dist/types/components/authors/useManageAffiliations.d.ts +18 -0
  32. package/dist/types/components/authors/useManageCredit.d.ts +13 -0
  33. package/dist/types/components/form/ModalFormActions.d.ts +2 -2
  34. package/dist/types/components/modal-drawer/GenericDrawer.d.ts +14 -0
  35. package/dist/types/components/modal-drawer/GenericDrawerGroup.d.ts +45 -0
  36. package/dist/types/lib/normalize.d.ts +25 -0
  37. package/dist/types/types.d.ts +1 -0
  38. package/dist/types/versions.d.ts +1 -1
  39. package/package.json +4 -4
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /*!
3
- * © 2024 Atypon Systems LLC
3
+ * © 2025 Atypon Systems LLC
4
4
  *
5
5
  * Licensed under the Apache License, Version 2.0 (the "License");
6
6
  * you may not use this file except in compliance with the License.
@@ -41,114 +41,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
41
41
  return (mod && mod.__esModule) ? mod : { "default": mod };
42
42
  };
43
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
- exports.AuthorsModal = exports.affiliationsReducer = exports.authorsReducer = void 0;
44
+ exports.AuthorsModal = exports.authorsReducer = void 0;
45
45
  const json_schema_1 = require("@manuscripts/json-schema");
46
46
  const style_guide_1 = require("@manuscripts/style-guide");
47
+ const transform_1 = require("@manuscripts/transform");
47
48
  const lodash_1 = require("lodash");
48
49
  const react_1 = __importStar(require("react"));
49
50
  const styled_components_1 = __importDefault(require("styled-components"));
50
51
  const array_reducer_1 = require("../../lib/array-reducer");
51
52
  const authors_1 = require("../../lib/authors");
53
+ const normalize_1 = require("../../lib/normalize");
52
54
  const ConfirmationDialog_1 = require("../dialog/ConfirmationDialog");
53
55
  const FormFooter_1 = __importDefault(require("../form/FormFooter"));
54
56
  const FormPlaceholder_1 = require("../form/FormPlaceholder");
55
57
  const ModalFormActions_1 = require("../form/ModalFormActions");
58
+ const GenericDrawerGroup_1 = require("../modal-drawer/GenericDrawerGroup");
59
+ const AffiliationDrawer_1 = require("./AffiliationDrawer");
56
60
  const AuthorDetailsForm_1 = require("./AuthorDetailsForm");
57
61
  const AuthorList_1 = require("./AuthorList");
58
- const AddAuthorButton = styled_components_1.default.div `
59
- display: flex;
60
- align-items: center;
61
- padding: 12px 8px 12px 12px;
62
- cursor: pointer;
63
- &[data-active='true'] {
64
- background: ${(props) => props.theme.colors.background.fifth};
65
- border: 1px solid ${(props) => props.theme.colors.border.primary};
66
- border-left: 0;
67
- border-right: 0;
68
- }
69
- `;
70
- const ActionTitle = styled_components_1.default.div `
71
- padding-left: ${(props) => props.theme.grid.unit * 2}px;
72
- `;
73
- const FormLabel = styled_components_1.default.legend `
74
- margin-bottom: 12px;
75
- font: ${(props) => props.theme.font.weight.normal}
76
- ${(props) => props.theme.font.size.xlarge} /
77
- ${(props) => props.theme.font.lineHeight.large}
78
- ${(props) => props.theme.font.family.sans};
79
- letter-spacing: -0.4px;
80
- color: ${(props) => props.theme.colors.text.secondary};
81
- `;
82
- const AuthorForms = styled_components_1.default.div `
83
- padding-left: ${(props) => props.theme.grid.unit * 3}px;
84
- padding-right: ${(props) => props.theme.grid.unit * 3}px;
85
- position: relative;
86
- margin-top: 20px;
87
- `;
88
- const StyledSidebarContent = (0, styled_components_1.default)(style_guide_1.SidebarContent) `
89
- padding: 0;
90
- `;
91
- const AuthorsSection = styled_components_1.default.div `
92
- margin-top: ${(props) => props.theme.grid.unit * 4}px;
93
- padding-top: ${(props) => props.theme.grid.unit * 4}px;
94
- border-top: 1px solid ${(props) => props.theme.colors.border.tertiary};
95
- `;
96
- const AuthorsHeader = styled_components_1.default.div `
97
- display: flex;
98
- justify-content: space-between;
99
- align-items: flex-start;
100
- flex-direction: column;
101
- margin-bottom: ${(props) => props.theme.grid.unit * 2}px;
102
- `;
103
- const AuthorsTitle = styled_components_1.default.h3 `
104
- margin: 0;
105
- font-weight: ${(props) => props.theme.font.weight.normal};
106
- font-size: ${(props) => props.theme.font.size.large};
107
- font-family: ${(props) => props.theme.font.family.sans};
108
- color: ${(props) => props.theme.colors.text.secondary};
109
- `;
110
- const AffiliateButton = styled_components_1.default.button `
111
- color: ${(props) => props.theme.colors.brand.default};
112
- background: none;
113
- border: none;
114
- cursor: pointer;
115
- padding: 0;
116
- font: ${(props) => props.theme.font.weight.normal}
117
- ${(props) => props.theme.font.size.normal}
118
- ${(props) => props.theme.font.family.sans};
119
- display: flex;
120
- align-items: center;
121
- gap: 4px;
122
- margin-top: ${(props) => props.theme.grid.unit * 2}px;
123
- &:hover {
124
- opacity: 0.8;
125
- }
126
- `;
127
- const StyledModalBody = (0, styled_components_1.default)(style_guide_1.ModalBody) `
128
- position: relative;
129
- height: calc(90vh - 40px);
130
- `;
131
- const StyledModalSidebarHeader = (0, styled_components_1.default)(style_guide_1.ModalSidebarHeader) `
132
- margin-bottom: 16px;
133
- `;
62
+ const CreditDrawer_1 = require("./CreditDrawer");
63
+ const useManageAffiliations_1 = require("./useManageAffiliations");
64
+ const useManageCredit_1 = require("./useManageCredit");
134
65
  exports.authorsReducer = (0, array_reducer_1.arrayReducer)((a, b) => a.id === b.id);
135
- exports.affiliationsReducer = (0, array_reducer_1.arrayReducer)((a, b) => a.id === b.id);
136
- const normalize = (author) => ({
137
- id: author.id,
138
- role: author.role || '',
139
- affiliations: (author.affiliations || []).sort(),
140
- bibliographicName: author.bibliographicName,
141
- email: author.email || '',
142
- isCorresponding: author.isCorresponding || false,
143
- ORCIDIdentifier: author.ORCIDIdentifier || '',
144
- priority: author.priority || 0,
145
- isJointContributor: author.isJointContributor || false,
146
- userID: author.userID || '',
147
- invitationID: author.invitationID || '',
148
- footnote: author.footnote || [],
149
- corresp: author.corresp || [],
150
- prefix: author.prefix || '',
151
- });
152
66
  const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author, onSaveAuthor, onDeleteAuthor, addNewAuthor = false, }) => {
153
67
  const [isOpen, setOpen] = (0, react_1.useState)(true);
154
68
  const [isDisableSave, setDisableSave] = (0, react_1.useState)(true);
@@ -156,48 +70,38 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
156
70
  const [showConfirmationDialog, setShowConfirmationDialog] = (0, react_1.useState)(false);
157
71
  const [showRequiredFieldConfirmationDialog, setShowRequiredFieldConfirmationDialog,] = (0, react_1.useState)(false);
158
72
  const [lastSavedAuthor, setLastSavedAuthor] = (0, react_1.useState)(null);
159
- const [showDeleteDialog, setShowDeleteDialog] = (0, react_1.useState)(false);
73
+ const [showingDeleteDialog, setShowDeleteDialog] = (0, react_1.useState)(false);
160
74
  const [newAuthor, setNewAuthor] = (0, react_1.useState)(false);
161
75
  const [unSavedChanges, setUnSavedChanges] = (0, react_1.useState)(false);
162
76
  const [nextAuthor, setNextAuthor] = (0, react_1.useState)(null);
163
77
  const [isSwitchingAuthor, setIsSwitchingAuthor] = (0, react_1.useState)(false);
164
78
  const [isCreatingNewAuthor, setIsCreatingNewAuthor] = (0, react_1.useState)(false);
165
- const [showAffiliationDrawer, setShowAffiliationDrawer] = (0, react_1.useState)(false);
166
- const [selectedAffiliations, setSelectedAffiliations] = (0, react_1.useState)([]);
79
+ const [showCreditDrawer, setShowCreditDrawer] = (0, react_1.useState)(false);
167
80
  const valuesRef = (0, react_1.useRef)();
168
81
  const actionsRef = (0, react_1.useRef)();
169
82
  const authorFormRef = (0, react_1.useRef)(null);
170
83
  const [authors, dispatchAuthors] = (0, react_1.useReducer)(exports.authorsReducer, $authors.sort(authors_1.authorComparator));
171
- const [affiliations] = (0, react_1.useReducer)(exports.affiliationsReducer, $affiliations);
172
- const affiliationItems = affiliations.map((affiliation) => ({
173
- id: affiliation.id,
174
- label: affiliation.institution,
175
- country: affiliation.country,
176
- city: affiliation.city,
177
- state: affiliation.county,
178
- }));
179
- const [selectedAffiliationIds, setSelectedAffiliationIds] = (0, react_1.useState)([]);
180
84
  (0, react_1.useEffect)(() => {
181
85
  if (addNewAuthor) {
182
- handleAddAuthor();
86
+ addAuthor();
183
87
  }
184
88
  }, [addNewAuthor]);
185
89
  const [selection, setSelection] = (0, react_1.useState)(author);
90
+ const { showAffiliationDrawer, setShowAffiliationDrawer, selectedAffiliations, setSelectedAffiliations, removeAffiliation, selectAffiliation, affiliations, } = (0, useManageAffiliations_1.useManageAffiliations)(selection, $affiliations);
186
91
  (0, react_1.useEffect)(() => {
187
92
  const currentAuthor = selection;
188
- const relevantAffiliations = affiliationItems.filter((item) => currentAuthor?.affiliations?.includes(item.id));
93
+ const relevantAffiliations = affiliations.filter((item) => currentAuthor?.affiliations?.includes(item.id));
189
94
  setSelectedAffiliations(relevantAffiliations);
190
- setSelectedAffiliationIds(relevantAffiliations.map((item) => item.id));
191
95
  }, []);
192
- const handleSelect = (author) => {
96
+ const selectAuthor = (author) => {
193
97
  if (author.id === selection?.id) {
194
98
  return;
195
99
  }
196
100
  const values = valuesRef.current;
197
101
  setIsCreatingNewAuthor(false);
198
102
  if (values && selection) {
199
- const normalizedSelection = normalize(selection);
200
- const normalizedValues = normalize(values);
103
+ const normalizedSelection = (0, normalize_1.normalizeAuthor)(selection);
104
+ const normalizedValues = (0, normalize_1.normalizeAuthor)(values);
201
105
  const hasChanges = !(0, lodash_1.isEqual)(normalizedSelection, normalizedValues);
202
106
  if (hasChanges && !isDisableSave) {
203
107
  setShowConfirmationDialog(true);
@@ -222,11 +126,10 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
222
126
  }
223
127
  };
224
128
  const updateAffiliationSelection = (author) => {
225
- const relevantAffiliations = affiliationItems.filter((item) => author.affiliations?.includes(item.id));
129
+ const relevantAffiliations = affiliations.filter((item) => author.affiliations?.includes(item.id));
226
130
  setSelectedAffiliations(relevantAffiliations);
227
- setSelectedAffiliationIds(relevantAffiliations.map((item) => item.id));
228
131
  };
229
- const handleClose = () => {
132
+ const close = () => {
230
133
  if (unSavedChanges) {
231
134
  if (isDisableSave) {
232
135
  setShowRequiredFieldConfirmationDialog(true);
@@ -241,7 +144,7 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
241
144
  setOpen(false);
242
145
  }
243
146
  };
244
- const handleSave = () => {
147
+ const save = () => {
245
148
  if (!authorFormRef.current?.checkValidity()) {
246
149
  setShowConfirmationDialog(false);
247
150
  setTimeout(() => {
@@ -250,7 +153,7 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
250
153
  }
251
154
  else {
252
155
  if (valuesRef.current && selection) {
253
- handleSaveAuthor(valuesRef.current);
156
+ saveAuthor(valuesRef.current);
254
157
  }
255
158
  if (nextAuthor) {
256
159
  setSelection(nextAuthor);
@@ -267,12 +170,11 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
267
170
  setShowConfirmationDialog(false);
268
171
  }
269
172
  };
270
- const handleCancel = () => {
271
- handleResetAuthor();
173
+ const cancel = () => {
174
+ resetAuthor();
272
175
  if (nextAuthor) {
273
- const affiliations = nextAuthor.affiliations || [];
274
- setSelectedAffiliationIds(affiliations);
275
- setSelectedAffiliations(affiliationItems.filter((item) => affiliations.includes(item.id)));
176
+ const nextAuthorAffiliations = nextAuthor.affiliations || [];
177
+ setSelectedAffiliations(affiliations.filter((item) => nextAuthorAffiliations.includes(item.id)));
276
178
  setSelection(nextAuthor);
277
179
  setNextAuthor(null);
278
180
  setNewAuthor(false);
@@ -292,7 +194,7 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
292
194
  setShowRequiredFieldConfirmationDialog(false);
293
195
  setShowAffiliationDrawer(false);
294
196
  };
295
- const handleSaveAuthor = (values) => {
197
+ const saveAuthor = (values) => {
296
198
  if (!values || !selection) {
297
199
  return;
298
200
  }
@@ -316,7 +218,7 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
316
218
  items: [author],
317
219
  });
318
220
  };
319
- const handleMoveAuthor = (from, to, shift) => {
221
+ const moveAuthor = (0, react_1.useCallback)((from, to, shift) => {
320
222
  const copy = (0, lodash_1.cloneDeep)(authors);
321
223
  const order = copy.map((a, i) => {
322
224
  if (a.id === from.id) {
@@ -340,38 +242,23 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
340
242
  type: 'set',
341
243
  state: copy,
342
244
  });
343
- };
245
+ }, [authors, dispatchAuthors, onSaveAuthor]);
344
246
  const createNewAuthor = () => {
345
247
  const name = (0, json_schema_1.buildBibliographicName)({ given: '', family: '' });
346
- const author = {
347
- id: (0, json_schema_1.generateID)(json_schema_1.ObjectTypes.Contributor),
348
- role: '',
349
- affiliations: [],
350
- bibliographicName: name,
351
- email: '',
352
- isCorresponding: false,
353
- ORCIDIdentifier: '',
354
- priority: authors.length,
355
- isJointContributor: false,
356
- userID: '',
357
- invitationID: '',
358
- corresp: [],
359
- footnote: [],
360
- prefix: '',
361
- };
248
+ const author = createEmptyAuthor(name, authors.length);
362
249
  setIsSwitchingAuthor(!!selection);
363
250
  setSelectedAffiliations([]);
364
- setSelectedAffiliationIds([]);
251
+ setSelectedCreditRoles([]);
365
252
  setSelection(author);
366
253
  setNewAuthor(true);
367
254
  };
368
- const handleAddAuthor = () => {
255
+ const addAuthor = () => {
369
256
  const values = valuesRef.current;
370
257
  setIsSwitchingAuthor(!!selection);
371
258
  setIsCreatingNewAuthor(true);
372
259
  if (values &&
373
260
  selection &&
374
- !(0, lodash_1.isEqual)(normalize(values), normalize(selection))) {
261
+ !(0, lodash_1.isEqual)((0, normalize_1.normalizeAuthor)(values), (0, normalize_1.normalizeAuthor)(selection))) {
375
262
  if (isDisableSave) {
376
263
  setShowRequiredFieldConfirmationDialog(true);
377
264
  }
@@ -385,7 +272,7 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
385
272
  setShowAffiliationDrawer(false);
386
273
  }
387
274
  };
388
- const handleDeleteAuthor = () => {
275
+ const deleteAuthor = () => {
389
276
  if (!selection) {
390
277
  return;
391
278
  }
@@ -397,19 +284,10 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
397
284
  item: selection,
398
285
  });
399
286
  };
400
- const handleRemoveAffiliation = (affId) => {
401
- if (!selection) {
402
- return;
403
- }
404
- const newAffiliations = selectedAffiliationIds.filter((id) => id !== affId);
405
- setSelectedAffiliationIds(newAffiliations);
406
- setSelectedAffiliations(affiliationItems.filter((item) => newAffiliations.includes(item.id)));
407
- };
408
- const handleResetAuthor = () => {
287
+ const resetAuthor = () => {
409
288
  actionsRef.current?.reset();
410
- const affiliations = selection?.affiliations || [];
411
- setSelectedAffiliationIds(affiliations);
412
- setSelectedAffiliations(affiliationItems.filter((item) => affiliations.includes(item.id)));
289
+ const selectedAffs = selection?.affiliations || [];
290
+ setSelectedAffiliations(affiliations.filter((item) => selectedAffs.includes(item.id)));
413
291
  setShowConfirmationDialog(false);
414
292
  setShowRequiredFieldConfirmationDialog(false);
415
293
  setUnSavedChanges(false);
@@ -422,17 +300,12 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
422
300
  }
423
301
  setIsCreatingNewAuthor(false);
424
302
  };
425
- const handleChangeAuthor = (values) => {
426
- const normalized = (0, lodash_1.omit)(normalize(selection), 'priority');
427
- const updatedValues = (0, lodash_1.omit)(normalize(values), 'priority');
303
+ const changeAuthor = (values) => {
304
+ const normalized = (0, lodash_1.omit)((0, normalize_1.normalizeAuthor)(selection), 'priority');
305
+ const updatedValues = (0, lodash_1.omit)((0, normalize_1.normalizeAuthor)(values), 'priority');
428
306
  const isSameAuthor = updatedValues.id === normalized.id;
429
307
  const hasChanges = !(0, lodash_1.isEqual)(updatedValues, normalized);
430
- if (isSameAuthor && hasChanges) {
431
- setUnSavedChanges(true);
432
- }
433
- else {
434
- setUnSavedChanges(false);
435
- }
308
+ setUnSavedChanges(isSameAuthor && hasChanges);
436
309
  valuesRef.current = { ...updatedValues, priority: values.priority };
437
310
  const { given, family } = values.bibliographicName;
438
311
  const { email, isCorresponding } = values;
@@ -450,51 +323,95 @@ const AuthorsModal = ({ authors: $authors, affiliations: $affiliations, author,
450
323
  }
451
324
  setEmailRequired(isCorresponding);
452
325
  };
453
- const handleShowDeleteDialog = () => {
454
- setShowDeleteDialog((prev) => !prev);
455
- };
456
- const handleAffiliationSelect = (affiliationId) => {
457
- if (!selection) {
458
- return;
459
- }
460
- const currentAffiliations = selectedAffiliationIds || [];
461
- const isAlreadySelected = currentAffiliations.includes(affiliationId);
462
- const newAffiliations = isAlreadySelected
463
- ? currentAffiliations.filter((id) => id !== affiliationId)
464
- : [...currentAffiliations, affiliationId];
465
- setSelectedAffiliationIds(newAffiliations);
466
- setSelectedAffiliations(affiliationItems.filter((item) => newAffiliations.includes(item.id)));
467
- };
468
- return (react_1.default.createElement(style_guide_1.StyledModal, { isOpen: isOpen, onRequestClose: () => handleClose(), shouldCloseOnOverlayClick: true },
326
+ const { removeCreditRole, selectCreditRole, selectedCreditRoles, setSelectedCreditRoles, vocabTermItems, } = (0, useManageCredit_1.useManageCredit)(selection);
327
+ return (react_1.default.createElement(style_guide_1.StyledModal, { isOpen: isOpen, onRequestClose: () => close(), shouldCloseOnOverlayClick: true },
469
328
  react_1.default.createElement(style_guide_1.ModalContainer, { "data-cy": "authors-modal" },
470
329
  react_1.default.createElement(style_guide_1.ModalHeader, null,
471
- react_1.default.createElement(style_guide_1.CloseButton, { onClick: () => handleClose(), "data-cy": "modal-close-button" })),
330
+ react_1.default.createElement(style_guide_1.CloseButton, { onClick: () => close(), "data-cy": "modal-close-button" })),
472
331
  react_1.default.createElement(StyledModalBody, null,
473
332
  react_1.default.createElement(style_guide_1.ModalSidebar, { "data-cy": "authors-sidebar" },
474
333
  react_1.default.createElement(StyledModalSidebarHeader, null,
475
334
  react_1.default.createElement(style_guide_1.ModalSidebarTitle, null, "Authors")),
476
335
  react_1.default.createElement(StyledSidebarContent, null,
477
- react_1.default.createElement(AddAuthorButton, { "data-cy": "add-author-button", onClick: handleAddAuthor, "data-active": isCreatingNewAuthor || newAuthor },
336
+ react_1.default.createElement(AddAuthorButton, { "data-cy": "add-author-button", onClick: addAuthor, "data-active": isCreatingNewAuthor || newAuthor },
478
337
  react_1.default.createElement(style_guide_1.AddIcon, { width: 18, height: 18 }),
479
338
  react_1.default.createElement(ActionTitle, null, "New Author")),
480
- react_1.default.createElement(AuthorList_1.AuthorList, { author: selection, authors: authors, onSelect: handleSelect, onDelete: handleShowDeleteDialog, moveAuthor: handleMoveAuthor, lastSavedAuthor: lastSavedAuthor }))),
481
- react_1.default.createElement(style_guide_1.ScrollableModalContent, { "data-cy": "author-modal-content" }, selection ? (react_1.default.createElement(AuthorForms, null,
482
- react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showRequiredFieldConfirmationDialog, onPrimary: () => setShowRequiredFieldConfirmationDialog(false), onSecondary: handleCancel, type: ConfirmationDialog_1.DialogType.REQUIRED, entityType: "author" }),
483
- react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showConfirmationDialog, onPrimary: handleSave, onSecondary: handleCancel, type: ConfirmationDialog_1.DialogType.SAVE, entityType: "author" }),
484
- react_1.default.createElement(ModalFormActions_1.ModalFormActions, { form: 'author-details-form', type: "author", onDelete: handleDeleteAuthor, showDeleteDialog: showDeleteDialog, handleShowDeleteDialog: handleShowDeleteDialog, newEntity: newAuthor ||
485
- (isCreatingNewAuthor &&
486
- !showConfirmationDialog &&
487
- !showRequiredFieldConfirmationDialog), isDisableSave: isDisableSave }),
488
- react_1.default.createElement(FormLabel, null, "Details"),
489
- react_1.default.createElement(AuthorDetailsForm_1.AuthorDetailsForm, { values: normalize(selection), onChange: handleChangeAuthor, onSave: handleSaveAuthor, actionsRef: actionsRef, isEmailRequired: isEmailRequired, selectedAffiliations: selectedAffiliationIds, authorFormRef: authorFormRef }),
490
- react_1.default.createElement(AuthorsSection, null,
491
- react_1.default.createElement(AuthorsHeader, null,
492
- react_1.default.createElement(AuthorsTitle, null, "Authors"),
493
- react_1.default.createElement(AffiliateButton, { onClick: () => setShowAffiliationDrawer(true), "data-cy": "affiliate-authors-button" },
494
- react_1.default.createElement(style_guide_1.AddInstitutionIcon, { width: 16, height: 16 }),
495
- "Assign Institutions")),
496
- react_1.default.createElement(style_guide_1.SelectedItemsBox, { "data-cy": "author-affiliations", items: selectedAffiliations, onRemove: handleRemoveAffiliation, placeholder: "No institutions assigned" })),
497
- showAffiliationDrawer && (react_1.default.createElement(style_guide_1.Drawer, { items: affiliationItems, selectedIds: selectedAffiliationIds, title: "Authors", onSelect: handleAffiliationSelect, onBack: () => setShowAffiliationDrawer(false), width: "100%" })))) : (react_1.default.createElement(FormPlaceholder_1.FormPlaceholder, { type: "author", title: "Author Details", message: "Select an author from the list to display their details here.", placeholderIcon: react_1.default.createElement(style_guide_1.AuthorPlaceholderIcon, null) })))),
498
- react_1.default.createElement(FormFooter_1.default, { onCancel: handleClose }))));
339
+ react_1.default.createElement(AuthorList_1.AuthorList, { author: selection, authors: authors, onSelect: selectAuthor, onDelete: () => setShowDeleteDialog((prev) => !prev), moveAuthor: moveAuthor, lastSavedAuthor: lastSavedAuthor }))),
340
+ react_1.default.createElement(DrawerRelativeParent, null,
341
+ react_1.default.createElement(style_guide_1.ScrollableModalContent, { "data-cy": "author-modal-content" }, selection ? (react_1.default.createElement(AuthorForms, null,
342
+ react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showRequiredFieldConfirmationDialog, onPrimary: () => setShowRequiredFieldConfirmationDialog(false), onSecondary: cancel, type: ConfirmationDialog_1.DialogType.REQUIRED, entityType: "author" }),
343
+ react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showConfirmationDialog, onPrimary: save, onSecondary: cancel, type: ConfirmationDialog_1.DialogType.SAVE, entityType: "author" }),
344
+ react_1.default.createElement(ModalFormActions_1.ModalFormActions, { form: 'author-details-form', type: "author", onDelete: deleteAuthor, showingDeleteDialog: showingDeleteDialog, showDeleteDialog: () => setShowDeleteDialog((prev) => !prev), newEntity: newAuthor ||
345
+ (isCreatingNewAuthor &&
346
+ !showConfirmationDialog &&
347
+ !showRequiredFieldConfirmationDialog), isDisableSave: isDisableSave }),
348
+ react_1.default.createElement(FormLabel, null, "Details"),
349
+ 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 }),
350
+ 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 }) }),
351
+ react_1.default.createElement(GenericDrawerGroup_1.DrawerGroup, { Drawer: CreditDrawer_1.CreditDrawer, removeItem: removeCreditRole, selectedItems: selectedCreditRoles.map((r) => ({
352
+ id: r.vocabTerm,
353
+ ...r,
354
+ })), onSelect: selectCreditRole, items: vocabTermItems, showDrawer: showCreditDrawer, setShowDrawer: setShowCreditDrawer, title: "Contributions (Credit)", buttonText: "Assign Credit Roles", cy: "credit-taxnonomy", labelField: "vocabTerm", Icon: react_1.default.createElement(style_guide_1.AddRoleIcon, { width: 16, height: 16 }) }))) : (react_1.default.createElement(FormPlaceholder_1.FormPlaceholder, { type: "author", title: "Author Details", message: "Select an author from the list to display their details here.", placeholderIcon: react_1.default.createElement(style_guide_1.AuthorPlaceholderIcon, null) }))))),
355
+ react_1.default.createElement(FormFooter_1.default, { onCancel: close }))));
499
356
  };
500
357
  exports.AuthorsModal = AuthorsModal;
358
+ function createEmptyAuthor(name, priority) {
359
+ return {
360
+ id: (0, transform_1.generateNodeID)(transform_1.schema.nodes.contributor),
361
+ role: '',
362
+ affiliations: [],
363
+ bibliographicName: name,
364
+ email: '',
365
+ isCorresponding: false,
366
+ ORCIDIdentifier: '',
367
+ priority,
368
+ isJointContributor: false,
369
+ userID: '',
370
+ invitationID: '',
371
+ corresp: [],
372
+ footnote: [],
373
+ prefix: '',
374
+ };
375
+ }
376
+ const AddAuthorButton = styled_components_1.default.div `
377
+ display: flex;
378
+ align-items: center;
379
+ padding: 12px 8px 12px 12px;
380
+ cursor: pointer;
381
+ &[data-active='true'] {
382
+ background: ${(props) => props.theme.colors.background.fifth};
383
+ border: 1px solid ${(props) => props.theme.colors.border.primary};
384
+ border-left: 0;
385
+ border-right: 0;
386
+ }
387
+ `;
388
+ const ActionTitle = styled_components_1.default.div `
389
+ padding-left: ${(props) => props.theme.grid.unit * 2}px;
390
+ `;
391
+ const FormLabel = styled_components_1.default.legend `
392
+ margin-bottom: 12px;
393
+ font: ${(props) => props.theme.font.weight.normal}
394
+ ${(props) => props.theme.font.size.xlarge} /
395
+ ${(props) => props.theme.font.lineHeight.large}
396
+ ${(props) => props.theme.font.family.sans};
397
+ letter-spacing: -0.4px;
398
+ color: ${(props) => props.theme.colors.text.secondary};
399
+ `;
400
+ const AuthorForms = styled_components_1.default.div `
401
+ padding-left: ${(props) => props.theme.grid.unit * 3}px;
402
+ padding-right: ${(props) => props.theme.grid.unit * 3}px;
403
+ margin-top: 20px;
404
+ `;
405
+ const StyledSidebarContent = (0, styled_components_1.default)(style_guide_1.SidebarContent) `
406
+ padding: 0;
407
+ `;
408
+ const StyledModalBody = (0, styled_components_1.default)(style_guide_1.ModalBody) `
409
+ position: relative;
410
+ height: calc(90vh - 40px);
411
+ `;
412
+ const StyledModalSidebarHeader = (0, styled_components_1.default)(style_guide_1.ModalSidebarHeader) `
413
+ margin-bottom: 16px;
414
+ `;
415
+ const DrawerRelativeParent = styled_components_1.default.div `
416
+ position: relative;
417
+ `;
@@ -0,0 +1,37 @@
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.CreditDrawer = void 0;
7
+ const style_guide_1 = require("@manuscripts/style-guide");
8
+ const react_1 = __importDefault(require("react"));
9
+ const styled_components_1 = __importDefault(require("styled-components"));
10
+ const AuthorDetailsForm_1 = require("./AuthorDetailsForm");
11
+ const CreditDrawer = ({ items, selectedItems = [], onSelect, ...drawerProps }) => {
12
+ return (react_1.default.createElement(style_guide_1.Drawer, { ...drawerProps },
13
+ react_1.default.createElement(TwoColumnContainer, null, items.map((item, i) => (react_1.default.createElement(TwoColumnCheckbox, { key: item.id },
14
+ react_1.default.createElement(style_guide_1.CheckboxLabel, null,
15
+ react_1.default.createElement(style_guide_1.CheckboxField, { id: 'credit-role-' + i, name: item.id, checked: selectedItems?.map((a) => a.id).includes(item.id), onChange: () => {
16
+ onSelect(item.id);
17
+ } }),
18
+ react_1.default.createElement(AuthorDetailsForm_1.LabelText, null, item.vocabTerm))))))));
19
+ };
20
+ exports.CreditDrawer = CreditDrawer;
21
+ const TwoColumnContainer = (0, styled_components_1.default)(style_guide_1.DrawerItemsList) `
22
+ display: flex;
23
+ flex-flow: row wrap;
24
+ padding: 0 ${(props) => props.theme.grid.unit * 4}px;
25
+ position: relative;
26
+
27
+ &:after {
28
+ content: '';
29
+ display: block;
30
+ border-bottom: 1px solid #f0f0f0;
31
+ min-width: 100%;
32
+ padding-top: 16px;
33
+ }
34
+ `;
35
+ const TwoColumnCheckbox = (0, styled_components_1.default)(AuthorDetailsForm_1.CheckboxContainer) `
36
+ flex 1 0 50%;
37
+ `;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useManageAffiliations = exports.affiliationsReducer = void 0;
4
+ const react_1 = require("react");
5
+ const array_reducer_1 = require("../../lib/array-reducer");
6
+ exports.affiliationsReducer = (0, array_reducer_1.arrayReducer)((a, b) => a.id === b.id);
7
+ const useManageAffiliations = (selection, $affiliations) => {
8
+ const [affiliations] = (0, react_1.useReducer)(exports.affiliationsReducer, $affiliations);
9
+ const [showAffiliationDrawer, setShowAffiliationDrawer] = (0, react_1.useState)(false);
10
+ const [selectedAffiliations, setSelectedAffiliations] = (0, react_1.useState)([]);
11
+ const removeAffiliation = (affId) => {
12
+ if (!selection) {
13
+ return;
14
+ }
15
+ const newAffiliations = selectedAffiliations
16
+ .map((a) => a.id)
17
+ .filter((id) => id !== affId);
18
+ setSelectedAffiliations(affiliations.filter((item) => newAffiliations.includes(item.id)));
19
+ };
20
+ const selectAffiliation = (affiliationId) => {
21
+ if (!selection) {
22
+ return;
23
+ }
24
+ const currentAffiliations = selectedAffiliations.map((a) => a.id);
25
+ const isAlreadySelected = currentAffiliations.includes(affiliationId);
26
+ const newAffiliations = isAlreadySelected
27
+ ? currentAffiliations.filter((id) => id !== affiliationId)
28
+ : [...currentAffiliations, affiliationId];
29
+ setSelectedAffiliations(affiliations.filter((item) => newAffiliations.includes(item.id)));
30
+ };
31
+ return {
32
+ showAffiliationDrawer,
33
+ setShowAffiliationDrawer,
34
+ selectedAffiliations,
35
+ setSelectedAffiliations,
36
+ removeAffiliation,
37
+ selectAffiliation,
38
+ affiliations,
39
+ };
40
+ };
41
+ exports.useManageAffiliations = useManageAffiliations;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useManageCredit = void 0;
4
+ const transform_1 = require("@manuscripts/transform");
5
+ const react_1 = require("react");
6
+ const useManageCredit = (selection) => {
7
+ const vocabTermItems = (0, react_1.useMemo)(() => {
8
+ return Object.values(transform_1.CreditVocabTerm).map((c) => ({
9
+ vocabTerm: c,
10
+ id: c,
11
+ }));
12
+ }, []);
13
+ (0, react_1.useEffect)(() => {
14
+ setSelectedCreditRoles(selection?.creditRoles ? selection?.creditRoles : []);
15
+ }, [selection]);
16
+ const [selectedCreditRoles, setSelectedCreditRoles] = (0, react_1.useState)([]);
17
+ const selectCreditRole = (role) => {
18
+ setSelectedCreditRoles((prev) => {
19
+ const clear = prev.filter((t) => t.vocabTerm !== role);
20
+ if (clear.length !== prev.length) {
21
+ return clear;
22
+ }
23
+ const newTerm = vocabTermItems.find((t) => t.vocabTerm === role);
24
+ if (newTerm) {
25
+ return [...prev, { vocabTerm: newTerm.vocabTerm }];
26
+ }
27
+ return prev;
28
+ });
29
+ };
30
+ const removeCreditRole = (role) => {
31
+ setSelectedCreditRoles((prev) => {
32
+ return prev.filter((r) => r.vocabTerm !== role);
33
+ });
34
+ };
35
+ return {
36
+ removeCreditRole,
37
+ selectCreditRole,
38
+ selectedCreditRoles,
39
+ setSelectedCreditRoles,
40
+ vocabTermItems,
41
+ };
42
+ };
43
+ exports.useManageCredit = useManageCredit;
@@ -13,6 +13,8 @@ const Footer = styled_components_1.default.div `
13
13
  height: 40px;
14
14
  box-shadow: 0px -2px 12px 0px rgba(216, 216, 216, 0.26);
15
15
  border-radius: 0px 0px 8px 8px;
16
+ position: relative;
17
+ z-index: 3;
16
18
  `;
17
19
  const RemoveButton = styled_components_1.default.button `
18
20
  background-color: #0d79d0;
@@ -32,12 +32,12 @@ const StyledIconButton = (0, styled_components_1.default)(style_guide_1.IconButt
32
32
  margin-right: 4px;
33
33
  }
34
34
  `;
35
- const ModalFormActions = ({ type, form, onDelete, showDeleteDialog, handleShowDeleteDialog, newEntity, isDisableSave, }) => {
35
+ const ModalFormActions = ({ type, form, onDelete, showingDeleteDialog, showDeleteDialog, newEntity, isDisableSave, }) => {
36
36
  return (react_1.default.createElement(ActionsContainer, { "data-cy": `${type}-action` },
37
- react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showDeleteDialog, onPrimary: () => {
37
+ react_1.default.createElement(ConfirmationDialog_1.ConfirmationDialog, { isOpen: showingDeleteDialog, onPrimary: () => {
38
38
  onDelete();
39
- handleShowDeleteDialog();
40
- }, onSecondary: handleShowDeleteDialog, type: ConfirmationDialog_1.DialogType.DELETE, entityType: type }),
39
+ showDeleteDialog();
40
+ }, onSecondary: showDeleteDialog, type: ConfirmationDialog_1.DialogType.DELETE, entityType: type }),
41
41
  react_1.default.createElement(StyledButtonGroup, null,
42
42
  react_1.default.createElement(StyledIconButton, { disabled: isDisableSave, type: "submit", form: form },
43
43
  react_1.default.createElement(style_guide_1.PlusIcon, null),
@@ -0,0 +1,16 @@
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.GenericDrawer = void 0;
7
+ const style_guide_1 = require("@manuscripts/style-guide");
8
+ const react_1 = __importDefault(require("react"));
9
+ const GenericDrawer = ({ items, selectedItems = [], onSelect, ...drawerProps }) => {
10
+ return (react_1.default.createElement(style_guide_1.Drawer, { ...drawerProps },
11
+ react_1.default.createElement(style_guide_1.DrawerItemsList, null, items.map((item) => (react_1.default.createElement(style_guide_1.DrawerListItem, { "data-cy": "item", key: item.id, selected: selectedItems?.map((a) => a.id).includes(item.id), onClick: () => onSelect(item.id) },
12
+ react_1.default.createElement(style_guide_1.DrawerIcon, null, selectedItems?.map((a) => a.id).includes(item.id) ? (react_1.default.createElement(style_guide_1.AddedIcon, { width: 22, height: 22 })) : (react_1.default.createElement(style_guide_1.AddIcon, { width: 22, height: 22 }))),
13
+ react_1.default.createElement(style_guide_1.DrawerLabelContainer, null,
14
+ react_1.default.createElement(style_guide_1.DrawerItemLabel, null, item.label))))))));
15
+ };
16
+ exports.GenericDrawer = GenericDrawer;