@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.
- 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
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { AddIcon, AddAuthorIcon, Category, CitationCountIcon, CloseButton, Dialog, ModalBody, ModalContainer, ModalHeader, ModalSidebar, ModalSidebarHeader, ModalSidebarTitle, ScrollableModalContent, SidebarContent, StyledModal, useScrollDetection, withListNavigation, withNavigableListItem, } from '@manuscripts/style-guide';
|
|
1
|
+
import { AddIcon, AddAuthorIcon, Category, CitationCountIcon, CloseButton, Dialog, ModalBody, ModalContainer, ModalHeader, ModalSidebar, ModalSidebarHeader, ModalSidebarTitle, ScrollableModalContent, SidebarContent, StyledModal, useScrollDetection, withListNavigation, withNavigableListItem, ButtonGroup, DeleteIcon, LinkIcon, outlineStyle, } from '@manuscripts/style-guide';
|
|
2
|
+
import { Button, IconButton } from '@manuscripts/style-guide/mui';
|
|
2
3
|
import { generateNodeID, schema, } from '@manuscripts/transform';
|
|
3
4
|
import isEqual from 'lodash/isEqual';
|
|
4
5
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
5
|
-
import styled from 'styled-components';
|
|
6
|
-
import { ReferenceForm, } from './ReferenceForm/ReferenceForm';
|
|
6
|
+
import styled, { css } from 'styled-components';
|
|
7
|
+
import { ReferenceForm, validateReference, } from './ReferenceForm/ReferenceForm';
|
|
7
8
|
import { ReferenceLine } from './ReferenceLine';
|
|
8
9
|
import { ImportBibliographyModal } from './ImportBibliographyModal';
|
|
9
10
|
import { ImportSuccessPlaceholder } from './ImportSuccessPlaceholder';
|
|
@@ -20,6 +21,7 @@ export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts,
|
|
|
20
21
|
const valuesRef = useRef(undefined);
|
|
21
22
|
const [selection, setSelection] = useState();
|
|
22
23
|
const [isNew, setIsNew] = useState(false);
|
|
24
|
+
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
|
|
23
25
|
const selectionRef = useRef(null);
|
|
24
26
|
const sortedItems = useMemo(() => [...items].sort((a, b) => {
|
|
25
27
|
const aUncited = (citationCounts.get(a.id) ?? 0) === 0;
|
|
@@ -84,6 +86,10 @@ export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts,
|
|
|
84
86
|
const extraKeys = allKeys.filter((key) => !basicProps.includes(key));
|
|
85
87
|
return extraKeys.length > 0;
|
|
86
88
|
};
|
|
89
|
+
const canDeleteSelectedItem = (selection &&
|
|
90
|
+
!citationCounts.get(selection.id) &&
|
|
91
|
+
isNewItem(selection, ['id', 'type'])) ??
|
|
92
|
+
false;
|
|
87
93
|
const handleSave = (values) => {
|
|
88
94
|
if (!values || !selection) {
|
|
89
95
|
return;
|
|
@@ -122,8 +128,13 @@ export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts,
|
|
|
122
128
|
setIsNew(false);
|
|
123
129
|
setSelection(item);
|
|
124
130
|
};
|
|
131
|
+
const [canSave, setCanSave] = useState(false);
|
|
125
132
|
const handleChange = (values) => {
|
|
126
133
|
valuesRef.current = values;
|
|
134
|
+
const errors = validateReference(values);
|
|
135
|
+
const isValid = Object.keys(errors).length === 0;
|
|
136
|
+
const dirty = actionsRef.current?.isDirty() ?? false;
|
|
137
|
+
setCanSave(isValid && dirty);
|
|
127
138
|
};
|
|
128
139
|
const handleImportSave = (data) => {
|
|
129
140
|
handleImport(data);
|
|
@@ -144,6 +155,19 @@ export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts,
|
|
|
144
155
|
title: 'Save',
|
|
145
156
|
},
|
|
146
157
|
} }),
|
|
158
|
+
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: {
|
|
159
|
+
secondary: {
|
|
160
|
+
action: () => {
|
|
161
|
+
handleDelete();
|
|
162
|
+
setShowDeleteDialog(false);
|
|
163
|
+
},
|
|
164
|
+
title: 'Delete',
|
|
165
|
+
},
|
|
166
|
+
primary: {
|
|
167
|
+
action: () => setShowDeleteDialog(false),
|
|
168
|
+
title: 'Cancel',
|
|
169
|
+
},
|
|
170
|
+
} }),
|
|
147
171
|
React.createElement(ReferencesModalContainer, { "data-cy": 'references-editor' },
|
|
148
172
|
React.createElement(ModalHeader, null,
|
|
149
173
|
React.createElement(CloseButton, { "data-cy": "modal-close-button", onClick: onCancel })),
|
|
@@ -166,18 +190,25 @@ export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts,
|
|
|
166
190
|
React.createElement(AddIcon, null),
|
|
167
191
|
React.createElement("span", null, "New Reference")),
|
|
168
192
|
React.createElement(ReferencesInnerWrapper, null,
|
|
169
|
-
React.createElement(ExistingReferencesHeading, null, "Existing References"),
|
|
193
|
+
sortedItems.length ? (React.createElement(ExistingReferencesHeading, null, "Existing References")) : null,
|
|
170
194
|
sortedItems.slice(startIndex, endIndex + 1).map((item) => (React.createElement(ReferenceButton, { key: item.id, id: item.id, className: isSelected(item) ? 'selected' : '', onClick: () => handleItemClick(item), ref: isSelected(item) ? selectionRef : null },
|
|
171
195
|
React.createElement(IconContainer, null,
|
|
172
196
|
React.createElement(CitationCountIconStyled, null),
|
|
173
197
|
(citationCounts.get(item.id) || 0) > 0 ? (React.createElement(CitationCount, { "data-tooltip-content": "Number of times used in the document" }, citationCounts.get(item.id))) : (React.createElement(CitationCount, { className: "unused" }, "0"))),
|
|
174
|
-
React.createElement(ReferenceLine, { showUncited: !citationCounts.get(item.id), item: item })
|
|
198
|
+
React.createElement(ReferenceLine, { showUncited: !citationCounts.get(item.id), item: item }),
|
|
199
|
+
isSelected(item) && (React.createElement(ButtonGroup, null,
|
|
200
|
+
React.createElement(IconButton, { component: 'a', href: `https://doi.org/${item.DOI}`, target: '_blank', size: 'small' },
|
|
201
|
+
React.createElement(DOILinkIcon, { fill: '#6E6E6E' })),
|
|
202
|
+
React.createElement(IconButton, { disabled: !canDeleteSelectedItem, size: 'small', onClick: () => setShowDeleteDialog(true) },
|
|
203
|
+
React.createElement(DeleteIcon, { fill: '#6E6E6E' }))))))))),
|
|
175
204
|
React.createElement(ImportFromFileFooter, null,
|
|
176
205
|
React.createElement(ImportFromFileButton, { type: "button", "data-cy": "import-from-file-button", onClick: () => setImporting(true) },
|
|
177
206
|
React.createElement(AddAuthorIcon, null),
|
|
178
207
|
"Import from file"))),
|
|
179
|
-
React.createElement(
|
|
180
|
-
|
|
208
|
+
React.createElement(ReferencesContent, null, importSuccessCount !== null ? (React.createElement(ImportSuccessPlaceholder, { count: importSuccessCount })) : (selection && (React.createElement(ReferenceForm, { values: normalizeBlblioItem(selection), onChange: handleChange, onSave: handleSave, actionsRef: actionsRef }))))),
|
|
209
|
+
React.createElement(Footer, null,
|
|
210
|
+
React.createElement(TertiaryButton, { variant: "tertiary", onClick: onCancel }, "Close"),
|
|
211
|
+
React.createElement(Button, { disabled: !canSave, onClick: () => actionsRef.current?.submit() }, "Save Changes"))))));
|
|
181
212
|
};
|
|
182
213
|
const ReferencesModalContainer = styled(ModalContainer) `
|
|
183
214
|
min-width: 960px;
|
|
@@ -185,15 +216,19 @@ const ReferencesModalContainer = styled(ModalContainer) `
|
|
|
185
216
|
const ReferencesSidebar = styled(ModalSidebar) `
|
|
186
217
|
width: 70%;
|
|
187
218
|
`;
|
|
219
|
+
const ReferencesContent = styled(ScrollableModalContent) `
|
|
220
|
+
padding-top: 32px;
|
|
221
|
+
`;
|
|
188
222
|
const ReferencesSidebarContent = styled(SidebarContent) `
|
|
189
223
|
overflow-y: auto;
|
|
224
|
+
padding-top: 8px;
|
|
190
225
|
`;
|
|
191
226
|
const ReferencesInnerWrapper = withListNavigation(styled.div `
|
|
192
227
|
width: 100%;
|
|
193
228
|
padding: 12px 0;
|
|
194
229
|
`);
|
|
195
230
|
const CitationCountIconStyled = styled(CitationCountIcon) ``;
|
|
196
|
-
const
|
|
231
|
+
const referenceButtonStyles = css `
|
|
197
232
|
cursor: pointer;
|
|
198
233
|
display: flex;
|
|
199
234
|
width: 100%;
|
|
@@ -205,6 +240,7 @@ const ReferenceButton = withNavigableListItem(styled.button `
|
|
|
205
240
|
border: none;
|
|
206
241
|
border-radius: 0;
|
|
207
242
|
text-align: inherit;
|
|
243
|
+
color: #353535;
|
|
208
244
|
|
|
209
245
|
padding: ${(props) => props.theme.grid.unit * 4}px 0;
|
|
210
246
|
border-top: 1px solid transparent;
|
|
@@ -229,6 +265,12 @@ const ReferenceButton = withNavigableListItem(styled.button `
|
|
|
229
265
|
padding: ${(props) => props.theme.grid.unit * 2}px;
|
|
230
266
|
border-radius: 6px;
|
|
231
267
|
}
|
|
268
|
+
`;
|
|
269
|
+
const ReferenceButton = withNavigableListItem(styled.div.attrs({
|
|
270
|
+
role: 'button',
|
|
271
|
+
tabIndex: 0,
|
|
272
|
+
}) `
|
|
273
|
+
${referenceButtonStyles}
|
|
232
274
|
`);
|
|
233
275
|
const IconContainer = styled.div `
|
|
234
276
|
padding-right: ${(props) => props.theme.grid.unit * 5}px;
|
|
@@ -251,10 +293,14 @@ const CitationCount = styled.div `
|
|
|
251
293
|
background-color: #fe8f1f;
|
|
252
294
|
}
|
|
253
295
|
`;
|
|
254
|
-
const NewReferenceButton = styled
|
|
296
|
+
const NewReferenceButton = styled.button `
|
|
297
|
+
${referenceButtonStyles}
|
|
298
|
+
|
|
255
299
|
svg {
|
|
256
300
|
margin-right: 8px;
|
|
257
301
|
}
|
|
302
|
+
|
|
303
|
+
${outlineStyle}
|
|
258
304
|
`;
|
|
259
305
|
const ExistingReferencesHeading = styled.h3 `
|
|
260
306
|
font-size: 18px;
|
|
@@ -291,3 +337,21 @@ const ImportFromFileButton = styled.button `
|
|
|
291
337
|
fill: #6e6e6e;
|
|
292
338
|
}
|
|
293
339
|
`;
|
|
340
|
+
const Footer = styled.div `
|
|
341
|
+
display: flex;
|
|
342
|
+
justify-content: flex-end;
|
|
343
|
+
padding: 16px 32px;
|
|
344
|
+
gap: 16px;
|
|
345
|
+
`;
|
|
346
|
+
const TertiaryButton = styled(Button) `
|
|
347
|
+
&.MuiButton-textSecondary {
|
|
348
|
+
color: #0d79d0;
|
|
349
|
+
|
|
350
|
+
&:hover {
|
|
351
|
+
background-color: rgba(13, 121, 208, 0.04);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
`;
|
|
355
|
+
const DOILinkIcon = styled(LinkIcon) `
|
|
356
|
+
transform: rotate(-45deg);
|
|
357
|
+
`;
|
package/dist/es/menus.js
CHANGED
|
@@ -26,6 +26,7 @@ import { templateAllows } from './lib/template';
|
|
|
26
26
|
import { isEditAllowed } from './lib/utils';
|
|
27
27
|
import { getEditorProps } from './plugins/editor-props';
|
|
28
28
|
import { openInsertAwardModal } from './components/awards/AwardModal';
|
|
29
|
+
import { openReferencesEditor } from './components/references/ReferencesEditor';
|
|
29
30
|
export const getEditorMenus = (editor) => {
|
|
30
31
|
const { isCommandValid, state, view } = editor;
|
|
31
32
|
const doCommand = (command) => () => editor.doCommand(command);
|
|
@@ -563,6 +564,17 @@ export const getEditorMenus = (editor) => {
|
|
|
563
564
|
run: doCommand(insertInlineCitation),
|
|
564
565
|
isHidden: !templateAllows(state, schema.nodes.citation),
|
|
565
566
|
},
|
|
567
|
+
{
|
|
568
|
+
id: 'insert-reference-section',
|
|
569
|
+
label: 'New reference',
|
|
570
|
+
shortcut: {
|
|
571
|
+
mac: 'Option+CommandOrControl+N',
|
|
572
|
+
pc: 'CommandOrControl+Option+N',
|
|
573
|
+
},
|
|
574
|
+
isEnabled: isEditAllowed(state),
|
|
575
|
+
run: doCommand(openReferencesEditor),
|
|
576
|
+
isHidden: !templateAllows(state, schema.nodes.bibliography_item),
|
|
577
|
+
},
|
|
566
578
|
{
|
|
567
579
|
id: 'insert-cross-reference',
|
|
568
580
|
label: 'Cross-reference',
|
package/dist/es/versions.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '3.19.
|
|
1
|
+
export const VERSION = '3.19.1';
|
|
2
2
|
export const MATHJAX_VERSION = '3.2.2';
|
|
@@ -17,13 +17,13 @@ import { BibliographyItemAttrs } from '@manuscripts/transform';
|
|
|
17
17
|
import React, { MutableRefObject } from 'react';
|
|
18
18
|
export interface ReferenceFormActions {
|
|
19
19
|
reset: () => void;
|
|
20
|
+
submit: () => void;
|
|
21
|
+
isDirty: () => boolean;
|
|
20
22
|
}
|
|
23
|
+
export declare const validateReference: (values: BibliographyItemAttrs) => Partial<BibliographyItemAttrs>;
|
|
21
24
|
export declare const ReferenceForm: React.FC<{
|
|
22
25
|
values: BibliographyItemAttrs;
|
|
23
|
-
showDelete: boolean;
|
|
24
26
|
onChange: (values: BibliographyItemAttrs) => void;
|
|
25
|
-
onCancel: () => void;
|
|
26
|
-
onDelete: () => void;
|
|
27
27
|
onSave: (values: BibliographyItemAttrs) => void;
|
|
28
28
|
actionsRef?: MutableRefObject<ReferenceFormActions | undefined>;
|
|
29
29
|
}>;
|
|
@@ -243,7 +243,6 @@ export declare const Button: import("styled-components/dist/types").IStyledCompo
|
|
|
243
243
|
as?: import("styled-components").WebTarget | undefined;
|
|
244
244
|
forwardedAs?: import("styled-components").WebTarget | undefined;
|
|
245
245
|
}, "$defaultColor" | "$size">>> & string;
|
|
246
|
-
export declare const Actions: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
|
|
247
246
|
export declare const ReferenceTextField: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("styled-components").FastOmit<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, keyof import("@manuscripts/style-guide").TextFieldProps> & import("@manuscripts/style-guide").TextFieldProps, never> & Partial<Pick<import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, keyof import("@manuscripts/style-guide").TextFieldProps> & import("@manuscripts/style-guide").TextFieldProps, never>>, "as" | "forwardedAs"> & {
|
|
248
247
|
as?: import("styled-components").WebTarget | undefined;
|
|
249
248
|
forwardedAs?: import("styled-components").WebTarget | undefined;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { BibliographyItemAttrs } from '@manuscripts/transform';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { ReferencesModalProps } from './ReferencesModal';
|
|
4
|
+
import { EditorState, Transaction } from 'prosemirror-state';
|
|
5
|
+
import { EditorView } from 'prosemirror-view';
|
|
4
6
|
export type ReferencesEditorProps = Omit<ReferencesModalProps, 'isOpen' | 'onCancel' | 'handleImport' | 'onSave'> & {
|
|
5
7
|
onSave: (item: BibliographyItemAttrs[]) => void;
|
|
6
8
|
};
|
|
7
9
|
export declare const ReferencesEditor: React.FC<ReferencesEditorProps>;
|
|
10
|
+
export declare const openReferencesEditor: (state: EditorState, _?: (tr: Transaction) => void, view?: EditorView) => boolean;
|
package/dist/types/versions.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "3.19.
|
|
1
|
+
export declare const VERSION = "3.19.1";
|
|
2
2
|
export declare const MATHJAX_VERSION = "3.2.2";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manuscripts/body-editor",
|
|
3
3
|
"description": "Prosemirror components for editing and viewing manuscripts",
|
|
4
|
-
"version": "3.19.
|
|
4
|
+
"version": "3.19.1",
|
|
5
5
|
"repository": "github:Atypon-OpenSource/manuscripts-body-editor",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "dist/cjs",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@citation-js/plugin-pubmed": "0.3.0",
|
|
42
42
|
"@citation-js/plugin-ris": "0.7.18",
|
|
43
43
|
"@iarna/word-count": "1.1.2",
|
|
44
|
-
"@manuscripts/style-guide": "3.8.
|
|
44
|
+
"@manuscripts/style-guide": "3.8.1",
|
|
45
45
|
"@manuscripts/track-changes-plugin": "2.4.0",
|
|
46
46
|
"@manuscripts/transform": "4.5.7",
|
|
47
47
|
"@popperjs/core": "2.11.8",
|
|
@@ -16,15 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import {
|
|
18
18
|
AddAuthorIcon,
|
|
19
|
-
ButtonGroup,
|
|
20
|
-
Category,
|
|
21
|
-
DeleteIcon,
|
|
22
|
-
Dialog,
|
|
23
|
-
IconButton,
|
|
24
|
-
LinkIcon,
|
|
25
19
|
OptionType,
|
|
26
|
-
PrimaryButton,
|
|
27
|
-
SecondaryButton,
|
|
28
20
|
SelectField,
|
|
29
21
|
Label,
|
|
30
22
|
FormRow,
|
|
@@ -42,9 +34,7 @@ import { shouldRenderField } from '../../../lib/utils'
|
|
|
42
34
|
import { ChangeHandlingForm } from '../../ChangeHandlingForm'
|
|
43
35
|
import { PersonDropDown } from './PersonDropDown'
|
|
44
36
|
import {
|
|
45
|
-
Actions,
|
|
46
37
|
Button,
|
|
47
|
-
DeleteButton,
|
|
48
38
|
FormFields,
|
|
49
39
|
ReferenceTextArea,
|
|
50
40
|
ReferenceTextField,
|
|
@@ -58,22 +48,33 @@ const bibliographyItemTypeOptions: OptionType[] = bibliographyItemTypes.map(
|
|
|
58
48
|
)
|
|
59
49
|
export interface ReferenceFormActions {
|
|
60
50
|
reset: () => void
|
|
51
|
+
submit: () => void
|
|
52
|
+
isDirty: () => boolean
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const validateReference = (values: BibliographyItemAttrs) => {
|
|
56
|
+
const errors: Partial<BibliographyItemAttrs> = {}
|
|
57
|
+
|
|
58
|
+
if (values.type === 'literal') {
|
|
59
|
+
if (!values.literal?.trim()) {
|
|
60
|
+
errors.literal = 'Literal is required for unstructured references'
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
if (!values.title?.trim()) {
|
|
64
|
+
errors.title = 'Title is required'
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return errors
|
|
61
68
|
}
|
|
62
69
|
|
|
63
70
|
export const ReferenceForm: React.FC<{
|
|
64
71
|
values: BibliographyItemAttrs
|
|
65
|
-
showDelete: boolean
|
|
66
72
|
onChange: (values: BibliographyItemAttrs) => void
|
|
67
|
-
onCancel: () => void
|
|
68
|
-
onDelete: () => void
|
|
69
73
|
onSave: (values: BibliographyItemAttrs) => void
|
|
70
74
|
actionsRef?: MutableRefObject<ReferenceFormActions | undefined>
|
|
71
75
|
}> = ({
|
|
72
76
|
values,
|
|
73
|
-
showDelete,
|
|
74
77
|
onChange,
|
|
75
|
-
onDelete,
|
|
76
|
-
onCancel,
|
|
77
78
|
onSave,
|
|
78
79
|
actionsRef,
|
|
79
80
|
}) => {
|
|
@@ -88,28 +89,15 @@ export const ReferenceForm: React.FC<{
|
|
|
88
89
|
}
|
|
89
90
|
}, [values])
|
|
90
91
|
|
|
91
|
-
const [showDeleteDialog, setShowDeleteDialog] = useState(false)
|
|
92
|
-
|
|
93
|
-
const validateReference = (values: BibliographyItemAttrs) => {
|
|
94
|
-
const errors: Partial<BibliographyItemAttrs> = {}
|
|
95
|
-
|
|
96
|
-
if (values.type === 'literal') {
|
|
97
|
-
if (!values.literal?.trim()) {
|
|
98
|
-
errors.literal = 'Literal is required for unstructured references'
|
|
99
|
-
}
|
|
100
|
-
} else {
|
|
101
|
-
if (!values.title?.trim()) {
|
|
102
|
-
errors.title = 'Title is required'
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return errors
|
|
106
|
-
}
|
|
107
|
-
|
|
108
92
|
if (actionsRef && !actionsRef.current) {
|
|
109
93
|
actionsRef.current = {
|
|
110
94
|
reset: () => {
|
|
111
95
|
formRef.current?.resetForm()
|
|
112
96
|
},
|
|
97
|
+
submit: () => {
|
|
98
|
+
formRef.current?.submitForm()
|
|
99
|
+
},
|
|
100
|
+
isDirty: () => formRef.current?.dirty ?? false,
|
|
113
101
|
}
|
|
114
102
|
}
|
|
115
103
|
|
|
@@ -124,55 +112,6 @@ export const ReferenceForm: React.FC<{
|
|
|
124
112
|
{(formik) => {
|
|
125
113
|
return (
|
|
126
114
|
<ChangeHandlingForm onChange={onChange}>
|
|
127
|
-
<Dialog
|
|
128
|
-
isOpen={showDeleteDialog}
|
|
129
|
-
category={Category.confirmation}
|
|
130
|
-
header="Delete Reference"
|
|
131
|
-
message="Are you sure you want to delete this reference from the list?"
|
|
132
|
-
actions={{
|
|
133
|
-
secondary: {
|
|
134
|
-
action: () => {
|
|
135
|
-
onDelete()
|
|
136
|
-
setShowDeleteDialog(false)
|
|
137
|
-
},
|
|
138
|
-
title: 'Delete',
|
|
139
|
-
},
|
|
140
|
-
primary: {
|
|
141
|
-
action: () => setShowDeleteDialog(false),
|
|
142
|
-
title: 'Cancel',
|
|
143
|
-
},
|
|
144
|
-
}}
|
|
145
|
-
/>
|
|
146
|
-
<Actions>
|
|
147
|
-
<ButtonGroup>
|
|
148
|
-
<IconButton
|
|
149
|
-
as="a"
|
|
150
|
-
href={`https://doi.org/${formik.values.DOI}`}
|
|
151
|
-
target={'_blank'}
|
|
152
|
-
>
|
|
153
|
-
<LinkIcon />
|
|
154
|
-
</IconButton>
|
|
155
|
-
<DeleteButton
|
|
156
|
-
$defaultColor
|
|
157
|
-
disabled={!showDelete}
|
|
158
|
-
data-tooltip-content="Unable to delete because the item is used in the document"
|
|
159
|
-
data-tooltip-hidden={showDelete}
|
|
160
|
-
onClick={() => setShowDeleteDialog(true)}
|
|
161
|
-
>
|
|
162
|
-
<DeleteIcon />
|
|
163
|
-
</DeleteButton>
|
|
164
|
-
</ButtonGroup>
|
|
165
|
-
<ButtonGroup>
|
|
166
|
-
<SecondaryButton onClick={onCancel}>Cancel</SecondaryButton>
|
|
167
|
-
<PrimaryButton
|
|
168
|
-
type="submit"
|
|
169
|
-
disabled={!formik.isValid || !formik.dirty}
|
|
170
|
-
>
|
|
171
|
-
Save
|
|
172
|
-
</PrimaryButton>
|
|
173
|
-
</ButtonGroup>
|
|
174
|
-
</Actions>
|
|
175
|
-
|
|
176
115
|
<FormFields ref={fieldsRef}>
|
|
177
116
|
<FormRow>
|
|
178
117
|
<Label htmlFor={'citation-item-type'}>Type</Label>
|
|
@@ -37,19 +37,6 @@ export const Button = styled(IconButton).attrs({
|
|
|
37
37
|
}
|
|
38
38
|
`
|
|
39
39
|
|
|
40
|
-
export const Actions = styled.div`
|
|
41
|
-
flex-shrink: 1;
|
|
42
|
-
display: flex;
|
|
43
|
-
justify-content: space-between;
|
|
44
|
-
align-items: center;
|
|
45
|
-
|
|
46
|
-
.tooltip {
|
|
47
|
-
max-width: ${(props) => props.theme.grid.unit * 39}px;
|
|
48
|
-
padding: ${(props) => props.theme.grid.unit * 2}px;
|
|
49
|
-
border-radius: 6px;
|
|
50
|
-
}
|
|
51
|
-
`
|
|
52
|
-
|
|
53
40
|
export const ReferenceTextField = styled(TextField)`
|
|
54
41
|
padding: ${(props) => props.theme.grid.unit * 2}px
|
|
55
42
|
${(props) => props.theme.grid.unit * 3}px;
|
|
@@ -23,6 +23,12 @@ import React, { useEffect, useReducer, useState } from 'react'
|
|
|
23
23
|
import { attrsReducer } from '../../lib/array-reducer'
|
|
24
24
|
import { cleanItemValues } from '../../lib/utils'
|
|
25
25
|
import { ReferencesModal, ReferencesModalProps } from './ReferencesModal'
|
|
26
|
+
import { getEditorProps } from '../../plugins/editor-props'
|
|
27
|
+
import { deleteNode, saveBibliographyItem } from '../../lib/view'
|
|
28
|
+
import ReactSubView from '../../views/ReactSubView'
|
|
29
|
+
import { EditorState, Transaction } from 'prosemirror-state'
|
|
30
|
+
import { EditorView } from 'prosemirror-view'
|
|
31
|
+
import { getBibliographyPluginState } from '../../plugins/bibliography'
|
|
26
32
|
|
|
27
33
|
export type ReferencesEditorProps = Omit<
|
|
28
34
|
ReferencesModalProps,
|
|
@@ -88,3 +94,35 @@ export const ReferencesEditor: React.FC<ReferencesEditorProps> = (props) => {
|
|
|
88
94
|
/>
|
|
89
95
|
)
|
|
90
96
|
}
|
|
97
|
+
|
|
98
|
+
export const openReferencesEditor = (
|
|
99
|
+
state: EditorState,
|
|
100
|
+
_?: (tr: Transaction) => void,
|
|
101
|
+
view?: EditorView
|
|
102
|
+
) => {
|
|
103
|
+
if (!view) {
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const props = getEditorProps(state)
|
|
108
|
+
const bib = getBibliographyPluginState(view.state)
|
|
109
|
+
|
|
110
|
+
const componentProps: ReferencesEditorProps = {
|
|
111
|
+
items: bib ? Array.from(bib.bibliographyItems.values()) : [],
|
|
112
|
+
citationCounts: new Map<string, number>(bib?.citationCounts),
|
|
113
|
+
onDelete: (item) => deleteNode(view, item.id),
|
|
114
|
+
onSave: (item) => saveBibliographyItem(view, item),
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const referencesEditor = ReactSubView(
|
|
118
|
+
props,
|
|
119
|
+
ReferencesEditor,
|
|
120
|
+
componentProps,
|
|
121
|
+
state.doc,
|
|
122
|
+
() => 0,
|
|
123
|
+
view
|
|
124
|
+
)
|
|
125
|
+
view.focus()
|
|
126
|
+
document.body.appendChild(referencesEditor)
|
|
127
|
+
return true
|
|
128
|
+
}
|