@manuscripts/body-editor 3.18.7 → 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.
- package/dist/cjs/components/references/ReferenceForm/ReferenceForm.js +22 -40
- package/dist/cjs/components/references/ReferenceForm/styled-components.js +1 -13
- package/dist/cjs/components/references/ReferencesEditor.js +26 -1
- package/dist/cjs/components/references/ReferencesModal.js +71 -7
- package/dist/cjs/menus.js +12 -0
- package/dist/cjs/versions.js +1 -1
- package/dist/es/components/references/ReferenceForm/ReferenceForm.js +21 -40
- package/dist/es/components/references/ReferenceForm/styled-components.js +0 -12
- package/dist/es/components/references/ReferencesEditor.js +21 -0
- package/dist/es/components/references/ReferencesModal.js +73 -9
- package/dist/es/menus.js +12 -0
- package/dist/es/versions.js +1 -1
- package/dist/types/components/references/ReferenceForm/ReferenceForm.d.ts +3 -3
- package/dist/types/components/references/ReferenceForm/styled-components.d.ts +0 -1
- package/dist/types/components/references/ReferencesEditor.d.ts +3 -0
- package/dist/types/versions.d.ts +1 -1
- package/package.json +2 -2
- package/src/components/references/ReferenceForm/ReferenceForm.tsx +21 -82
- package/src/components/references/ReferenceForm/styled-components.ts +0 -13
- package/src/components/references/ReferencesEditor.tsx +38 -0
- package/src/components/references/ReferencesModal.tsx +116 -14
- package/src/lib/view.ts +1 -0
- package/src/menus.tsx +12 -0
- package/src/versions.ts +1 -1
|
@@ -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
|
|
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.
|
|
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 =
|
|
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(
|
|
219
|
-
|
|
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
|
|
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 =
|
|
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',
|
package/dist/cjs/versions.js
CHANGED
|
@@ -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,
|
|
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 {
|
|
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
|
|
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
|
+
};
|