@manuscripts/body-editor 3.19.0 → 3.19.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.
@@ -48,7 +48,7 @@ var __importStar = (this && this.__importStar) || (function () {
48
48
  };
49
49
  })();
50
50
  Object.defineProperty(exports, "__esModule", { value: true });
51
- exports.ReferenceForm = void 0;
51
+ exports.ReferenceForm = exports.validateReference = void 0;
52
52
  const style_guide_1 = require("@manuscripts/style-guide");
53
53
  const formik_1 = require("formik");
54
54
  const react_1 = __importStar(require("react"));
@@ -61,7 +61,22 @@ const bibliographyItemTypeOptions = references_1.bibliographyItemTypes.map((i) =
61
61
  label: i[1],
62
62
  value: i[0],
63
63
  }));
64
- const ReferenceForm = ({ values, showDelete, onChange, onDelete, onCancel, onSave, actionsRef, }) => {
64
+ const validateReference = (values) => {
65
+ const errors = {};
66
+ if (values.type === 'literal') {
67
+ if (!values.literal?.trim()) {
68
+ errors.literal = 'Literal is required for unstructured references';
69
+ }
70
+ }
71
+ else {
72
+ if (!values.title?.trim()) {
73
+ errors.title = 'Title is required';
74
+ }
75
+ }
76
+ return errors;
77
+ };
78
+ exports.validateReference = validateReference;
79
+ const ReferenceForm = ({ values, onChange, onSave, actionsRef, }) => {
65
80
  const fieldsRef = (0, react_1.useRef)(null);
66
81
  const formRef = (0, react_1.useRef)(null);
67
82
  const [newAuthorIndex, setNewAuthorIndex] = (0, react_1.useState)();
@@ -71,52 +86,19 @@ const ReferenceForm = ({ values, showDelete, onChange, onDelete, onCancel, onSav
71
86
  fieldsRef.current.scrollTop = 0;
72
87
  }
73
88
  }, [values]);
74
- const [showDeleteDialog, setShowDeleteDialog] = (0, react_1.useState)(false);
75
- const validateReference = (values) => {
76
- const errors = {};
77
- if (values.type === 'literal') {
78
- if (!values.literal?.trim()) {
79
- errors.literal = 'Literal is required for unstructured references';
80
- }
81
- }
82
- else {
83
- if (!values.title?.trim()) {
84
- errors.title = 'Title is required';
85
- }
86
- }
87
- return errors;
88
- };
89
89
  if (actionsRef && !actionsRef.current) {
90
90
  actionsRef.current = {
91
91
  reset: () => {
92
92
  formRef.current?.resetForm();
93
93
  },
94
+ submit: () => {
95
+ formRef.current?.submitForm();
96
+ },
97
+ isDirty: () => formRef.current?.dirty ?? false,
94
98
  };
95
99
  }
96
- return (react_1.default.createElement(formik_1.Formik, { initialValues: values, onSubmit: onSave, enableReinitialize: true, innerRef: formRef, validate: validateReference }, (formik) => {
100
+ return (react_1.default.createElement(formik_1.Formik, { initialValues: values, onSubmit: onSave, enableReinitialize: true, innerRef: formRef, validate: exports.validateReference }, (formik) => {
97
101
  return (react_1.default.createElement(ChangeHandlingForm_1.ChangeHandlingForm, { onChange: onChange },
98
- react_1.default.createElement(style_guide_1.Dialog, { isOpen: showDeleteDialog, category: style_guide_1.Category.confirmation, header: "Delete Reference", message: "Are you sure you want to delete this reference from the list?", actions: {
99
- secondary: {
100
- action: () => {
101
- onDelete();
102
- setShowDeleteDialog(false);
103
- },
104
- title: 'Delete',
105
- },
106
- primary: {
107
- action: () => setShowDeleteDialog(false),
108
- title: 'Cancel',
109
- },
110
- } }),
111
- react_1.default.createElement(styled_components_1.Actions, null,
112
- react_1.default.createElement(style_guide_1.ButtonGroup, null,
113
- react_1.default.createElement(style_guide_1.IconButton, { as: "a", href: `https://doi.org/${formik.values.DOI}`, target: '_blank' },
114
- react_1.default.createElement(style_guide_1.LinkIcon, null)),
115
- react_1.default.createElement(styled_components_1.DeleteButton, { "$defaultColor": true, disabled: !showDelete, "data-tooltip-content": "Unable to delete because the item is used in the document", "data-tooltip-hidden": showDelete, onClick: () => setShowDeleteDialog(true) },
116
- react_1.default.createElement(style_guide_1.DeleteIcon, null))),
117
- react_1.default.createElement(style_guide_1.ButtonGroup, null,
118
- react_1.default.createElement(style_guide_1.SecondaryButton, { onClick: onCancel }, "Cancel"),
119
- react_1.default.createElement(style_guide_1.PrimaryButton, { type: "submit", disabled: !formik.isValid || !formik.dirty }, "Save"))),
120
102
  react_1.default.createElement(styled_components_1.FormFields, { ref: fieldsRef },
121
103
  react_1.default.createElement(style_guide_1.FormRow, null,
122
104
  react_1.default.createElement(style_guide_1.Label, { htmlFor: 'citation-item-type' }, "Type"),
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.RemoveButton = exports.ToggleButton = exports.DropdownIndicator = exports.Title = exports.PersonForm = exports.Section = exports.DeleteButton = exports.FormFields = exports.ReferenceTextArea = exports.ReferenceTextField = exports.Actions = exports.Button = void 0;
6
+ exports.RemoveButton = exports.ToggleButton = exports.DropdownIndicator = exports.Title = exports.PersonForm = exports.Section = exports.DeleteButton = exports.FormFields = exports.ReferenceTextArea = exports.ReferenceTextField = exports.Button = void 0;
7
7
  const style_guide_1 = require("@manuscripts/style-guide");
8
8
  const styled_components_1 = __importDefault(require("styled-components"));
9
9
  exports.Button = (0, styled_components_1.default)(style_guide_1.IconButton).attrs({
@@ -19,18 +19,6 @@ exports.Button = (0, styled_components_1.default)(style_guide_1.IconButton).attr
19
19
  mask: none;
20
20
  }
21
21
  `;
22
- exports.Actions = styled_components_1.default.div `
23
- flex-shrink: 1;
24
- display: flex;
25
- justify-content: space-between;
26
- align-items: center;
27
-
28
- .tooltip {
29
- max-width: ${(props) => props.theme.grid.unit * 39}px;
30
- padding: ${(props) => props.theme.grid.unit * 2}px;
31
- border-radius: 6px;
32
- }
33
- `;
34
22
  exports.ReferenceTextField = (0, styled_components_1.default)(style_guide_1.TextField) `
35
23
  padding: ${(props) => props.theme.grid.unit * 2}px
36
24
  ${(props) => props.theme.grid.unit * 3}px;
@@ -32,13 +32,20 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
35
38
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ReferencesEditor = void 0;
39
+ exports.openReferencesEditor = exports.ReferencesEditor = void 0;
37
40
  const transform_1 = require("@manuscripts/transform");
38
41
  const react_1 = __importStar(require("react"));
39
42
  const array_reducer_1 = require("../../lib/array-reducer");
40
43
  const utils_1 = require("../../lib/utils");
41
44
  const ReferencesModal_1 = require("./ReferencesModal");
45
+ const editor_props_1 = require("../../plugins/editor-props");
46
+ const view_1 = require("../../lib/view");
47
+ const ReactSubView_1 = __importDefault(require("../../views/ReactSubView"));
48
+ const bibliography_1 = require("../../plugins/bibliography");
42
49
  const itemsReducer = (0, array_reducer_1.attrsReducer)();
43
50
  const ReferencesEditor = (props) => {
44
51
  const [isOpen, setOpen] = (0, react_1.useState)(true);
@@ -76,3 +83,21 @@ const ReferencesEditor = (props) => {
76
83
  return (react_1.default.createElement(ReferencesModal_1.ReferencesModal, { isOpen: isOpen, onCancel: () => setOpen(false), items: items, item: selectedItem, citationCounts: props.citationCounts, onSave: handleSave, onDelete: handleDelete, handleImport: handleImport }));
77
84
  };
78
85
  exports.ReferencesEditor = ReferencesEditor;
86
+ const openReferencesEditor = (state, _, view) => {
87
+ if (!view) {
88
+ return false;
89
+ }
90
+ const props = (0, editor_props_1.getEditorProps)(state);
91
+ const bib = (0, bibliography_1.getBibliographyPluginState)(view.state);
92
+ const componentProps = {
93
+ items: bib ? Array.from(bib.bibliographyItems.values()) : [],
94
+ citationCounts: new Map(bib?.citationCounts),
95
+ onDelete: (item) => (0, view_1.deleteNode)(view, item.id),
96
+ onSave: (item) => (0, view_1.saveBibliographyItem)(view, item),
97
+ };
98
+ const referencesEditor = (0, ReactSubView_1.default)(props, exports.ReferencesEditor, componentProps, state.doc, () => 0, view);
99
+ view.focus();
100
+ document.body.appendChild(referencesEditor);
101
+ return true;
102
+ };
103
+ exports.openReferencesEditor = openReferencesEditor;
@@ -38,10 +38,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.ReferencesModal = void 0;
40
40
  const style_guide_1 = require("@manuscripts/style-guide");
41
+ const mui_1 = require("@manuscripts/style-guide/mui");
41
42
  const transform_1 = require("@manuscripts/transform");
42
43
  const isEqual_1 = __importDefault(require("lodash/isEqual"));
43
44
  const react_1 = __importStar(require("react"));
44
- const styled_components_1 = __importDefault(require("styled-components"));
45
+ const styled_components_1 = __importStar(require("styled-components"));
45
46
  const ReferenceForm_1 = require("./ReferenceForm/ReferenceForm");
46
47
  const ReferenceLine_1 = require("./ReferenceLine");
47
48
  const ImportBibliographyModal_1 = require("./ImportBibliographyModal");
@@ -59,6 +60,7 @@ const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts, onSave
59
60
  const valuesRef = (0, react_1.useRef)(undefined);
60
61
  const [selection, setSelection] = (0, react_1.useState)();
61
62
  const [isNew, setIsNew] = (0, react_1.useState)(false);
63
+ const [showDeleteDialog, setShowDeleteDialog] = (0, react_1.useState)(false);
62
64
  const selectionRef = (0, react_1.useRef)(null);
63
65
  const sortedItems = (0, react_1.useMemo)(() => [...items].sort((a, b) => {
64
66
  const aUncited = (citationCounts.get(a.id) ?? 0) === 0;
@@ -123,6 +125,10 @@ const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts, onSave
123
125
  const extraKeys = allKeys.filter((key) => !basicProps.includes(key));
124
126
  return extraKeys.length > 0;
125
127
  };
128
+ const canDeleteSelectedItem = (selection &&
129
+ !citationCounts.get(selection.id) &&
130
+ isNewItem(selection, ['id', 'type'])) ??
131
+ false;
126
132
  const handleSave = (values) => {
127
133
  if (!values || !selection) {
128
134
  return;
@@ -161,8 +167,13 @@ const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts, onSave
161
167
  setIsNew(false);
162
168
  setSelection(item);
163
169
  };
170
+ const [canSave, setCanSave] = (0, react_1.useState)(false);
164
171
  const handleChange = (values) => {
165
172
  valuesRef.current = values;
173
+ const errors = (0, ReferenceForm_1.validateReference)(values);
174
+ const isValid = Object.keys(errors).length === 0;
175
+ const dirty = actionsRef.current?.isDirty() ?? false;
176
+ setCanSave(isValid && dirty);
166
177
  };
167
178
  const handleImportSave = (data) => {
168
179
  handleImport(data);
@@ -183,6 +194,19 @@ const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts, onSave
183
194
  title: 'Save',
184
195
  },
185
196
  } }),
197
+ react_1.default.createElement(style_guide_1.Dialog, { isOpen: showDeleteDialog, category: style_guide_1.Category.confirmation, header: "Delete Reference", message: "Are you sure you want to delete this reference from the list?", actions: {
198
+ secondary: {
199
+ action: () => {
200
+ handleDelete();
201
+ setShowDeleteDialog(false);
202
+ },
203
+ title: 'Delete',
204
+ },
205
+ primary: {
206
+ action: () => setShowDeleteDialog(false),
207
+ title: 'Cancel',
208
+ },
209
+ } }),
186
210
  react_1.default.createElement(ReferencesModalContainer, { "data-cy": 'references-editor' },
187
211
  react_1.default.createElement(style_guide_1.ModalHeader, null,
188
212
  react_1.default.createElement(style_guide_1.CloseButton, { "data-cy": "modal-close-button", onClick: onCancel })),
@@ -205,18 +229,25 @@ const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts, onSave
205
229
  react_1.default.createElement(style_guide_1.AddIcon, null),
206
230
  react_1.default.createElement("span", null, "New Reference")),
207
231
  react_1.default.createElement(ReferencesInnerWrapper, null,
208
- react_1.default.createElement(ExistingReferencesHeading, null, "Existing References"),
232
+ sortedItems.length ? (react_1.default.createElement(ExistingReferencesHeading, null, "Existing References")) : null,
209
233
  sortedItems.slice(startIndex, endIndex + 1).map((item) => (react_1.default.createElement(ReferenceButton, { key: item.id, id: item.id, className: isSelected(item) ? 'selected' : '', onClick: () => handleItemClick(item), ref: isSelected(item) ? selectionRef : null },
210
234
  react_1.default.createElement(IconContainer, null,
211
235
  react_1.default.createElement(CitationCountIconStyled, null),
212
236
  (citationCounts.get(item.id) || 0) > 0 ? (react_1.default.createElement(CitationCount, { "data-tooltip-content": "Number of times used in the document" }, citationCounts.get(item.id))) : (react_1.default.createElement(CitationCount, { className: "unused" }, "0"))),
213
- react_1.default.createElement(ReferenceLine_1.ReferenceLine, { showUncited: !citationCounts.get(item.id), item: item })))))),
237
+ react_1.default.createElement(ReferenceLine_1.ReferenceLine, { showUncited: !citationCounts.get(item.id), item: item }),
238
+ isSelected(item) && (react_1.default.createElement(style_guide_1.ButtonGroup, null,
239
+ react_1.default.createElement(mui_1.IconButton, { component: 'a', href: `https://doi.org/${item.DOI}`, target: '_blank', size: 'small' },
240
+ react_1.default.createElement(DOILinkIcon, { fill: '#6E6E6E' })),
241
+ react_1.default.createElement(mui_1.IconButton, { disabled: !canDeleteSelectedItem, size: 'small', onClick: () => setShowDeleteDialog(true) },
242
+ react_1.default.createElement(style_guide_1.DeleteIcon, { fill: '#6E6E6E' }))))))))),
214
243
  react_1.default.createElement(ImportFromFileFooter, null,
215
244
  react_1.default.createElement(ImportFromFileButton, { type: "button", "data-cy": "import-from-file-button", onClick: () => setImporting(true) },
216
245
  react_1.default.createElement(style_guide_1.AddAuthorIcon, null),
217
246
  "Import from file"))),
218
- react_1.default.createElement(style_guide_1.ScrollableModalContent, null, importSuccessCount !== null ? (react_1.default.createElement(ImportSuccessPlaceholder_1.ImportSuccessPlaceholder, { count: importSuccessCount })) : (selection && (react_1.default.createElement(ReferenceForm_1.ReferenceForm, { values: (0, normalize_1.normalizeBlblioItem)(selection), showDelete: !citationCounts.get(selection.id) &&
219
- isNewItem(selection, ['id', 'type']), onChange: handleChange, onCancel: onCancel, onDelete: handleDelete, onSave: handleSave, actionsRef: actionsRef })))))))));
247
+ react_1.default.createElement(ReferencesContent, null, importSuccessCount !== null ? (react_1.default.createElement(ImportSuccessPlaceholder_1.ImportSuccessPlaceholder, { count: importSuccessCount })) : (selection && (react_1.default.createElement(ReferenceForm_1.ReferenceForm, { values: (0, normalize_1.normalizeBlblioItem)(selection), onChange: handleChange, onSave: handleSave, actionsRef: actionsRef }))))),
248
+ react_1.default.createElement(Footer, null,
249
+ react_1.default.createElement(TertiaryButton, { variant: "tertiary", onClick: onCancel }, "Close"),
250
+ react_1.default.createElement(mui_1.Button, { disabled: !canSave, onClick: () => actionsRef.current?.submit() }, "Save Changes"))))));
220
251
  };
