@manuscripts/body-editor 3.16.1 → 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/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/lib/view.js +39 -1
- 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/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/lib/view.js +36 -0
- 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/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/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/package.json +1 -1
- 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/lib/view.ts +65 -0
- package/src/versions.ts +1 -1
- package/src/views/bibliography_element.ts +3 -4
- package/src/views/citation_editable.ts +5 -50
|
@@ -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
|
-
`
|
|
@@ -0,0 +1,133 @@
|
|
|
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 {
|
|
17
|
+
CheckboxField,
|
|
18
|
+
CheckboxLabel,
|
|
19
|
+
FormActionsBar,
|
|
20
|
+
ModalTitle,
|
|
21
|
+
PrimaryButton,
|
|
22
|
+
SecondaryButton,
|
|
23
|
+
} from '@manuscripts/style-guide'
|
|
24
|
+
import { BibliographyItemAttrs } from '@manuscripts/transform'
|
|
25
|
+
import React, { useState } from 'react'
|
|
26
|
+
import styled from 'styled-components'
|
|
27
|
+
|
|
28
|
+
import { ReferenceLine } from './ReferenceLine'
|
|
29
|
+
|
|
30
|
+
export interface ImportReferencesConfirmationProps {
|
|
31
|
+
items: BibliographyItemAttrs[]
|
|
32
|
+
onCancel: () => void
|
|
33
|
+
onConfirm: (items: BibliographyItemAttrs[]) => void
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const ImportReferencesConfirmation: React.FC<
|
|
37
|
+
ImportReferencesConfirmationProps
|
|
38
|
+
> = ({ items, onCancel, onConfirm }) => {
|
|
39
|
+
const [selected, setSelected] = useState(() => items.map(() => true))
|
|
40
|
+
|
|
41
|
+
const selectedCount = selected.filter(Boolean).length
|
|
42
|
+
const countLabel = selectedCount === 1 ? 'reference' : 'references'
|
|
43
|
+
|
|
44
|
+
const toggleItem = (index: number) => {
|
|
45
|
+
setSelected((current) =>
|
|
46
|
+
current.map((value, i) => (i === index ? !value : value))
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const handleConfirm = () => {
|
|
51
|
+
onConfirm(items.filter((_, index) => selected[index]))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<>
|
|
56
|
+
<Title>Import References</Title>
|
|
57
|
+
<Subtitle>
|
|
58
|
+
Importing {selectedCount} {countLabel}
|
|
59
|
+
</Subtitle>
|
|
60
|
+
<List>
|
|
61
|
+
{items.map((item, index) => (
|
|
62
|
+
<ListItem key={index}>
|
|
63
|
+
<ItemCheckbox>
|
|
64
|
+
<CheckboxField
|
|
65
|
+
checked={selected[index]}
|
|
66
|
+
aria-label={`Select reference ${index + 1}`}
|
|
67
|
+
onChange={() => toggleItem(index)}
|
|
68
|
+
/>
|
|
69
|
+
<div />
|
|
70
|
+
</ItemCheckbox>
|
|
71
|
+
<ReferenceLine item={item} />
|
|
72
|
+
</ListItem>
|
|
73
|
+
))}
|
|
74
|
+
</List>
|
|
75
|
+
<FormActionsBar>
|
|
76
|
+
<SecondaryButton type="button" onClick={onCancel}>
|
|
77
|
+
Cancel
|
|
78
|
+
</SecondaryButton>
|
|
79
|
+
<PrimaryButton
|
|
80
|
+
type="button"
|
|
81
|
+
disabled={selectedCount === 0}
|
|
82
|
+
onClick={handleConfirm}
|
|
83
|
+
>
|
|
84
|
+
Import {selectedCount} {countLabel}
|
|
85
|
+
</PrimaryButton>
|
|
86
|
+
</FormActionsBar>
|
|
87
|
+
</>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const Title = styled(ModalTitle)`
|
|
92
|
+
border-bottom: 1px solid ${(props) => props.theme.colors.border.secondary};
|
|
93
|
+
margin: 0 -${(props) => 6 * props.theme.grid.unit}px 20px;
|
|
94
|
+
padding: 0 ${(props) => 6 * props.theme.grid.unit}px
|
|
95
|
+
${(props) => props.theme.grid.unit * 4}px;
|
|
96
|
+
`
|
|
97
|
+
|
|
98
|
+
const Subtitle = styled.p`
|
|
99
|
+
color: ${(props) => props.theme.colors.text.secondary};
|
|
100
|
+
font-weight: ${(props) => props.theme.font.weight.bold};
|
|
101
|
+
margin: 0 0 16px;
|
|
102
|
+
font-size: 14px;
|
|
103
|
+
`
|
|
104
|
+
|
|
105
|
+
const List = styled.div`
|
|
106
|
+
display: flex;
|
|
107
|
+
flex-direction: column;
|
|
108
|
+
margin-bottom: ${(props) => props.theme.grid.unit * 5}px;
|
|
109
|
+
overflow-y: auto;
|
|
110
|
+
`
|
|
111
|
+
|
|
112
|
+
const ListItem = styled.div`
|
|
113
|
+
border-bottom: 1px solid ${(props) => props.theme.colors.border.secondary};
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: flex-start;
|
|
116
|
+
gap: ${(props) => props.theme.grid.unit * 3}px;
|
|
117
|
+
padding: ${(props) => props.theme.grid.unit * 3}px 0;
|
|
118
|
+
`
|
|
119
|
+
|
|
120
|
+
const ItemCheckbox = styled(CheckboxLabel)`
|
|
121
|
+
flex-shrink: 0;
|
|
122
|
+
|
|
123
|
+
> div {
|
|
124
|
+
margin: 0;
|
|
125
|
+
|
|
126
|
+
&::before {
|
|
127
|
+
width: 18px;
|
|
128
|
+
height: 18px;
|
|
129
|
+
border-radius: 4px;
|
|
130
|
+
margin: 0;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
`
|
|
@@ -0,0 +1,93 @@
|
|
|
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 React from 'react'
|
|
17
|
+
import styled from 'styled-components'
|
|
18
|
+
|
|
19
|
+
export interface ImportSuccessPlaceholderProps {
|
|
20
|
+
count: number
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const ImportSuccessPlaceholder: React.FC<
|
|
24
|
+
ImportSuccessPlaceholderProps
|
|
25
|
+
> = ({ count }) => {
|
|
26
|
+
const countLabel = count === 1 ? 'reference' : 'references'
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Container data-cy="import-success-placeholder">
|
|
30
|
+
<IconCircle>
|
|
31
|
+
<SuccessCheckIcon />
|
|
32
|
+
</IconCircle>
|
|
33
|
+
<Title>Successfully Imported</Title>
|
|
34
|
+
<Message>
|
|
35
|
+
Your library has been updated with {count} new {countLabel}.
|
|
36
|
+
</Message>
|
|
37
|
+
</Container>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const SuccessCheckIcon = () => (
|
|
42
|
+
<svg
|
|
43
|
+
width="32"
|
|
44
|
+
height="32"
|
|
45
|
+
viewBox="0 0 32 32"
|
|
46
|
+
fill="none"
|
|
47
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
48
|
+
aria-hidden="true"
|
|
49
|
+
>
|
|
50
|
+
<path
|
|
51
|
+
d="M26.6656 8L12.0004 22.6656L5.3344 15.9994"
|
|
52
|
+
stroke="#36B260"
|
|
53
|
+
strokeWidth="3"
|
|
54
|
+
strokeLinecap="round"
|
|
55
|
+
/>
|
|
56
|
+
</svg>
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
const Container = styled.div`
|
|
60
|
+
display: flex;
|
|
61
|
+
flex-direction: column;
|
|
62
|
+
align-items: center;
|
|
63
|
+
justify-content: center;
|
|
64
|
+
gap: ${(props) => props.theme.grid.unit * 4}px;
|
|
65
|
+
height: 100%;
|
|
66
|
+
padding: 40px;
|
|
67
|
+
box-sizing: border-box;
|
|
68
|
+
text-align: center;
|
|
69
|
+
`
|
|
70
|
+
|
|
71
|
+
const IconCircle = styled.div`
|
|
72
|
+
display: flex;
|
|
73
|
+
align-items: center;
|
|
74
|
+
justify-content: center;
|
|
75
|
+
width: 64px;
|
|
76
|
+
height: 64px;
|
|
77
|
+
border-radius: 32px;
|
|
78
|
+
background: #f6ffed;
|
|
79
|
+
`
|
|
80
|
+
|
|
81
|
+
const Title = styled.h2`
|
|
82
|
+
margin: 0;
|
|
83
|
+
font-size: 24px;
|
|
84
|
+
line-height: 32px;
|
|
85
|
+
letter-spacing: -0.37px;
|
|
86
|
+
color: ${(props) => props.theme.colors.text.primary};
|
|
87
|
+
`
|
|
88
|
+
|
|
89
|
+
const Message = styled.p`
|
|
90
|
+
margin: 0;
|
|
91
|
+
line-height: ${(props) => props.theme.font.lineHeight.large};
|
|
92
|
+
color: ${(props) => props.theme.colors.text.secondary};
|
|
93
|
+
`
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
IconTextButton,
|
|
21
21
|
PrimaryButton,
|
|
22
22
|
SecondaryButton,
|
|
23
|
-
UploadIcon,
|
|
24
23
|
withFocusTrap,
|
|
25
24
|
} from '@manuscripts/style-guide'
|
|
26
25
|
import { BibliographyItemAttrs } from '@manuscripts/transform'
|
|
@@ -74,7 +73,6 @@ export const ReferenceSearch: React.FC<{
|
|
|
74
73
|
sources: BibliographyItemSource[]
|
|
75
74
|
items: BibliographyItemAttrs[]
|
|
76
75
|
onAdd: () => void
|
|
77
|
-
onImport: () => void
|
|
78
76
|
onCite: (items: BibliographyItemAttrs[]) => void
|
|
79
77
|
onCancel: () => void
|
|
80
78
|
}> = ({
|
|
@@ -82,7 +80,6 @@ export const ReferenceSearch: React.FC<{
|
|
|
82
80
|
sources,
|
|
83
81
|
items,
|
|
84
82
|
onAdd,
|
|
85
|
-
onImport,
|
|
86
83
|
onCite,
|
|
87
84
|
onCancel,
|
|
88
85
|
}) => {
|
|
@@ -146,10 +143,6 @@ export const ReferenceSearch: React.FC<{
|
|
|
146
143
|
<AddNewIcon />
|
|
147
144
|
Add new
|
|
148
145
|
</IconTextButton>
|
|
149
|
-
<IconTextButton onClick={onImport}>
|
|
150
|
-
<UploadIcon />
|
|
151
|
-
Import new
|
|
152
|
-
</IconTextButton>
|
|
153
146
|
</AddReferenceActions>
|
|
154
147
|
<ButtonGroup>
|
|
155
148
|
<SecondaryButton onClick={onCancel}>Close</SecondaryButton>
|