@manuscripts/body-editor 3.16.0 → 3.16.2
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/commands.js +45 -10
- package/dist/cjs/components/form/FormFooter.js +2 -2
- package/dist/cjs/components/keyboard-shortcuts-modal/KeyboardShortcutsModal.js +4 -2
- package/dist/cjs/components/references/CitationEditor.js +13 -19
- package/dist/cjs/components/references/ImportBibliography.js +77 -0
- package/dist/cjs/components/references/ImportBibliographyForm.js +1 -1
- package/dist/cjs/components/references/ImportBibliographyModal.js +12 -81
- package/dist/cjs/components/references/ImportReferencesConfirmation.js +113 -0
- package/dist/cjs/components/references/ImportSuccessPlaceholder.js +56 -0
- package/dist/cjs/components/references/ReferenceSearch.js +2 -5
- package/dist/cjs/components/references/ReferencesEditor.js +18 -2
- package/dist/cjs/components/references/ReferencesModal.js +86 -33
- package/dist/cjs/components/views/CrossReferenceItems.js +139 -52
- package/dist/cjs/components/views/DeleteSupplementDialog.js +1 -1
- package/dist/cjs/lib/supplements.js +9 -1
- package/dist/cjs/lib/view.js +39 -1
- package/dist/cjs/menus.js +35 -0
- package/dist/cjs/plugins/objects.js +1 -1
- package/dist/cjs/toolbar.js +6 -0
- package/dist/cjs/versions.js +1 -1
- package/dist/cjs/views/bibliography_element.js +1 -2
- package/dist/cjs/views/citation_editable.js +2 -29
- package/dist/cjs/views/cross_reference.js +12 -2
- package/dist/cjs/views/cross_reference_editable.js +95 -4
- package/dist/cjs/views/figure_editable.js +3 -0
- package/dist/es/commands.js +43 -9
- package/dist/es/components/form/FormFooter.js +2 -2
- package/dist/es/components/keyboard-shortcuts-modal/KeyboardShortcutsModal.js +4 -2
- package/dist/es/components/references/CitationEditor.js +13 -19
- package/dist/es/components/references/ImportBibliography.js +70 -0
- package/dist/es/components/references/ImportBibliographyForm.js +1 -1
- package/dist/es/components/references/ImportBibliographyModal.js +13 -79
- package/dist/es/components/references/ImportReferencesConfirmation.js +73 -0
- package/dist/es/components/references/ImportSuccessPlaceholder.js +49 -0
- package/dist/es/components/references/ReferenceSearch.js +3 -6
- package/dist/es/components/references/ReferencesEditor.js +19 -3
- package/dist/es/components/references/ReferencesModal.js +88 -35
- package/dist/es/components/views/CrossReferenceItems.js +141 -54
- package/dist/es/components/views/DeleteSupplementDialog.js +2 -2
- package/dist/es/lib/supplements.js +8 -1
- package/dist/es/lib/view.js +36 -0
- package/dist/es/menus.js +36 -1
- package/dist/es/plugins/objects.js +1 -1
- package/dist/es/toolbar.js +8 -2
- package/dist/es/versions.js +1 -1
- package/dist/es/views/bibliography_element.js +2 -3
- package/dist/es/views/citation_editable.js +3 -30
- package/dist/es/views/cross_reference.js +12 -2
- package/dist/es/views/cross_reference_editable.js +96 -5
- package/dist/es/views/figure_editable.js +3 -0
- package/dist/types/commands.d.ts +1 -0
- package/dist/types/components/form/FormFooter.d.ts +2 -1
- package/dist/types/components/references/CitationEditor.d.ts +1 -1
- package/dist/types/components/references/ImportBibliography.d.ts +7 -0
- package/dist/types/components/references/ImportReferencesConfirmation.d.ts +8 -0
- package/dist/types/components/references/ImportSuccessPlaceholder.d.ts +5 -0
- package/dist/types/components/references/ReferenceSearch.d.ts +0 -1
- package/dist/types/components/references/ReferencesEditor.d.ts +4 -1
- package/dist/types/components/references/ReferencesModal.d.ts +1 -0
- package/dist/types/components/views/CrossReferenceItems.d.ts +3 -0
- package/dist/types/lib/supplements.d.ts +1 -0
- package/dist/types/lib/view.d.ts +3 -1
- package/dist/types/versions.d.ts +1 -1
- package/dist/types/views/citation_editable.d.ts +0 -1
- package/dist/types/views/cross_reference_editable.d.ts +6 -0
- package/package.json +4 -4
- package/src/commands.ts +52 -10
- package/src/components/ChangeHandlingForm.tsx +4 -2
- package/src/components/form/FormFooter.tsx +3 -1
- package/src/components/keyboard-shortcuts-modal/KeyboardShortcutsModal.tsx +6 -7
- package/src/components/references/CitationEditor.tsx +16 -25
- package/src/components/references/ImportBibliography.tsx +119 -0
- package/src/components/references/ImportBibliographyForm.tsx +1 -1
- package/src/components/references/ImportBibliographyModal.tsx +34 -110
- package/src/components/references/ImportReferencesConfirmation.tsx +133 -0
- package/src/components/references/ImportSuccessPlaceholder.tsx +93 -0
- package/src/components/references/ReferenceSearch.tsx +0 -7
- package/src/components/references/ReferencesEditor.tsx +35 -6
- package/src/components/references/ReferencesModal.tsx +164 -78
- package/src/components/toolbar/InsertEmbedDialog.tsx +6 -2
- package/src/components/toolbar/type-selector/styles.ts +2 -1
- package/src/components/views/CrossReferenceItems.tsx +227 -100
- package/src/components/views/DeleteSupplementDialog.tsx +3 -6
- package/src/lib/footnotes.ts +3 -1
- package/src/lib/supplements.ts +13 -1
- package/src/lib/utils.ts +15 -4
- package/src/lib/view.ts +65 -0
- package/src/menus.tsx +39 -0
- package/src/plugins/add-subtitle.ts +18 -16
- package/src/plugins/objects.ts +2 -6
- package/src/toolbar.tsx +9 -0
- package/src/versions.ts +1 -1
- package/src/views/bibliography_element.ts +3 -4
- package/src/views/citation_editable.ts +5 -50
- package/src/views/cross_reference.ts +17 -3
- package/src/views/cross_reference_editable.ts +123 -11
- package/src/views/figure_editable.ts +4 -0
- package/src/views/supplement.ts +0 -1
- package/src/views/supplements.ts +2 -2
package/src/commands.ts
CHANGED
|
@@ -14,7 +14,11 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
isDeleted,
|
|
19
|
+
skipTracking,
|
|
20
|
+
skipSelect,
|
|
21
|
+
} from '@manuscripts/track-changes-plugin'
|
|
18
22
|
import {
|
|
19
23
|
AttachmentNode,
|
|
20
24
|
AwardNode,
|
|
@@ -525,7 +529,7 @@ export const insertSupplementWeblink = (
|
|
|
525
529
|
const supplement = schema.nodes.supplement.createAndFill(
|
|
526
530
|
{
|
|
527
531
|
id: generateNodeID(schema.nodes.supplement),
|
|
528
|
-
href: url
|
|
532
|
+
href: url,
|
|
529
533
|
},
|
|
530
534
|
createAndFillCaption()
|
|
531
535
|
) as SupplementNode
|
|
@@ -554,7 +558,7 @@ export const updateSupplementWeblink = (
|
|
|
554
558
|
...node.attrs,
|
|
555
559
|
href: url,
|
|
556
560
|
title: title,
|
|
557
|
-
|
|
561
|
+
})
|
|
558
562
|
view.dispatch(tr)
|
|
559
563
|
return true
|
|
560
564
|
}
|
|
@@ -782,21 +786,62 @@ export const insertInlineCitation = (
|
|
|
782
786
|
return true
|
|
783
787
|
}
|
|
784
788
|
|
|
789
|
+
export const canInsertCrossReference = (
|
|
790
|
+
state: ManuscriptEditorState
|
|
791
|
+
): boolean => {
|
|
792
|
+
if (!canInsert(schema.nodes.cross_reference)(state)) {
|
|
793
|
+
return false
|
|
794
|
+
}
|
|
795
|
+
const { from, to, empty, $from, $to } = state.selection
|
|
796
|
+
if (empty) {
|
|
797
|
+
return true
|
|
798
|
+
}
|
|
799
|
+
if (!$from.sameParent($to)) {
|
|
800
|
+
return false
|
|
801
|
+
}
|
|
802
|
+
let overlaps = false
|
|
803
|
+
state.doc.nodesBetween(from, to, (node) => {
|
|
804
|
+
if (node.isAtom && !node.isText) {
|
|
805
|
+
overlaps = true
|
|
806
|
+
return false
|
|
807
|
+
}
|
|
808
|
+
return !overlaps
|
|
809
|
+
})
|
|
810
|
+
return !overlaps
|
|
811
|
+
}
|
|
812
|
+
|
|
785
813
|
export const insertCrossReference = (
|
|
786
814
|
state: ManuscriptEditorState,
|
|
787
815
|
dispatch?: Dispatch
|
|
788
816
|
) => {
|
|
817
|
+
if (!canInsertCrossReference(state)) {
|
|
818
|
+
return false
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
const text = selectedText()
|
|
822
|
+
|
|
789
823
|
const node = state.schema.nodes.cross_reference.create({
|
|
824
|
+
id: generateNodeID(schema.nodes.cross_reference),
|
|
790
825
|
rids: [],
|
|
826
|
+
label: text,
|
|
791
827
|
})
|
|
792
828
|
|
|
793
|
-
const
|
|
829
|
+
const { tr } = state
|
|
830
|
+
let pos: number
|
|
831
|
+
const isWrap = !state.selection.empty
|
|
794
832
|
|
|
795
|
-
|
|
833
|
+
if (isWrap) {
|
|
834
|
+
pos = state.selection.from
|
|
835
|
+
tr.replaceSelectionWith(node)
|
|
836
|
+
} else {
|
|
837
|
+
pos = state.selection.to
|
|
838
|
+
tr.insert(pos, node)
|
|
839
|
+
}
|
|
796
840
|
|
|
797
841
|
if (dispatch) {
|
|
798
842
|
const selection = NodeSelection.create(tr.doc, pos)
|
|
799
|
-
|
|
843
|
+
tr.setSelection(selection).scrollIntoView()
|
|
844
|
+
dispatch(isWrap ? skipTracking(tr) : tr)
|
|
800
845
|
}
|
|
801
846
|
|
|
802
847
|
return true
|
|
@@ -1524,10 +1569,7 @@ export const insertTransGraphicalAbstract =
|
|
|
1524
1569
|
lang,
|
|
1525
1570
|
category: category.id,
|
|
1526
1571
|
},
|
|
1527
|
-
[
|
|
1528
|
-
schema.nodes.section_title.create(),
|
|
1529
|
-
createAndFillFigureElement(state),
|
|
1530
|
-
]
|
|
1572
|
+
[schema.nodes.section_title.create(), createAndFillFigureElement(state)]
|
|
1531
1573
|
) as TransGraphicalAbstractNode
|
|
1532
1574
|
|
|
1533
1575
|
const tr = state.tr.insert(pos, node)
|
|
@@ -17,8 +17,10 @@ import { Form, useFormikContext } from 'formik'
|
|
|
17
17
|
import React, { MutableRefObject, PropsWithChildren, useEffect } from 'react'
|
|
18
18
|
import styled from 'styled-components'
|
|
19
19
|
|
|
20
|
-
export interface ChangeHandlingFormProps<Values>
|
|
21
|
-
|
|
20
|
+
export interface ChangeHandlingFormProps<Values> extends Omit<
|
|
21
|
+
React.FormHTMLAttributes<HTMLFormElement>,
|
|
22
|
+
'onChange'
|
|
23
|
+
> {
|
|
22
24
|
onChange: (values: Values) => void
|
|
23
25
|
id?: string
|
|
24
26
|
formRef?: MutableRefObject<HTMLFormElement | null>
|
|
@@ -37,14 +37,16 @@ const StyledIconTextButton = styled(IconTextButton)`
|
|
|
37
37
|
const FormFooter = ({
|
|
38
38
|
onCancel,
|
|
39
39
|
primaryAction,
|
|
40
|
+
cancelLabel = 'Close',
|
|
40
41
|
}: {
|
|
41
42
|
onCancel: () => void
|
|
42
43
|
primaryAction?: React.ReactNode
|
|
44
|
+
cancelLabel?: string
|
|
43
45
|
}) => {
|
|
44
46
|
return (
|
|
45
47
|
<Footer>
|
|
46
48
|
<StyledIconTextButton color="secondary" onClick={onCancel}>
|
|
47
|
-
|
|
49
|
+
{cancelLabel}
|
|
48
50
|
</StyledIconTextButton>
|
|
49
51
|
{primaryAction}
|
|
50
52
|
</Footer>
|
|
@@ -86,14 +86,11 @@ export const KeyboardShortcutsModal: React.FC<KeyboardShortcutsModalProps> = ({
|
|
|
86
86
|
</StyledModalSidebarTitle>
|
|
87
87
|
</StyledModalSidebarHeader>
|
|
88
88
|
<StyledSidebarContent>
|
|
89
|
-
<ShortcutTabs
|
|
90
|
-
selectedIndex={tabIndex}
|
|
91
|
-
onChange={setTabIndex}
|
|
92
|
-
>
|
|
89
|
+
<ShortcutTabs selectedIndex={tabIndex} onChange={setTabIndex}>
|
|
93
90
|
<ModalTabsWrapper>
|
|
94
91
|
<ModalTabs tabLabels={TAB_LABELS} />
|
|
95
92
|
</ModalTabsWrapper>
|
|
96
|
-
|
|
93
|
+
|
|
97
94
|
<InspectorTabPanels>
|
|
98
95
|
{EDITOR_KEYBOARD_SHORTCUT_TABS.map((tab) => (
|
|
99
96
|
<ShortcutTabPanel key={tab.id}>
|
|
@@ -139,7 +136,8 @@ const ShortcutTabs = styled(InspectorTabs)`
|
|
|
139
136
|
`
|
|
140
137
|
|
|
141
138
|
const ModalTabsWrapper = styled('div')`
|
|
142
|
-
margin: 0 ${(props) => props.theme.grid.unit * 8}px
|
|
139
|
+
margin: 0 ${(props) => props.theme.grid.unit * 8}px
|
|
140
|
+
${(props) => props.theme.grid.unit * 3}px;
|
|
143
141
|
`
|
|
144
142
|
|
|
145
143
|
const ShortcutTabPanel = styled(InspectorTabPanel).attrs({
|
|
@@ -198,7 +196,8 @@ const Section = styled.section`
|
|
|
198
196
|
`
|
|
199
197
|
|
|
200
198
|
const SectionTitle = styled.h3`
|
|
201
|
-
margin: 0 ${(props) => props.theme.grid.unit * 8}px
|
|
199
|
+
margin: 0 ${(props) => props.theme.grid.unit * 8}px
|
|
200
|
+
${(props) => props.theme.grid.unit * 2}px;
|
|
202
201
|
font-size: ${(props) => props.theme.font.size.large};
|
|
203
202
|
font-weight: ${(props) => props.theme.font.weight.normal};
|
|
204
203
|
line-height: ${(props) => props.theme.font.lineHeight.large};
|
|
@@ -36,7 +36,6 @@ import { arrayReducer, attrsReducer } from '../../lib/array-reducer'
|
|
|
36
36
|
import { cleanItemValues } from '../../lib/utils'
|
|
37
37
|
import { BibliographyItemSource } from './BibliographyItemSource'
|
|
38
38
|
import { CitedItem, CitedItems } from './CitationViewer'
|
|
39
|
-
import { ImportBibliographyModal } from './ImportBibliographyModal'
|
|
40
39
|
import { ReferenceLine } from './ReferenceLine'
|
|
41
40
|
import { ReferenceSearch } from './ReferenceSearch'
|
|
42
41
|
import { ReferencesModal } from './ReferencesModal'
|
|
@@ -92,7 +91,7 @@ export interface CitationEditorProps {
|
|
|
92
91
|
sources: BibliographyItemSource[]
|
|
93
92
|
onCite: (items: BibliographyItemAttrs[]) => void
|
|
94
93
|
onUncite: (id: string) => void
|
|
95
|
-
onSave: (item: BibliographyItemAttrs) => void
|
|
94
|
+
onSave: (item: BibliographyItemAttrs[]) => void
|
|
96
95
|
onDelete: (item: BibliographyItemAttrs) => void
|
|
97
96
|
onCancel: () => void
|
|
98
97
|
canEdit: boolean
|
|
@@ -118,7 +117,7 @@ export const CitationEditor: React.FC<CitationEditorProps> = ({
|
|
|
118
117
|
const [rids, dispatchRids] = useReducer(ridsReducer, $rids)
|
|
119
118
|
const handleSave = (item: BibliographyItemAttrs) => {
|
|
120
119
|
const cleanedItem = cleanItemValues(item)
|
|
121
|
-
onSave(cleanedItem)
|
|
120
|
+
onSave([cleanedItem])
|
|
122
121
|
dispatchItems({
|
|
123
122
|
type: 'update',
|
|
124
123
|
items: [cleanedItem],
|
|
@@ -163,7 +162,6 @@ export const CitationEditor: React.FC<CitationEditorProps> = ({
|
|
|
163
162
|
})
|
|
164
163
|
|
|
165
164
|
const [searching, setSearching] = useState(false)
|
|
166
|
-
const [importing, setImporting] = useState(false)
|
|
167
165
|
|
|
168
166
|
const handleAdd = () => {
|
|
169
167
|
setSearching(false)
|
|
@@ -178,16 +176,19 @@ export const CitationEditor: React.FC<CitationEditorProps> = ({
|
|
|
178
176
|
setEditingForm({ show: true, item: item })
|
|
179
177
|
}
|
|
180
178
|
|
|
181
|
-
const handleImport = () => {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
179
|
+
const handleImport = (data: BibliographyItemAttrs[]) => {
|
|
180
|
+
const newItems = data.map((item) =>
|
|
181
|
+
cleanItemValues({
|
|
182
|
+
...item,
|
|
183
|
+
id: generateNodeID(schema.nodes.bibliography_item),
|
|
184
|
+
})
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
onSave(newItems)
|
|
188
|
+
|
|
189
|
+
dispatchItems({
|
|
190
|
+
type: 'set',
|
|
191
|
+
state: [...items, ...newItems],
|
|
191
192
|
})
|
|
192
193
|
}
|
|
193
194
|
|
|
@@ -205,15 +206,7 @@ export const CitationEditor: React.FC<CitationEditorProps> = ({
|
|
|
205
206
|
item={editingForm.item}
|
|
206
207
|
onSave={handleSave}
|
|
207
208
|
onDelete={handleDelete}
|
|
208
|
-
|
|
209
|
-
)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (importing) {
|
|
213
|
-
return (
|
|
214
|
-
<ImportBibliographyModal
|
|
215
|
-
onCancel={() => setImporting(false)}
|
|
216
|
-
onSave={handleSaveImport}
|
|
209
|
+
handleImport={handleImport}
|
|
217
210
|
/>
|
|
218
211
|
)
|
|
219
212
|
}
|
|
@@ -223,7 +216,6 @@ export const CitationEditor: React.FC<CitationEditorProps> = ({
|
|
|
223
216
|
sources={sources}
|
|
224
217
|
items={items}
|
|
225
218
|
onAdd={handleAdd}
|
|
226
|
-
onImport={handleImport}
|
|
227
219
|
onCite={(items) => {
|
|
228
220
|
setSearching(false)
|
|
229
221
|
handleCite(items)
|
|
@@ -239,7 +231,6 @@ export const CitationEditor: React.FC<CitationEditorProps> = ({
|
|
|
239
231
|
sources={sources}
|
|
240
232
|
items={items}
|
|
241
233
|
onAdd={handleAdd}
|
|
242
|
-
onImport={handleImport}
|
|
243
234
|
onCite={handleCite}
|
|
244
235
|
onCancel={onCancel}
|
|
245
236
|
/>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2026 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { ModalTitle, Tooltip } from '@manuscripts/style-guide'
|
|
17
|
+
import { BibliographyItemAttrs } from '@manuscripts/transform'
|
|
18
|
+
import React from 'react'
|
|
19
|
+
import styled from 'styled-components'
|
|
20
|
+
|
|
21
|
+
import { ImportBibliographyForm } from './ImportBibliographyForm'
|
|
22
|
+
|
|
23
|
+
const exampleBibtex = `@book{abramowitz+stegun,
|
|
24
|
+
author = "Milton {Abramowitz} and Irene A. {Stegun}",
|
|
25
|
+
title = "Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables",
|
|
26
|
+
publisher = "Dover",
|
|
27
|
+
year = 1964,
|
|
28
|
+
address = "New York City",
|
|
29
|
+
edition = "ninth Dover printing, tenth GPO printing"
|
|
30
|
+
}`
|
|
31
|
+
|
|
32
|
+
const examplePubmed = `Example Identifiers:
|
|
33
|
+
pmid:17170128
|
|
34
|
+
PMC1852221`
|
|
35
|
+
|
|
36
|
+
const exampleRis = `TY - JOUR
|
|
37
|
+
AU - Shannon, Claude E.
|
|
38
|
+
PY - 1948
|
|
39
|
+
DA - July
|
|
40
|
+
TI - A Mathematical Theory of Communication
|
|
41
|
+
T2 - Bell System Technical Journal
|
|
42
|
+
SP - 379
|
|
43
|
+
EP - 423
|
|
44
|
+
VL - 27
|
|
45
|
+
ER - `
|
|
46
|
+
|
|
47
|
+
const exampleEnw = `%0 Journal Article
|
|
48
|
+
%D 2018
|
|
49
|
+
%@ 0903-4641
|
|
50
|
+
%A Abbassi-Daloii, Tooba
|
|
51
|
+
%A Yousefi, Soheil
|
|
52
|
+
%A Sekhavati, Mohammad Hadi
|
|
53
|
+
%A Tahmoorespur, Mojtaba
|
|
54
|
+
%J APMIS
|
|
55
|
+
%N 1
|
|
56
|
+
%P 65-75
|
|
57
|
+
%T Impact of heat shock protein 60KD in combination with outer membrane proteins on immune response against Brucella melitensis
|
|
58
|
+
%R https://doi.org/10.1111/apm.12778
|
|
59
|
+
%U https://onlinelibrary.wiley.com/doi/abs/10.1111/apm.12778
|
|
60
|
+
%V 126
|
|
61
|
+
%X Lorem ipsum dolor sit amet`
|
|
62
|
+
|
|
63
|
+
const exampleDoi = `Example DOI Identifiers:
|
|
64
|
+
10.1080/15588742.2015.1017684
|
|
65
|
+
http://dx.doi.org/10.1080/15588742.2015.1017684`
|
|
66
|
+
|
|
67
|
+
const supportedFormats = [
|
|
68
|
+
{ label: 'BibTex', example: exampleBibtex },
|
|
69
|
+
{ label: 'PubMed', example: examplePubmed },
|
|
70
|
+
{ label: 'RIS', example: exampleRis },
|
|
71
|
+
{ label: 'ENW', example: exampleEnw },
|
|
72
|
+
{ label: 'DOI', example: exampleDoi },
|
|
73
|
+
] as const
|
|
74
|
+
|
|
75
|
+
export interface ImportBibliographyProps {
|
|
76
|
+
onCancel: () => void
|
|
77
|
+
onContinue: (data: BibliographyItemAttrs[]) => void
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const ImportBibliography: React.FC<ImportBibliographyProps> = ({
|
|
81
|
+
onCancel,
|
|
82
|
+
onContinue,
|
|
83
|
+
}) => (
|
|
84
|
+
<>
|
|
85
|
+
<ModalTitle>Import Bibliography</ModalTitle>
|
|
86
|
+
<p>
|
|
87
|
+
{supportedFormats.map(({ label, example }, index) => (
|
|
88
|
+
<React.Fragment key={label}>
|
|
89
|
+
{index > 0 &&
|
|
90
|
+
(index === supportedFormats.length - 1 ? ' and ' : ', ')}
|
|
91
|
+
<SpanWithExample
|
|
92
|
+
data-tooltip-id="import-example-tooltip"
|
|
93
|
+
data-tooltip-content={example}
|
|
94
|
+
>
|
|
95
|
+
{label}
|
|
96
|
+
</SpanWithExample>
|
|
97
|
+
</React.Fragment>
|
|
98
|
+
))}{' '}
|
|
99
|
+
formats are supported
|
|
100
|
+
</p>
|
|
101
|
+
<ImportBibliographyForm onCancel={onCancel} onSave={onContinue} />
|
|
102
|
+
<Example
|
|
103
|
+
id="import-example-tooltip"
|
|
104
|
+
place="bottom"
|
|
105
|
+
render={(s) => <pre>{s.content}</pre>}
|
|
106
|
+
/>
|
|
107
|
+
</>
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
const SpanWithExample = styled.span`
|
|
111
|
+
text-decoration: underline dotted;
|
|
112
|
+
text-underline-offset: 4px;
|
|
113
|
+
`
|
|
114
|
+
|
|
115
|
+
const Example = styled(Tooltip)`
|
|
116
|
+
text-align: left !important;
|
|
117
|
+
max-width: 480px !important;
|
|
118
|
+
overflow: hidden !important;
|
|
119
|
+
`
|
|
@@ -18,142 +18,66 @@ import {
|
|
|
18
18
|
ModalCardBody,
|
|
19
19
|
ModalContainer,
|
|
20
20
|
ModalHeader,
|
|
21
|
-
ModalTitle,
|
|
22
21
|
StyledModal,
|
|
23
|
-
Tooltip,
|
|
24
22
|
} from '@manuscripts/style-guide'
|
|
25
23
|
import { BibliographyItemAttrs } from '@manuscripts/transform'
|
|
26
24
|
import React, { useState } from 'react'
|
|
27
|
-
import styled from 'styled-components'
|
|
28
25
|
|
|
29
|
-
import {
|
|
26
|
+
import { ImportBibliography } from './ImportBibliography'
|
|
27
|
+
import { ImportReferencesConfirmation } from './ImportReferencesConfirmation'
|
|
28
|
+
|
|
30
29
|
export interface ImportBibliographyModalProps {
|
|
31
30
|
onCancel: () => void
|
|
32
31
|
onSave: (data: BibliographyItemAttrs[]) => void
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
const exampleBibtex = `@book{abramowitz+stegun,
|
|
36
|
-
author = "Milton {Abramowitz} and Irene A. {Stegun}",
|
|
37
|
-
title = "Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables",
|
|
38
|
-
publisher = "Dover",
|
|
39
|
-
year = 1964,
|
|
40
|
-
address = "New York City",
|
|
41
|
-
edition = "ninth Dover printing, tenth GPO printing"
|
|
42
|
-
}`
|
|
43
|
-
|
|
44
|
-
const examplePubmed = `Example Identifiers:
|
|
45
|
-
pmid:17170128
|
|
46
|
-
PMC1852221`
|
|
47
|
-
|
|
48
|
-
const exampleRis = `TY - JOUR
|
|
49
|
-
AU - Shannon, Claude E.
|
|
50
|
-
PY - 1948
|
|
51
|
-
DA - July
|
|
52
|
-
TI - A Mathematical Theory of Communication
|
|
53
|
-
T2 - Bell System Technical Journal
|
|
54
|
-
SP - 379
|
|
55
|
-
EP - 423
|
|
56
|
-
VL - 27
|
|
57
|
-
ER - `
|
|
58
|
-
|
|
59
|
-
const exampleEnw = `%0 Journal Article
|
|
60
|
-
%D 2018
|
|
61
|
-
%@ 0903-4641
|
|
62
|
-
%A Abbassi-Daloii, Tooba
|
|
63
|
-
%A Yousefi, Soheil
|
|
64
|
-
%A Sekhavati, Mohammad Hadi
|
|
65
|
-
%A Tahmoorespur, Mojtaba
|
|
66
|
-
%J APMIS
|
|
67
|
-
%N 1
|
|
68
|
-
%P 65-75
|
|
69
|
-
%T Impact of heat shock protein 60KD in combination with outer membrane proteins on immune response against Brucella melitensis
|
|
70
|
-
%R https://doi.org/10.1111/apm.12778
|
|
71
|
-
%U https://onlinelibrary.wiley.com/doi/abs/10.1111/apm.12778
|
|
72
|
-
%V 126
|
|
73
|
-
%X Lorem ipsum dolor sit amet`
|
|
74
|
-
|
|
75
|
-
const exampleDoi = `Example DOI Identifiers:
|
|
76
|
-
10.1080/15588742.2015.1017684
|
|
77
|
-
http://dx.doi.org/10.1080/15588742.2015.1017684`
|
|
78
|
-
|
|
79
34
|
export const ImportBibliographyModal: React.FC<
|
|
80
35
|
ImportBibliographyModalProps
|
|
81
36
|
> = ({ onCancel, onSave }) => {
|
|
82
37
|
const [isOpen, setOpen] = useState(true)
|
|
38
|
+
const [pendingItems, setPendingItems] = useState<
|
|
39
|
+
BibliographyItemAttrs[] | null
|
|
40
|
+
>(null)
|
|
83
41
|
|
|
84
|
-
const
|
|
85
|
-
handleClose()
|
|
86
|
-
}
|
|
42
|
+
const isConfirming = pendingItems !== null
|
|
87
43
|
const handleClose = () => setOpen(false)
|
|
44
|
+
const handleBack = () => setPendingItems(null)
|
|
88
45
|
|
|
89
|
-
const
|
|
90
|
-
onSave(
|
|
46
|
+
const handleConfirm = (items: BibliographyItemAttrs[]) => {
|
|
47
|
+
onSave(items)
|
|
91
48
|
handleClose()
|
|
92
49
|
}
|
|
93
50
|
|
|
94
51
|
return (
|
|
95
52
|
<StyledModal isOpen={isOpen} onRequestClose={onCancel}>
|
|
96
|
-
<ModalContainer
|
|
53
|
+
<ModalContainer
|
|
54
|
+
data-cy={
|
|
55
|
+
isConfirming
|
|
56
|
+
? 'import-confirmation-modal'
|
|
57
|
+
: 'import-bibliography-modal'
|
|
58
|
+
}
|
|
59
|
+
>
|
|
97
60
|
<ModalHeader>
|
|
98
|
-
<CloseButton
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<ModalTitle>Import Bibliography</ModalTitle>
|
|
102
|
-
<p>
|
|
103
|
-
<SpanWithExample
|
|
104
|
-
data-tooltip-id="import-example-tooltip"
|
|
105
|
-
data-tooltip-content={exampleBibtex}
|
|
106
|
-
>
|
|
107
|
-
BibTex
|
|
108
|
-
</SpanWithExample>
|
|
109
|
-
,{' '}
|
|
110
|
-
<SpanWithExample
|
|
111
|
-
data-tooltip-id="import-example-tooltip"
|
|
112
|
-
data-tooltip-content={examplePubmed}
|
|
113
|
-
>
|
|
114
|
-
PubMed
|
|
115
|
-
</SpanWithExample>
|
|
116
|
-
,{' '}
|
|
117
|
-
<SpanWithExample
|
|
118
|
-
data-tooltip-id="import-example-tooltip"
|
|
119
|
-
data-tooltip-content={exampleRis}
|
|
120
|
-
>
|
|
121
|
-
RIS
|
|
122
|
-
</SpanWithExample>
|
|
123
|
-
,{' '}
|
|
124
|
-
<SpanWithExample
|
|
125
|
-
data-tooltip-id="import-example-tooltip"
|
|
126
|
-
data-tooltip-content={exampleEnw}
|
|
127
|
-
>
|
|
128
|
-
ENW
|
|
129
|
-
</SpanWithExample>{' '}
|
|
130
|
-
and{' '}
|
|
131
|
-
<SpanWithExample
|
|
132
|
-
data-tooltip-id="import-example-tooltip"
|
|
133
|
-
data-tooltip-content={exampleDoi}
|
|
134
|
-
>
|
|
135
|
-
DOI
|
|
136
|
-
</SpanWithExample>{' '}
|
|
137
|
-
formats are supported
|
|
138
|
-
</p>
|
|
139
|
-
<ImportBibliographyForm onCancel={handleCancel} onSave={handleSave} />
|
|
140
|
-
<Example
|
|
141
|
-
id="import-example-tooltip"
|
|
142
|
-
place="bottom"
|
|
143
|
-
render={(s) => <pre>{s.content}</pre>}
|
|
61
|
+
<CloseButton
|
|
62
|
+
onClick={isConfirming ? handleBack : onCancel}
|
|
63
|
+
data-cy="modal-close-button"
|
|
144
64
|
/>
|
|
65
|
+
</ModalHeader>
|
|
66
|
+
<ModalCardBody $width={724}>
|
|
67
|
+
{pendingItems ? (
|
|
68
|
+
<ImportReferencesConfirmation
|
|
69
|
+
items={pendingItems}
|
|
70
|
+
onCancel={handleBack}
|
|
71
|
+
onConfirm={handleConfirm}
|
|
72
|
+
/>
|
|
73
|
+
) : (
|
|
74
|
+
<ImportBibliography
|
|
75
|
+
onCancel={onCancel}
|
|
76
|
+
onContinue={setPendingItems}
|
|
77
|
+
/>
|
|
78
|
+
)}
|
|
145
79
|
</ModalCardBody>
|
|
146
80
|
</ModalContainer>
|
|
147
81
|
</StyledModal>
|
|
148
82
|
)
|
|
149
83
|
}
|
|
150
|
-
|
|
151
|
-
const SpanWithExample = styled.span`
|
|
152
|
-
text-decoration: underline dotted;
|
|
153
|
-
text-underline-offset: 4px;
|
|
154
|
-
`
|
|
155
|
-
const Example = styled(Tooltip)`
|
|
156
|
-
text-align: left !important;
|
|
157
|
-
max-width: 480px !important;
|
|
158
|
-
overflow: hidden !important;
|
|
159
|
-
`
|