@manuscripts/body-editor 2.8.83 → 2.8.85

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 (37) hide show
  1. package/dist/cjs/commands.js +22 -2
  2. package/dist/cjs/components/affiliations/AffiliationsModal.js +106 -61
  3. package/dist/cjs/components/outline/DraggableTree.js +7 -4
  4. package/dist/cjs/components/outline/Outline.js +6 -0
  5. package/dist/cjs/configs/editor-views.js +2 -1
  6. package/dist/cjs/icons.js +2 -1
  7. package/dist/cjs/lib/files.js +5 -1
  8. package/dist/cjs/menus.js +6 -0
  9. package/dist/cjs/node-type-icons.js +1 -0
  10. package/dist/cjs/plugins/comments.js +1 -0
  11. package/dist/cjs/versions.js +1 -1
  12. package/dist/cjs/views/affiliations.js +39 -16
  13. package/dist/cjs/views/hero_image.js +64 -0
  14. package/dist/cjs/views/hero_image_editable.js +21 -0
  15. package/dist/es/commands.js +20 -1
  16. package/dist/es/components/affiliations/AffiliationsModal.js +107 -62
  17. package/dist/es/components/outline/DraggableTree.js +8 -5
  18. package/dist/es/components/outline/Outline.js +6 -0
  19. package/dist/es/configs/editor-views.js +2 -1
  20. package/dist/es/icons.js +2 -1
  21. package/dist/es/lib/files.js +5 -1
  22. package/dist/es/menus.js +7 -1
  23. package/dist/es/node-type-icons.js +1 -0
  24. package/dist/es/plugins/comments.js +1 -0
  25. package/dist/es/versions.js +1 -1
  26. package/dist/es/views/affiliations.js +39 -16
  27. package/dist/es/views/hero_image.js +57 -0
  28. package/dist/es/views/hero_image_editable.js +19 -0
  29. package/dist/types/commands.d.ts +1 -0
  30. package/dist/types/components/affiliations/AffiliationsModal.d.ts +1 -0
  31. package/dist/types/icons.d.ts +1 -0
  32. package/dist/types/versions.d.ts +1 -1
  33. package/dist/types/views/affiliations.d.ts +3 -2
  34. package/dist/types/views/hero_image.d.ts +27 -0
  35. package/dist/types/views/hero_image_editable.d.ts +44 -0
  36. package/package.json +2 -2
  37. package/styles/AdvancedEditor.css +54 -16
@@ -16,7 +16,7 @@
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.addRows = exports.addInlineComment = exports.addNodeComment = exports.isCommentingAllowed = exports.createAndFillTableElement = exports.selectAllIsolating = exports.ignoreAtomBlockNodeForward = exports.isAtEndOfTextBlock = exports.ignoreMetaNodeBackspaceCommand = exports.ignoreAtomBlockNodeBackward = exports.isTextSelection = exports.isAtStartOfTextBlock = exports.insertTOCSection = exports.insertBibliographySection = exports.insertList = exports.insertKeywords = exports.insertAward = exports.insertAffiliation = exports.insertContributors = exports.insertGraphicalAbstract = exports.insertBackmatterSection = exports.insertAbstractSection = exports.insertSection = exports.insertBoxElement = exports.insertInlineFootnote = exports.insertFootnotesElement = exports.insertTableElementFooter = exports.insertInlineEquation = exports.insertCrossReference = exports.insertInlineCitation = exports.insertLink = exports.insertSectionLabel = exports.findPosBeforeFirstSubsection = exports.insertBreak = exports.deleteBlock = exports.insertBlock = exports.insertAttachment = exports.insertSupplement = exports.insertTable = exports.insertFigure = exports.insertGeneralTableFootnote = exports.insertInlineTableFootnote = exports.insertEmbed = exports.createBlock = exports.createSelection = exports.canInsert = exports.blockActive = exports.isNodeSelection = exports.markActive = exports.addToStart = void 0;
19
- exports.activateSearchReplace = exports.activateSearch = exports.autoComplete = exports.addColumns = exports.addHeaderRow = void 0;
19
+ exports.insertHeroImage = exports.activateSearchReplace = exports.activateSearch = exports.autoComplete = exports.addColumns = exports.addHeaderRow = void 0;
20
20
  const json_schema_1 = require("@manuscripts/json-schema");
21
21
  const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
22
22
  const transform_1 = require("@manuscripts/transform");