221
252
  exports.ReferencesModal = ReferencesModal;
222
253
  const ReferencesModalContainer = (0, styled_components_1.default)(style_guide_1.ModalContainer) `
@@ -225,15 +256,19 @@ const ReferencesModalContainer = (0, styled_components_1.default)(style_guide_1.
225
256
  const ReferencesSidebar = (0, styled_components_1.default)(style_guide_1.ModalSidebar) `
226
257
  width: 70%;
227
258
  `;
259
+ const ReferencesContent = (0, styled_components_1.default)(style_guide_1.ScrollableModalContent) `
260
+ padding-top: 32px;
261
+ `;
228
262
  const ReferencesSidebarContent = (0, styled_components_1.default)(style_guide_1.SidebarContent) `
229
263
  overflow-y: auto;
264
+ padding-top: 8px;
230
265
  `;
231
266
  const ReferencesInnerWrapper = (0, style_guide_1.withListNavigation)(styled_components_1.default.div `
232
267
  width: 100%;
233
268
  padding: 12px 0;
234
269
  `);
235
270
  const CitationCountIconStyled = (0, styled_components_1.default)(style_guide_1.CitationCountIcon) ``;
236
- const ReferenceButton = (0, style_guide_1.withNavigableListItem)(styled_components_1.default.button `
271
+ const referenceButtonStyles = (0, styled_components_1.css) `
237
272
  cursor: pointer;
238
273
  display: flex;
239
274
  width: 100%;
@@ -245,6 +280,7 @@ const ReferenceButton = (0, style_guide_1.withNavigableListItem)(styled_componen
245
280
  border: none;
246
281
  border-radius: 0;
247
282
  text-align: inherit;
283
+ color: #353535;
248
284
 
249
285
  padding: ${(props) => props.theme.grid.unit * 4}px 0;
250
286
  border-top: 1px solid transparent;
@@ -269,6 +305,12 @@ const ReferenceButton = (0, style_guide_1.withNavigableListItem)(styled_componen
269
305
  padding: ${(props) => props.theme.grid.unit * 2}px;
270
306
  border-radius: 6px;
271
307
  }
308
+ `;
309
+ const ReferenceButton = (0, style_guide_1.withNavigableListItem)(styled_components_1.default.div.attrs({
310
+ role: 'button',
311
+ tabIndex: 0,
312
+ }) `
313
+ ${referenceButtonStyles}
272
314
  `);