@@ -160,6 +160,9 @@ const createBlock = (nodeType, position, state, dispatch, attrs) => {
160
160
  case transform_1.schema.nodes.image_element:
161
161
  node = createImageElement(attrs);
162
162
  break;
163
+ case transform_1.schema.nodes.hero_image:
164
+ node = createHeroImage(attrs);
165
+ break;
163
166
  case transform_1.schema.nodes.listing_element:
164
167
  node = transform_1.schema.nodes.listing_element.create({}, [
165
168
  transform_1.schema.nodes.listing.create(),
@@ -1077,7 +1080,8 @@ const isCommentingAllowed = (type) => type === transform_1.schema.nodes.title ||
1077
1080
  type === transform_1.schema.nodes.embed ||
1078
1081
  type === transform_1.schema.nodes.affiliations ||
1079
1082
  type === transform_1.schema.nodes.contributors ||
1080
- type === transform_1.schema.nodes.image_element;
1083
+ type === transform_1.schema.nodes.image_element ||
1084
+ type === transform_1.schema.nodes.hero_image;
1081
1085
  exports.isCommentingAllowed = isCommentingAllowed;
1082
1086
  const addNodeComment = (node, state, dispatch) => {
1083
1087
  if (!(0, exports.isCommentingAllowed)(node.type)) {
@@ -1235,3 +1239,19 @@ const activateSearchReplace = (state, dispatch) => {
1235
1239
  return true;
1236
1240
  };
1237
1241
  exports.activateSearchReplace = activateSearchReplace;
1242
+ const createHeroImage = (attrs) => transform_1.schema.nodes.hero_image.create(Object.assign(Object.assign({}, attrs), { id: (0, transform_1.generateNodeID)(transform_1.schema.nodes.hero_image) }), [
1243
+ transform_1.schema.nodes.figure.create(),
1244
+ transform_1.schema.nodes.alt_text.create(),
1245
+ transform_1.schema.nodes.long_desc.create(),
1246
+ ]);
1247
+ const insertHeroImage = () => (state, dispatch, view) => {
1248
+ if ((0, utils_1.getChildOfType)(state.doc, transform_1.schema.nodes.hero_image, true)) {
1249
+ return false;
1250
+ }
1251
+ const backmatter = (0, doc_1.findBackmatter)(state.doc);
1252
+ const position = backmatter.pos + backmatter.node.content.size + 1;
1253
+ view === null || view === void 0 ? void 0 : view.focus();
1254
+ (0, exports.createBlock)(transform_1.schema.nodes.hero_image, position, state, dispatch);
1255
+ return true;
1256
+ };
1257
+ exports.insertHeroImage = insertHeroImage;
@@ -109,7 +109,7 @@ const StyledModalSidebarHeader = (0, styled_components_1.default)(style_guide_1.
109
109
  margin-bottom: 16px;
110
110
  `;
111
111
  const normalize = (affiliation) => ({
112
- id: affiliation.id,
112
+ id: affiliation.id || (0, json_schema_1.generateID)(json_schema_1.ObjectTypes.Affiliation),
113
113
  institution: affiliation.institution,
114
114
  department: affiliation.department,
115
115
  addressLine1: affiliation.addressLine1,
@@ -122,9 +122,9 @@ const normalize = (affiliation) => ({
122
122
  email: affiliation.email,
123
123
  priority: affiliation.priority,
124
124
  });
125
- const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onSaveAffiliation, onDeleteAffiliation, onUpdateAuthors, addNewAffiliation = false, }) => {
125
+ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, affiliation, onSaveAffiliation, onDeleteAffiliation, onUpdateAuthors, addNewAffiliation = false, }) => {
126
126
  const [isOpen, setIsOpen] = (0, react_1.useState)(true);
127
- const [selection, setSelection] = (0, react_1.useState)(undefined);
127
+ const [selection, setSelection] = (0, react_1.useState)(affiliation);
128
128
  const [showDeleteDialog, setShowDeleteDialog] = (0, react_1.useState)(false);
129
129
  const valuesRef = (0, react_1.useRef)();
130
130
  const actionsRef = (0, react_1.useRef)();
@@ -134,37 +134,37 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
134
134
  const [newAffiliation, setNewAffiliation] = (0, react_1.useState)(false);
135
135
  const [showRequiredFieldConfirmationDialog, setShowRequiredFieldConfirmationDialog,] = (0, react_1.useState)(false);
136
136
  const [showConfirmationDialog, setShowConfirmationDialog] = (0, react_1.useState)(false);
137
- const affiliation = {
138
- id: (0, json_schema_1.generateID)(json_schema_1.ObjectTypes.Affiliation),
139
- institution: '',
140
- department: '',
141
- addressLine1: '',
142
- addressLine2: '',
143
- addressLine3: '',
144
- postCode: '',
145
- country: '',
146
- county: '',
147
- city: '',
148
- email: {
149
- href: '',
150
- text: '',
151
- },
152
- priority: affiliations.length,
153
- };
154
137
  const [showAuthorDrawer, setShowAuthorDrawer] = (0, react_1.useState)(false);
155
- const [selectedIds, setSelectedIds] = (0, react_1.useState)([]);
138
+ const [selectedAuthorIds, setSelectedAuthorIds] = (0, react_1.useState)([]);
156
139
  const [pendingSelection, setPendingSelection] = (0, react_1.useState)(null);
157
140
  const [pendingAction, setPendingAction] = (0, react_1.useState)(null);
158
141
  const [savedAffiliationId, setSavedAffiliationId] = (0, react_1.useState)(undefined);
159
- const [affiliationAuthorMap, setAffiliationAuthorMap] = (0, react_1.useState)({});
142
+ const [affiliationAuthorMap, setAffiliationAuthorMap] = (0, react_1.useState)(new Map());
143
+ (0, react_1.useEffect)(() => {
144
+ if (!selection) {
145
+ return;
146
+ }
147
+ const currentAffiliation = selection;
148
+ const affiliatedAuthorIds = authors
149
+ .filter((author) => { var _a; return (_a = author.affiliations) === null || _a === void 0 ? void 0 : _a.includes(currentAffiliation.id); })
150
+ .map((author) => author.id);
151
+ setSelectedAuthorIds(affiliatedAuthorIds);
152
+ setAffiliationAuthorMap((prevMap) => {
153
+ const newMap = new Map(prevMap);
154
+ newMap.set(currentAffiliation.id, affiliatedAuthorIds);
155
+ return newMap;
156
+ });
157
+ }, []);
160
158
  const handleClose = () => {
161
- var _a;
159
+ var _a, _b;
162
160
  const values = valuesRef.current;
163
161
  const hasAffiliationChanges = selection && !(0, lodash_1.isEqual)(values, normalize(selection));
164
- const originalAuthors = affiliationAuthorMap[(selection === null || selection === void 0 ? void 0 : selection.id) || ''] || [];
165
- const hasAuthorChanges = !(0, lodash_1.isEqual)(originalAuthors.sort(), selectedIds.sort());
162
+ const originalAuthors = selection
163
+ ? (_a = affiliationAuthorMap.get(selection.id)) !== null && _a !== void 0 ? _a : []
164
+ : [];
165
+ const hasAuthorChanges = !(0, lodash_1.isEqual)(originalAuthors.sort(), selectedAuthorIds.sort());
166
166
  const hasChanges = hasAffiliationChanges || (selection && hasAuthorChanges);
167
- const isInstitutionEmpty = ((_a = values === null || values === void 0 ? void 0 : values.institution) === null || _a === void 0 ? void 0 : _a.trim()) === '';
167
+ const isInstitutionEmpty = ((_b = values === null || values === void 0 ? void 0 : values.institution) === null || _b === void 0 ? void 0 : _b.trim()) === '';
168
168
  if (hasChanges) {
169
169
  if (isInstitutionEmpty && hasAffiliationChanges) {
170
170
  setShowRequiredFieldConfirmationDialog(true);
@@ -179,13 +179,15 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
179
179
  }
180
180
  };
181
181
  const handleSelect = (affiliation) => {
182
- var _a;
182
+ var _a, _b;
183
183
  const values = valuesRef.current;
184
184
  const hasAffiliationChanges = selection && !(0, lodash_1.isEqual)(values, normalize(selection));
185
- const originalAuthors = affiliationAuthorMap[(selection === null || selection === void 0 ? void 0 : selection.id) || ''] || [];
186
- const hasAuthorChanges = !(0, lodash_1.isEqual)(originalAuthors.sort(), selectedIds.sort());
185
+ const originalAuthors = selection
186
+ ? (_a = affiliationAuthorMap.get(selection.id)) !== null && _a !== void 0 ? _a : []
187
+ : [];
188
+ const hasAuthorChanges = !(0, lodash_1.isEqual)(originalAuthors.sort(), selectedAuthorIds.sort());
187
189
  const hasChanges = hasAffiliationChanges || hasAuthorChanges;
188
- const isInstitutionEmpty = ((_a = values === null || values === void 0 ? void 0 : values.institution) === null || _a === void 0 ? void 0 : _a.trim()) === '';
190
+ const isInstitutionEmpty = ((_b = values === null || values === void 0 ? void 0 : values.institution) === null || _b === void 0 ? void 0 : _b.trim()) === '';
189
191
  if (hasChanges) {
190
192
  setPendingSelection(affiliation);
191
193
  setPendingAction('select');
@@ -202,12 +204,16 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
202
204
  .map((author) => author.id);
203
205
  setNewAffiliation(false);
204
206
  setSelection(affiliation);
205
- setSelectedIds(affiliatedAuthorIds);
207
+ setSelectedAuthorIds(affiliatedAuthorIds);
206
208
  setShowAuthorDrawer(false);
207
- setAffiliationAuthorMap((prevMap) => (Object.assign(Object.assign({}, prevMap), { [affiliation.id]: affiliatedAuthorIds })));
209
+ setAffiliationAuthorMap((prevMap) => {
210
+ const newMap = new Map(prevMap);
211
+ newMap.set(affiliation.id, affiliatedAuthorIds);
212
+ return newMap;
213
+ });
208
214
  }
209
215
  };
210
- const handleSaveAffiliation = (values) => {
216
+ const handleSaveAffiliation = (0, react_1.useCallback)((values) => {
211
217
  if (!values || !selection) {
212
218
  return;
213
219
  }
@@ -219,7 +225,7 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
219
225
  items: [affiliation],
220
226
  });
221
227
  setSelection(affiliation);
222
- const updatedAuthors = authors.map((author) => (Object.assign(Object.assign({}, author), { affiliations: selectedIds.includes(author.id)
228
+ const updatedAuthors = authors.map((author) => (Object.assign(Object.assign({}, author), { affiliations: selectedAuthorIds.includes(author.id)
223
229
  ? [...new Set([...(author.affiliations || []), affiliation.id])]
224
230
  : (author.affiliations || []).filter((id) => id !== affiliation.id) })));
225
231
  dispatchAuthors({
@@ -228,15 +234,27 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
228
234
  });
229
235
  onUpdateAuthors(updatedAuthors);
230
236
  setNewAffiliation(false);
231
- setAffiliationAuthorMap((prevMap) => (Object.assign(Object.assign({}, prevMap), { [affiliation.id]: selectedIds })));
237
+ setAffiliationAuthorMap((prevMap) => {
238
+ const newMap = new Map(prevMap);
239
+ newMap.set(affiliation.id, selectedAuthorIds);
240
+ return newMap;
241
+ });
232
242
  setShowAuthorDrawer(false);
233
243
  setSavedAffiliationId(affiliation.id);
234
244
  setTimeout(() => {
235
245
  setSavedAffiliationId(undefined);
236
246
  }, 3200);
237
- };
247
+ }, [
248
+ authors,
249
+ dispatchAffiliations,
250
+ dispatchAuthors,
251
+ onSaveAffiliation,
252
+ onUpdateAuthors,
253
+ selectedAuthorIds,
254
+ selection,
255
+ ]);
238
256
  const handleAffiliationChange = (values) => {
239
- var _a;
257
+ var _a, _b;
240
258
  valuesRef.current = values;
241
259
  if (!selection || selection.id !== values.id) {
242
260
  setIsDisableSave(true);
@@ -244,8 +262,8 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
244
262
  }
245
263
  const isInstitutionEmpty = !((_a = values.institution) === null || _a === void 0 ? void 0 : _a.trim());
246
264
  const hasAffiliationChanges = selection && !(0, lodash_1.isEqual)(normalize(values), normalize(selection));
247
- const originalAuthors = affiliationAuthorMap[(selection === null || selection === void 0 ? void 0 : selection.id) || ''] || [];
248
- const hasAuthorChanges = selection && !(0, lodash_1.isEqual)(originalAuthors.sort(), selectedIds.sort());
265
+ const originalAuthors = (_b = affiliationAuthorMap.get(selection.id)) !== null && _b !== void 0 ? _b : [];
266
+ const hasAuthorChanges = selection && !(0, lodash_1.isEqual)(originalAuthors.sort(), selectedAuthorIds.sort());
249
267
  const shouldEnableSave = !isInstitutionEmpty && (hasAffiliationChanges || hasAuthorChanges);
250
268
  setIsDisableSave(!shouldEnableSave);
251
269
  };
@@ -267,22 +285,22 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
267
285
  type: 'delete',
268
286
  item: selection,
269
287
  });
270
- setSelectedIds([]);
288
+ setSelectedAuthorIds([]);
271
289
  setSelection(undefined);
272
290
  };
273
291
  const handleAuthorSelect = (authorId) => {
274
- var _a, _b;
292
+ var _a, _b, _c;
275
293
  if (!selection) {
276
294
  return;
277
295
  }
278
- const newSelectedAuthorIds = selectedIds.includes(authorId)
279
- ? selectedIds.filter((id) => id !== authorId)
280
- : [...selectedIds, authorId];
281
- setSelectedIds(newSelectedAuthorIds);
296
+ const newSelectedAuthorIds = selectedAuthorIds.includes(authorId)
297
+ ? selectedAuthorIds.filter((id) => id !== authorId)
298
+ : [...selectedAuthorIds, authorId];
299
+ setSelectedAuthorIds(newSelectedAuthorIds);
282
300
  const hasAffiliationChanges = !(0, lodash_1.isEqual)(valuesRef.current, normalize(selection));
283
- const originalAuthors = affiliationAuthorMap[selection.id] || [];
301
+ const originalAuthors = (_a = affiliationAuthorMap.get(selection.id)) !== null && _a !== void 0 ? _a : [];
284
302
  const hasAuthorChanges = !(0, lodash_1.isEqual)(originalAuthors.sort(), newSelectedAuthorIds.sort());
285
- const isInstitutionEmpty = !((_b = (_a = valuesRef.current) === null || _a === void 0 ? void 0 : _a.institution) === null || _b === void 0 ? void 0 : _b.trim());
303
+ const isInstitutionEmpty = !((_c = (_b = valuesRef.current) === null || _b === void 0 ? void 0 : _b.institution) === null || _c === void 0 ? void 0 : _c.trim());
286
304
  const shouldEnableSave = !isInstitutionEmpty && (hasAffiliationChanges || hasAuthorChanges);
287
305
  setIsDisableSave(!shouldEnableSave);
288
306
  };
@@ -290,7 +308,7 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
290
308
  id: author.id,
291
309
  label: `${author.bibliographicName.given} ${author.bibliographicName.family}`,
292
310
  }));
293
- const selectedAuthors = selectedIds
311
+ const selectedAuthors = selectedAuthorIds
294
312
  .map((authorId) => {
295
313
  const author = authors.find((a) => a.id === authorId);
296
314
  return {
@@ -306,6 +324,23 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
306
324
  const values = valuesRef.current;
307
325
  const hasChanges = !isDisableSave;
308
326
  const isInstitutionEmpty = ((_a = values === null || values === void 0 ? void 0 : values.institution) === null || _a === void 0 ? void 0 : _a.trim()) === '';
327
+ const emptyAffiliation = {
328
+ id: (0, json_schema_1.generateID)(json_schema_1.ObjectTypes.Affiliation),
329
+ institution: '',
330
+ department: '',
331
+ addressLine1: '',
332
+ addressLine2: '',
333
+ addressLine3: '',
334
+ postCode: '',
335
+ country: '',
336
+ county: '',
337
+ city: '',
338
+ email: {
339
+ href: '',
340
+ text: '',
341
+ },
342
+ priority: affiliations.length,
343
+ };
309
344
  if (hasChanges) {
310
345
  setPendingAction('new');
311
346
  if (isInstitutionEmpty) {
@@ -317,8 +352,8 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
317
352
  return;
318
353
  }
319
354
  setNewAffiliation(true);
320
- setSelection(affiliation);
321
- setSelectedIds([]);
355
+ setSelection(emptyAffiliation);
356
+ setSelectedAuthorIds([]);
322
357
  setShowAuthorDrawer(false);
323
358
  };
324
359
  (0, react_1.useEffect)(() => {
@@ -327,14 +362,14 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
327
362
  setNewAffiliation(true);
328
363
  }
329
364
  }, [addNewAffiliation]);
330
- const handleConfirmationSave = () => {
365
+ const handleConfirmationSave = (0, react_1.useCallback)(() => {
331
366
  handleSaveAffiliation(valuesRef.current);
332
367
  setShowConfirmationDialog(false);
333
368
  setShowRequiredFieldConfirmationDialog(false);
334
369
  if (pendingAction === 'new') {
335
370
  setNewAffiliation(true);
336
371
  setSelection(affiliation);
337
- setSelectedIds([]);
372
+ setSelectedAuthorIds([]);
338
373
  setIsDisableSave(true);
339
374
  }
340
375
  else if (pendingAction === 'select' && pendingSelection) {
@@ -343,17 +378,27 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
343
378
  const affiliatedAuthorIds = authors
344
379
  .filter((author) => { var _a; return (_a = author.affiliations) === null || _a === void 0 ? void 0 : _a.some((aff) => aff === pendingSelection.id); })
345
380
  .map((author) => author.id);
346
- setSelectedIds(affiliatedAuthorIds);
381
+ setSelectedAuthorIds(affiliatedAuthorIds);
347
382
  valuesRef.current = normalize(pendingSelection);
348
383
  setIsDisableSave(true);
349
- setAffiliationAuthorMap((prevMap) => (Object.assign(Object.assign({}, prevMap), { [pendingSelection.id]: affiliatedAuthorIds })));
384
+ setAffiliationAuthorMap((prevMap) => {
385
+ const newMap = new Map(prevMap);
386
+ newMap.set(pendingSelection.id, affiliatedAuthorIds);
387
+ return newMap;
388
+ });
350
389
  }
351
- setPendingSelection(null);
352
- setPendingAction(null);
353
390
  if (pendingAction === 'close') {
354
391
  setIsOpen(false);
355
392
  }
356
- };
393
+ setPendingSelection(null);
394
+ setPendingAction(null);
395
+ }, [
396
+ authors,
397
+ affiliation,
398
+ pendingAction,
399
+ pendingSelection,
400
+ handleSaveAffiliation,
401
+ ]);
357
402
  const handleConfirmationCancel = () => {
358
403
  setShowConfirmationDialog(false);
359
404
  setShowRequiredFieldConfirmationDialog(false);
@@ -364,12 +409,12 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
364
409
  const affiliatedAuthorIds = authors
365
410
  .filter((author) => { var _a; return (_a = author.affiliations) === null || _a === void 0 ? void 0 : _a.some((aff) => aff === pendingSelection.id); })
366
411
  .map((author) => author.id);
367
- setSelectedIds(affiliatedAuthorIds);
412
+ setSelectedAuthorIds(affiliatedAuthorIds);
368
413
  }
369
414
  else if (pendingAction === 'new') {
370
415
  setNewAffiliation(true);
371
416
  setSelection(affiliation);
372
- setSelectedIds([]);
417
+ setSelectedAuthorIds([]);
373
418
  }
374
419
  if (pendingSelection) {
375
420
  valuesRef.current = normalize(pendingSelection);
@@ -408,9 +453,9 @@ const AffiliationsModal = ({ authors: $authors, affiliations: $affiliations, onS
408
453
  react_1.default.createElement(style_guide_1.AddUserIcon, { width: 16, height: 16 }),
409
454
  "Affiliate Authors")),
410
455
  react_1.default.createElement(style_guide_1.SelectedItemsBox, { "data-cy": "affiliation-authors", items: selectedAuthors, onRemove: (id) => {
411
- setSelectedIds((prev) => prev.filter((authorId) => authorId !== id));
456
+ setSelectedAuthorIds((prev) => prev.filter((authorId) => authorId !== id));
412
457
  }, placeholder: "No authors assigned" })),
413
- showAuthorDrawer && (react_1.default.createElement(style_guide_1.Drawer, { items: authorItems, selectedIds: selectedIds, title: "Authors", onSelect: handleAuthorSelect, onBack: () => setShowAuthorDrawer(false), width: "100%" })))) : (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) })))),
458
+ showAuthorDrawer && (react_1.default.createElement(style_guide_1.Drawer, { items: authorItems, selectedIds: selectedAuthorIds, title: "Authors", onSelect: handleAuthorSelect, onBack: () => setShowAuthorDrawer(false), width: "100%" })))) : (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) })))),
414
459
  react_1.default.createElement(FormFooter_1.default, { onCancel: handleClose }))));
415
460
  };
416
461
  exports.AffiliationsModal = AffiliationsModal;
@@ -47,7 +47,8 @@ const excludedTypes = [
47
47
  transform_1.schema.nodes.title,
48
48
  transform_1.schema.nodes.alt_titles,
49
49
  transform_1.schema.nodes.alt_title,
50
- transform_1.schema.nodes.hero_image,
50
+ transform_1.schema.nodes.alt_text,
51
+ transform_1.schema.nodes.long_desc,
51
52
  ];
52
53
  const childrenExcludedTypes = [
53
54
  transform_1.schema.nodes.pullquote_element,
@@ -174,7 +175,8 @@ const DraggableTree = ({ tree, view, depth, can, }) => {
174
175
  }),
175
176
  });
176
177
  const isDeletedItem = (0, track_changes_utils_1.isDeleted)(node);
177
- const isTop = isManuscriptNode(parent);
178
+ const isHeroImage = (0, transform_1.isHeroImageNode)(node);
179
+ const isTop = isManuscriptNode(parent) && !isHeroImage;
178
180
  const handleContextMenu = (e) => {
179
181
  e.preventDefault();
180
182
  e.stopPropagation();
@@ -191,8 +193,9 @@ const DraggableTree = ({ tree, view, depth, can, }) => {
191
193
  const dragClass = isDragging ? 'dragging' : '';
192
194
  const dropClass = isOver && dropSide ? `drop-${dropSide}` : '';
193
195
  const deletedClass = isDeletedItem ? 'deleted' : '';
194
- return (react_1.default.createElement(Outline_1.Outline, { ref: ref, className: `${dragClass} ${dropClass} ${deletedClass}` },
195
- !isTop && node.type.name != 'manuscript' && (react_1.default.createElement(Outline_1.OutlineItem, { depth: depth, onContextMenu: handleContextMenu },
196
+ const heroImageClass = isHeroImage ? 'hero-image' : '';
197
+ return (react_1.default.createElement(Outline_1.Outline, { ref: ref, className: `${dragClass} ${dropClass} ${deletedClass} ${heroImageClass}` },
198
+ !isTop && node.type.name != 'manuscript' && (react_1.default.createElement(Outline_1.OutlineItem, { depth: isHeroImage ? 1 : depth, onContextMenu: handleContextMenu },
196
199
  items.length ? (react_1.default.createElement(Outline_1.OutlineItemArrow, { onClick: toggleOpen }, isOpen ? react_1.default.createElement(style_guide_1.TriangleExpandedIcon, null) : react_1.default.createElement(style_guide_1.TriangleCollapsedIcon, null))) : (react_1.default.createElement(Outline_1.OutlineItemNoArrow, null)),
197
200
  react_1.default.createElement(Outline_1.OutlineItemLink, { to: `#${node.attrs.id}` },
198
201
  react_1.default.createElement(Outline_1.OutlineItemIcon, null, (0, node_type_icons_1.nodeTypeIcon)(node.type)),
@@ -119,5 +119,11 @@ exports.Outline = styled_components_1.default.div `
119
119
  & .subtree.collapsed {
120
120
  display: none;
121
121
  }
122
+
123
+ & .hero-image {
124
+ margin-top: 1rem;
125
+ padding-top: 0.5rem;
126
+ border-top: 1px dashed #ddd;
127
+ }
122
128
  `;
123
129
  exports.OutlineItemPlaceholder = styled_components_1.default.span ``;
@@ -25,6 +25,7 @@ const figure_element_editable_1 = __importDefault(require("../views/figure_eleme
25
25
  const footnote_1 = __importDefault(require("../views/footnote"));
26
26
  const footnotes_element_1 = __importDefault(require("../views/footnotes_element"));
27
27
  const general_table_footnote_1 = __importDefault(require("../views/general_table_footnote"));
28
+ const hero_image_editable_1 = __importDefault(require("../views/hero_image_editable"));
28
29
  const inline_equation_editable_1 = __importDefault(require("../views/inline_equation_editable"));
29
30
  const inline_footnote_editable_1 = __importDefault(require("../views/inline_footnote_editable"));
30
31
  const keyword_1 = __importDefault(require("../views/keyword"));
@@ -92,6 +93,6 @@ exports.default = (props, dispatch) => {
92
93
  award: (0, award_1.default)(props, dispatch),
93
94
  long_desc: (0, accessibility_element_1.default)(props, dispatch),
94
95
  alt_text: (0, accessibility_element_1.default)(props, dispatch),
95
- hero_image: (0, empty_1.default)('hero_image'),
96
+ hero_image: (0, hero_image_editable_1.default)(props, dispatch),
96
97
  };
97
98
  };
package/dist/cjs/icons.js CHANGED
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.plusIcon = exports.lockIcon = exports.scrollIcon = exports.sectionCategoryIcon = exports.editIcon = exports.deleteIcon = exports.alertIcon = exports.arrowDown = void 0;
3
+ exports.plusIcon = exports.lockIcon = exports.scrollIcon = exports.sectionCategoryIcon = exports.editIcon = exports.deleteIcon = exports.alertIcon = exports.arrowUp = exports.arrowDown = void 0;
4
4
  const style_guide_1 = require("@manuscripts/style-guide");
5
5
  const react_1 = require("react");
6
6
  const server_1 = require("react-dom/server");
7
7
  const renderIcon = (c) => (0, server_1.renderToStaticMarkup)((0, react_1.createElement)(c));
8
8
  exports.arrowDown = renderIcon(style_guide_1.ArrowDownCircleIcon);
9
+ exports.arrowUp = renderIcon(style_guide_1.ArrowUpIcon);
9
10
  exports.alertIcon = renderIcon(style_guide_1.AlertIcon);
10
11
  exports.deleteIcon = renderIcon(style_guide_1.DeleteIcon);
11
12
  exports.editIcon = (0, server_1.renderToStaticMarkup)((0, react_1.createElement)(style_guide_1.EditIcon));
@@ -8,7 +8,11 @@ const MISSING_FILE = {
8
8
  id: '',
9
9
  name: '',
10
10
  };
11
- const figureTypes = [transform_1.schema.nodes.figure_element, transform_1.schema.nodes.image_element];
11
+ const figureTypes = [
12
+ transform_1.schema.nodes.figure_element,
13
+ transform_1.schema.nodes.image_element,
14
+ transform_1.schema.nodes.hero_image,
15
+ ];
12
16
  const groupFiles = (doc, files) => {
13
17
  const fileMap = new Map(files.map((f) => [f.id, f]));
14
18
  const figures = [];
package/dist/cjs/menus.js CHANGED
@@ -237,6 +237,12 @@ const getEditorMenus = (editor) => {
237
237
  isCommandValid((0, commands_1.canInsert)(transform_1.schema.nodes.image_element)),
238
238
  run: doCommand((0, commands_1.insertBlock)(transform_1.schema.nodes.image_element)),
239
239
  },
240
+ {
241
+ id: 'insert-hero-image',
242
+ label: 'Hero Image',
243
+ isEnabled: (0, utils_1.isEditAllowed)(state) && isCommandValid((0, commands_1.insertHeroImage)()),
244
+ run: doCommand((0, commands_1.insertHeroImage)()),
245
+ },
240
246
  {
241
247
  id: 'insert-table-element',
242
248
  label: 'Table',
@@ -38,6 +38,7 @@ const icons = new Map([
38
38
  [nodes.graphical_abstract_section, style_guide_1.OutlineSectionIcon],
39
39
  [nodes.footnotes_section, style_guide_1.OutlineSectionIcon],
40
40
  [nodes.image_element, OutlineImageIcon],
41
+ [nodes.hero_image, OutlineImageIcon],
41
42
  ]);
42
43
  const nodeTypeIcon = (nodeType, listType) => {
43
44
  if (nodeType === transform_1.schema.nodes.list) {
@@ -187,6 +187,7 @@ const getDecorationPos = (node, pos) => {
187
187
  case transform_1.schema.nodes.paragraph:
188
188
  case transform_1.schema.nodes.embed:
189
189
  case transform_1.schema.nodes.contributors:
190
+ case transform_1.schema.nodes.hero_image:
190
191
  return pos;
191
192
  case transform_1.schema.nodes.keywords:
192
193
  return pos + 2;
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MATHJAX_VERSION = exports.VERSION = void 0;
4
- exports.VERSION = '2.8.83';
4
+ exports.VERSION = '2.8.85';
5
5
  exports.MATHJAX_VERSION = '3.2.2';
@@ -39,17 +39,21 @@ class AffiliationsView extends block_view_1.default {
39
39
  this.stopEvent = () => true;
40
40
  this.handleClick = (event) => {
41
41
  const element = event.target;
42
- const item = element.closest('.affiliation');
43
- if (item) {
44
- const node = (0, view_1.findChildByID)(this.view, item.id);
45
- if (!node) {
46
- return;
47
- }
48
- const view = this.view;
49
- const tr = view.state.tr;
50
- tr.setSelection(prosemirror_state_1.NodeSelection.create(view.state.doc, node.pos));
51
- view.dispatch(tr);
42
+ const affiliation = element.closest('.affiliation');
43
+ if (!affiliation) {
44
+ return;
52
45
  }
46
+ const { node, pos } = (0, view_1.findChildByID)(this.view, affiliation.id) || {};
47
+ if (!node || !pos) {
48
+ return;
49
+ }
50
+ if (!(0, track_changes_utils_1.isDeleted)(node)) {
51
+ this.showContextMenu(affiliation);
52
+ }
53
+ const view = this.view;
54
+ const tr = view.state.tr;
55
+ tr.setSelection(prosemirror_state_1.NodeSelection.create(view.state.doc, pos));
56
+ view.dispatch(tr);
53
57
  };
54
58
  this.insertAffiliationNode = (attrs) => {
55
59
  const pos = this.getPos();
@@ -66,12 +70,16 @@ class AffiliationsView extends block_view_1.default {
66
70
  this.handleDeleteAffiliation = (affiliation) => {
67
71
  (0, view_1.deleteNode)(this.view, affiliation.id);
68
72
  };
69
- this.handleEdit = (addNew) => {
73
+ this.handleEdit = (id, addNew) => {
70
74
  var _a;
71
75
  this.props.popper.destroy();
72
76
  const contributors = (0, view_1.findChildrenAttrsByType)(this.view, transform_1.schema.nodes.contributor);
73
77
  const affiliations = (0, view_1.findChildrenAttrsByType)(this.view, transform_1.schema.nodes.affiliation);
78
+ const affiliation = id
79
+ ? affiliations.filter((a) => a.id === id)[0]
80
+ : undefined;
74
81
  const componentProps = {
82
+ affiliation,
75
83
  authors: contributors,
76
84
  affiliations,
77
85
  onSaveAffiliation: this.handleSaveAffiliation,
@@ -83,7 +91,7 @@ class AffiliationsView extends block_view_1.default {
83
91
  this.popper = (0, ReactSubView_1.default)(this.props, AffiliationsModal_1.AffiliationsModal, componentProps, this.node, this.getPos, this.view);
84
92
  this.container.appendChild(this.popper);
85
93
  };
86
- this.showContextMenu = () => {
94
+ this.showGroupContextMenu = () => {
87
95
  const can = this.props.getCapabilities();
88
96
  const componentProps = {
89
97
  actions: [],
@@ -96,12 +104,12 @@ class AffiliationsView extends block_view_1.default {
96
104
  });
97
105
  componentProps.actions.push({
98
106
  label: 'New Affiliation',
99
- action: () => this.handleEdit(true),
107
+ action: () => this.handleEdit('', true),
100
108
  icon: 'AddOutline',
101
109
  });
102
110
  componentProps.actions.push({
103
111
  label: 'Edit',
104
- action: () => this.handleEdit(),
112
+ action: () => this.handleEdit(''),
105
113
  icon: 'Edit',
106
114
  });
107
115
  this.contextMenu = (0, ReactSubView_1.default)(this.props, style_guide_1.ContextMenu, componentProps, this.node, this.getPos, this.view, ['context-menu']);
@@ -109,15 +117,30 @@ class AffiliationsView extends block_view_1.default {
109
117
  }
110
118
  return undefined;
111
119
  };
120
+ this.showContextMenu = (element) => {
121
+ const affiliationNameBlock = element.querySelector('.affiliation-name');
122
+ this.props.popper.destroy();
123
+ const componentProps = {
124
+ actions: [
125
+ {
126
+ label: 'Edit',
127
+ action: () => this.handleEdit(element.id),
128
+ icon: 'Edit',
129
+ },
130
+ ],
131
+ };
132
+ this.contextMenu = (0, ReactSubView_1.default)(this.props, style_guide_1.ContextMenu, componentProps, this.node, this.getPos, this.view, ['context-menu']);
133
+ this.props.popper.show(affiliationNameBlock || element, this.contextMenu, 'right-start');
134
+ };
112
135
  this.actionGutterButtons = () => {
113
- const contextMenu = this.showContextMenu();
136
+ const contextMenu = this.showGroupContextMenu();
114
137
  return contextMenu ? [contextMenu] : [];
115
138
  };
116
139
  this.selectNode = () => {
117
140
  const selectedMarker = document.querySelector('.comment-marker.selected-comment');
118
141
  this.dom.classList.add('ProseMirror-selectednode');
119
142
  if (!(0, track_changes_utils_1.isDeleted)(this.node) && !selectedMarker) {
120
- this.handleEdit(true);
143
+ this.handleEdit('', true);
121
144
  }
122
145
  };
123
146
  this.handleUpdateAuthors = (authors) => {