273
315
  const IconContainer = styled_components_1.default.div `
274
316
  padding-right: ${(props) => props.theme.grid.unit * 5}px;
@@ -291,10 +333,14 @@ const CitationCount = styled_components_1.default.div `
291
333
  background-color: #fe8f1f;
292
334
  }
293
335
  `;
294
- const NewReferenceButton = (0, styled_components_1.default)(ReferenceButton) `
336
+ const NewReferenceButton = styled_components_1.default.button `
337
+ ${referenceButtonStyles}
338
+
295
339
  svg {
296
340
  margin-right: 8px;
297
341
  }
342
+
343
+ ${style_guide_1.outlineStyle}
298
344
  `;
299
345
  const ExistingReferencesHeading = styled_components_1.default.h3 `
300
346
  font-size: 18px;
@@ -331,3 +377,21 @@ const ImportFromFileButton = styled_components_1.default.button `
331
377
  fill: #6e6e6e;
332
378
  }
333
379
  `;
380
+ const Footer = styled_components_1.default.div `
381
+ display: flex;
382
+ justify-content: flex-end;
383
+ padding: 16px 32px;
384
+ gap: 16px;
385
+ `;
386
+ const TertiaryButton = (0, styled_components_1.default)(mui_1.Button) `
387
+ &.MuiButton-textSecondary {
388
+ color: #0d79d0;
389
+
390
+ &:hover {
391
+ background-color: rgba(13, 121, 208, 0.04);
392
+ }
393
+ }
394
+ `;
395
+ const DOILinkIcon = (0, styled_components_1.default)(style_guide_1.LinkIcon) `
396
+ transform: rotate(-45deg);
397
+ `;
package/dist/cjs/menus.js CHANGED
@@ -29,6 +29,7 @@ const template_1 = require("./lib/template");
29
29
  const utils_1 = require("./lib/utils");
30
30
  const editor_props_1 = require("./plugins/editor-props");
31
31
  const AwardModal_1 = require("./components/awards/AwardModal");
32
+ const ReferencesEditor_1 = require("./components/references/ReferencesEditor");
32
33
  const getEditorMenus = (editor) => {
33
34
  const { isCommandValid, state, view } = editor;
34
35
  const doCommand = (command) => () => editor.doCommand(command);
@@ -566,6 +567,17 @@ const getEditorMenus = (editor) => {
566
567
  run: doCommand(commands_1.insertInlineCitation),
567
568
  isHidden: !(0, template_1.templateAllows)(state, transform_1.schema.nodes.citation),
568
569
  },
570
+ {
571
+ id: 'insert-reference-section',
572
+ label: 'New reference',
573
+ shortcut: {
574
+ mac: 'Option+CommandOrControl+N',
575
+ pc: 'CommandOrControl+Option+N',
576
+ },
577
+ isEnabled: (0, utils_1.isEditAllowed)(state),
578
+ run: doCommand(ReferencesEditor_1.openReferencesEditor),
579
+ isHidden: !(0, template_1.templateAllows)(state, transform_1.schema.nodes.bibliography_item),
580
+ },
569
581
  {
570
582
  id: 'insert-cross-reference',
571
583
  label: 'Cross-reference',
@@ -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 = '3.19.0';
4
+ exports.VERSION = '3.19.1';
5
5
  exports.MATHJAX_VERSION = '3.2.2';
@@ -13,19 +13,33 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { AddAuthorIcon, ButtonGroup, Category, DeleteIcon, Dialog, IconButton, LinkIcon, PrimaryButton, SecondaryButton, SelectField, Label, FormRow, YearField, } from '@manuscripts/style-guide';
16
+ import { AddAuthorIcon, SelectField, Label, FormRow, YearField, } from '@manuscripts/style-guide';
17
17
  import { Field, FieldArray, Formik } from 'formik';
18
18
  import React, { useEffect, useRef, useState } from 'react';
19
19
  import { bibliographyItemTypes } from '../../../lib/references';
20
20
  import { shouldRenderField } from '../../../lib/utils';
21
21
  import { ChangeHandlingForm } from '../../ChangeHandlingForm';
22
22
  import { PersonDropDown } from './PersonDropDown';
23
- import { Actions, Button, DeleteButton, FormFields, ReferenceTextArea, ReferenceTextField, } from './styled-components';
23
+ import { Button, FormFields, ReferenceTextArea, ReferenceTextField, } from './styled-components';
24
24
  const bibliographyItemTypeOptions = bibliographyItemTypes.map((i) => ({
25
25
  label: i[1],
26
26
  value: i[0],
27
27
  }));
28
- export const ReferenceForm = ({ values, showDelete, onChange, onDelete, onCancel, onSave, actionsRef, }) => {
28
+ export const validateReference = (values) => {
29
+ const errors = {};
30
+ if (values.type === 'literal') {
31
+ if (!values.literal?.trim()) {
32
+ errors.literal = 'Literal is required for unstructured references';
33
+ }
34
+ }
35
+ else {
36
+ if (!values.title?.trim()) {
37
+ errors.title = 'Title is required';
38
+ }
39
+ }
40
+ return errors;
41
+ };
42
+ export const ReferenceForm = ({ values, onChange, onSave, actionsRef, }) => {
29
43
  const fieldsRef = useRef(null);
30
44
  const formRef = useRef(null);
31
45
  const [newAuthorIndex, setNewAuthorIndex] = useState();
@@ -35,52 +49,19 @@ export const ReferenceForm = ({ values, showDelete, onChange, onDelete, onCancel
35
49
  fieldsRef.current.scrollTop = 0;
36
50
  }
37
51
  }, [values]);
38
- const [showDeleteDialog, setShowDeleteDialog] = useState(false);
39
- const validateReference = (values) => {
40
- const errors = {};
41
- if (values.type === 'literal') {
42
- if (!values.literal?.trim()) {
43
- errors.literal = 'Literal is required for unstructured references';
44
- }
45
- }
46
- else {
47
- if (!values.title?.trim()) {
48
- errors.title = 'Title is required';
49
- }
50
- }
51
- return errors;
52
- };
53
52
  if (actionsRef && !actionsRef.current) {
54
53
  actionsRef.current = {
55
54
  reset: () => {
56
55
  formRef.current?.resetForm();
57
56
  },
57
+ submit: () => {
58
+ formRef.current?.submitForm();
59
+ },
60
+ isDirty: () => formRef.current?.dirty ?? false,
58
61
  };
59
62
  }
60
63
  return (React.createElement(Formik, { initialValues: values, onSubmit: onSave, enableReinitialize: true, innerRef: formRef, validate: validateReference }, (formik) => {
61
64
  return (React.createElement(ChangeHandlingForm, { onChange: onChange },
62
- React.createElement(Dialog, { isOpen: showDeleteDialog, category: Category.confirmation, header: "Delete Reference", message: "Are you sure you want to delete this reference from the list?", actions: {
63
- secondary: {
64
- action: () => {
65
- onDelete();
66
- setShowDeleteDialog(false);
67
- },
68
- title: 'Delete',
69
- },
70
- primary: {
71
- action: () => setShowDeleteDialog(false),
72
- title: 'Cancel',
73
- },
74
- } }),
75
- React.createElement(Actions, null,
76
- React.createElement(ButtonGroup, null,
77
- React.createElement(IconButton, { as: "a", href: `https://doi.org/${formik.values.DOI}`, target: '_blank' },
78
- React.createElement(LinkIcon, null)),
79
- React.createElement(DeleteButton, { "$defaultColor": true, disabled: !showDelete, "data-tooltip-content": "Unable to delete because the item is used in the document", "data-tooltip-hidden": showDelete, onClick: () => setShowDeleteDialog(true) },
80
- React.createElement(DeleteIcon, null))),
81
- React.createElement(ButtonGroup, null,
82
- React.createElement(SecondaryButton, { onClick: onCancel }, "Cancel"),
83
- React.createElement(PrimaryButton, { type: "submit", disabled: !formik.isValid || !formik.dirty }, "Save"))),
84
65
  React.createElement(FormFields, { ref: fieldsRef },
85
66
  React.createElement(FormRow, null,
86
67
  React.createElement(Label, { htmlFor: 'citation-item-type' }, "Type"),
@@ -13,18 +13,6 @@ export const Button = styled(IconButton).attrs({
13
13
  mask: none;
14
14
  }
15
15
  `;
16
- export const Actions = styled.div `
17
- flex-shrink: 1;
18
- display: flex;
19
- justify-content: space-between;
20
- align-items: center;
21
-
22
- .tooltip {
23
- max-width: ${(props) => props.theme.grid.unit * 39}px;
24
- padding: ${(props) => props.theme.grid.unit * 2}px;
25
- border-radius: 6px;
26
- }
27
- `;
28
16
  export const ReferenceTextField = styled(TextField) `
29
17
  padding: ${(props) => props.theme.grid.unit * 2}px
30
18
  ${(props) => props.theme.grid.unit * 3}px;
@@ -3,6 +3,10 @@ import React, { useEffect, useReducer, useState } from 'react';
3
3
  import { attrsReducer } from '../../lib/array-reducer';
4
4
  import { cleanItemValues } from '../../lib/utils';
5
5
  import { ReferencesModal } from './ReferencesModal';
6
+ import { getEditorProps } from '../../plugins/editor-props';
7
+ import { deleteNode, saveBibliographyItem } from '../../lib/view';
8
+ import ReactSubView from '../../views/ReactSubView';
9
+ import { getBibliographyPluginState } from '../../plugins/bibliography';
6
10
  const itemsReducer = attrsReducer();
7
11
  export const ReferencesEditor = (props) => {
8
12
  const [isOpen, setOpen] = useState(true);
@@ -39,3 +43,20 @@ export const ReferencesEditor = (props) => {
39
43
  };
40
44
  return (React.createElement(ReferencesModal, { isOpen: isOpen, onCancel: () => setOpen(false), items: items, item: selectedItem, citationCounts: props.citationCounts, onSave: handleSave, onDelete: handleDelete, handleImport: handleImport }));
41
45
  };
46
+ export const openReferencesEditor = (state, _, view) => {
47
+ if (!view) {
48
+ return false;
49
+ }
50
+ const props = getEditorProps(state);
51
+ const bib = getBibliographyPluginState(view.state);
52
+ const componentProps = {
53
+ items: bib ? Array.from(bib.bibliographyItems.values()) : [],
54
+ citationCounts: new Map(bib?.citationCounts),
55
+ onDelete: (item) => deleteNode(view, item.id),
56
+ onSave: (item) => saveBibliographyItem(view, item),
57
+ };
58
+ const referencesEditor = ReactSubView(props, ReferencesEditor, componentProps, state.doc, () => 0, view);
59
+ view.focus();
60
+ document.body.appendChild(referencesEditor);
61
+ return true;
62
+ };