@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
|
@@ -13,8 +13,12 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {
|
|
17
|
-
|
|
16
|
+
import {
|
|
17
|
+
BibliographyItemAttrs,
|
|
18
|
+
generateNodeID,
|
|
19
|
+
schema,
|
|
20
|
+
} from '@manuscripts/transform'
|
|
21
|
+
import React, { useEffect, useReducer, useState } from 'react'
|
|
18
22
|
|
|
19
23
|
import { attrsReducer } from '../../lib/array-reducer'
|
|
20
24
|
import { cleanItemValues } from '../../lib/utils'
|
|
@@ -22,18 +26,25 @@ import { ReferencesModal, ReferencesModalProps } from './ReferencesModal'
|
|
|
22
26
|
|
|
23
27
|
export type ReferencesEditorProps = Omit<
|
|
24
28
|
ReferencesModalProps,
|
|
25
|
-
'isOpen' | 'onCancel'
|
|
26
|
-
>
|
|
29
|
+
'isOpen' | 'onCancel' | 'handleImport' | 'onSave'
|
|
30
|
+
> & {
|
|
31
|
+
onSave: (item: BibliographyItemAttrs[]) => void
|
|
32
|
+
}
|
|
27
33
|
|
|
28
34
|
const itemsReducer = attrsReducer<BibliographyItemAttrs>()
|
|
29
35
|
|
|
30
36
|
export const ReferencesEditor: React.FC<ReferencesEditorProps> = (props) => {
|
|
31
37
|
const [isOpen, setOpen] = useState(true)
|
|
32
38
|
const [items, dispatch] = useReducer(itemsReducer, props.items)
|
|
39
|
+
const [selectedItem, setSelectedItem] = useState(props.item)
|
|
40
|
+
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
setSelectedItem(props.item)
|
|
43
|
+
}, [props.item])
|
|
33
44
|
|
|
34
45
|
const handleSave = (item: BibliographyItemAttrs) => {
|
|
35
46
|
const cleanedItem = cleanItemValues(item)
|
|
36
|
-
props.onSave(cleanedItem)
|
|
47
|
+
props.onSave([cleanedItem])
|
|
37
48
|
dispatch({
|
|
38
49
|
type: 'update',
|
|
39
50
|
items: [cleanedItem],
|
|
@@ -48,14 +59,32 @@ export const ReferencesEditor: React.FC<ReferencesEditorProps> = (props) => {
|
|
|
48
59
|
})
|
|
49
60
|
}
|
|
50
61
|
|
|
62
|
+
const handleImport = (data: BibliographyItemAttrs[]) => {
|
|
63
|
+
const newItems = data.map((item) =>
|
|
64
|
+
cleanItemValues({
|
|
65
|
+
...item,
|
|
66
|
+
id: generateNodeID(schema.nodes.bibliography_item),
|
|
67
|
+
})
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
props.onSave(newItems)
|
|
71
|
+
|
|
72
|
+
dispatch({
|
|
73
|
+
type: 'set',
|
|
74
|
+
state: [...items, ...newItems],
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
51
78
|
return (
|
|
52
79
|
<ReferencesModal
|
|
53
|
-
{...props}
|
|
54
80
|
isOpen={isOpen}
|
|
55
81
|
onCancel={() => setOpen(false)}
|
|
56
82
|
items={items}
|
|
83
|
+
item={selectedItem}
|
|
84
|
+
citationCounts={props.citationCounts}
|
|
57
85
|
onSave={handleSave}
|
|
58
86
|
onDelete={handleDelete}
|
|
87
|
+
handleImport={handleImport}
|
|
59
88
|
/>
|
|
60
89
|
)
|
|
61
90
|
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import {
|
|
17
|
+
AddAuthorIcon,
|
|
17
18
|
Category,
|
|
18
19
|
CitationCountIcon,
|
|
19
20
|
CloseButton,
|
|
@@ -33,7 +34,7 @@ import {
|
|
|
33
34
|
} from '@manuscripts/style-guide'
|
|
34
35
|
import { BibliographyItemAttrs } from '@manuscripts/transform'
|
|
35
36
|
import isEqual from 'lodash/isEqual'
|
|
36
|
-
import React, { useEffect, useRef, useState } from 'react'
|
|
37
|
+
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
|
37
38
|
import styled from 'styled-components'
|
|
38
39
|
|
|
39
40
|
import {
|
|
@@ -41,6 +42,8 @@ import {
|
|
|
41
42
|
ReferenceFormActions,
|
|
42
43
|
} from './ReferenceForm/ReferenceForm'
|
|
43
44
|
import { ReferenceLine } from './ReferenceLine'
|
|
45
|
+
import { ImportBibliographyModal } from './ImportBibliographyModal'
|
|
46
|
+
import { ImportSuccessPlaceholder } from './ImportSuccessPlaceholder'
|
|
44
47
|
|
|
45
48
|
const ReferencesModalContainer = styled(ModalContainer)`
|
|
46
49
|
min-width: 960px;
|
|
@@ -54,6 +57,35 @@ const ReferencesSidebarContent = styled(SidebarContent)`
|
|
|
54
57
|
overflow-y: auto;
|
|
55
58
|
`
|
|
56
59
|
|
|
60
|
+
const ImportFromFileFooter = styled.div`
|
|
61
|
+
padding: 16px;
|
|
62
|
+
`
|
|
63
|
+
|
|
64
|
+
const ImportFromFileButton = styled.button`
|
|
65
|
+
display: flex;
|
|
66
|
+
width: 100%;
|
|
67
|
+
padding: 8px 24px;
|
|
68
|
+
justify-content: center;
|
|
69
|
+
align-items: center;
|
|
70
|
+
gap: 8px;
|
|
71
|
+
border-radius: 4px;
|
|
72
|
+
border: 1px dashed #c9c9c9;
|
|
73
|
+
background: #fafafa;
|
|
74
|
+
cursor: pointer;
|
|
75
|
+
font-family: ${(props) => props.theme.font.family.sans};
|
|
76
|
+
font-size: 14px;
|
|
77
|
+
color: #353535;
|
|
78
|
+
|
|
79
|
+
svg {
|
|
80
|
+
width: 20px;
|
|
81
|
+
height: 20px;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
svg rect {
|
|
85
|
+
fill: #6e6e6e;
|
|
86
|
+
}
|
|
87
|
+
`
|
|
88
|
+
|
|
57
89
|
const ReferencesInnerWrapper = withListNavigation(styled.div`
|
|
58
90
|
width: 100%;
|
|
59
91
|
padding: 12px 0;
|
|
@@ -155,6 +187,7 @@ export interface ReferencesModalProps {
|
|
|
155
187
|
citationCounts: Map<string, number>
|
|
156
188
|
onSave: (item: BibliographyItemAttrs) => void
|
|
157
189
|
onDelete: (item: BibliographyItemAttrs) => void
|
|
190
|
+
handleImport: (data: BibliographyItemAttrs[]) => void
|
|
158
191
|
}
|
|
159
192
|
|
|
160
193
|
export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
@@ -165,16 +198,36 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
165
198
|
citationCounts,
|
|
166
199
|
onSave,
|
|
167
200
|
onDelete,
|
|
201
|
+
handleImport,
|
|
168
202
|
}) => {
|
|
203
|
+
const [importing, setImporting] = useState(false)
|
|
204
|
+
const [importSuccessCount, setImportSuccessCount] = useState<number | null>(
|
|
205
|
+
null
|
|
206
|
+
)
|
|
169
207
|
const [confirm, setConfirm] = useState(false)
|
|
170
208
|
const valuesRef = useRef<BibliographyItemAttrs>(undefined)
|
|
171
209
|
|
|
172
210
|
const [selection, setSelection] = useState<BibliographyItemAttrs>()
|
|
173
211
|
const selectionRef = useRef<HTMLDivElement>(null)
|
|
212
|
+
|
|
213
|
+
const sortedItems = useMemo(
|
|
214
|
+
() =>
|
|
215
|
+
[...items].sort((a, b) => {
|
|
216
|
+
const aUncited = (citationCounts.get(a.id) ?? 0) === 0
|
|
217
|
+
const bUncited = (citationCounts.get(b.id) ?? 0) === 0
|
|
218
|
+
|
|
219
|
+
if (aUncited === bUncited) {
|
|
220
|
+
return 0
|
|
221
|
+
}
|
|
222
|
+
return aUncited ? 1 : -1
|
|
223
|
+
}),
|
|
224
|
+
[items, citationCounts]
|
|
225
|
+
)
|
|
226
|
+
|
|
174
227
|
const isSelected = (item: BibliographyItemAttrs) => {
|
|
175
228
|
return item.id === selection?.id
|
|
176
229
|
}
|
|
177
|
-
const selectionIndex =
|
|
230
|
+
const selectionIndex = sortedItems.findIndex(isSelected)
|
|
178
231
|
|
|
179
232
|
useEffect(() => {
|
|
180
233
|
setSelection(item)
|
|
@@ -199,8 +252,8 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
199
252
|
useEffect(() => {
|
|
200
253
|
const base = Math.max(0, selectionIndex - selectionTopOffset)
|
|
201
254
|
setStartIndex(base)
|
|
202
|
-
setEndIndex(Math.min(
|
|
203
|
-
}, [selectionIndex,
|
|
255
|
+
setEndIndex(Math.min(sortedItems.length - 1, base + pageSize))
|
|
256
|
+
}, [selectionIndex, sortedItems])
|
|
204
257
|
|
|
205
258
|
useEffect(() => {
|
|
206
259
|
if (triggers.top) {
|
|
@@ -209,12 +262,12 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
209
262
|
setEndIndex(Math.min(newFirst + dropLimit, endIndex))
|
|
210
263
|
}
|
|
211
264
|
if (triggers.bottom) {
|
|
212
|
-
const newLast = Math.min(
|
|
265
|
+
const newLast = Math.min(sortedItems.length - 1, endIndex + pageSize)
|
|
213
266
|
setEndIndex(newLast)
|
|
214
267
|
setStartIndex(Math.max(newLast - dropLimit, startIndex))
|
|
215
268
|
}
|
|
216
269
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
217
|
-
}, [triggers,
|
|
270
|
+
}, [triggers, sortedItems])
|
|
218
271
|
|
|
219
272
|
const actionsRef = useRef<ReferenceFormActions>(undefined)
|
|
220
273
|
|
|
@@ -260,7 +313,10 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
260
313
|
setSelection(undefined)
|
|
261
314
|
}
|
|
262
315
|
|
|
316
|
+
const clearImportSuccess = () => setImportSuccessCount(null)
|
|
317
|
+
|
|
263
318
|
const handleItemClick = (item: BibliographyItemAttrs) => {
|
|
319
|
+
clearImportSuccess()
|
|
264
320
|
const values = valuesRef.current
|
|
265
321
|
if (values && selection && !isEqual(values, normalize(selection))) {
|
|
266
322
|
setConfirm(true)
|
|
@@ -272,81 +328,111 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
272
328
|
const handleChange = (values: BibliographyItemAttrs) => {
|
|
273
329
|
valuesRef.current = values
|
|
274
330
|
}
|
|
275
|
-
|
|
331
|
+
|
|
332
|
+
const handleImportSave = (data: BibliographyItemAttrs[]) => {
|
|
333
|
+
handleImport(data)
|
|
334
|
+
setImporting(false)
|
|
335
|
+
setSelection(undefined)
|
|
336
|
+
setImportSuccessCount(data.length)
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (sortedItems.length <= 0) {
|
|
276
340
|
return <></>
|
|
277
341
|
}
|
|
278
342
|
|
|
279
343
|
return (
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
<
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
<
|
|
317
|
-
|
|
318
|
-
{
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
344
|
+
<>
|
|
345
|
+
{importing && (
|
|
346
|
+
<ImportBibliographyModal
|
|
347
|
+
onCancel={() => setImporting(false)}
|
|
348
|
+
onSave={handleImportSave}
|
|
349
|
+
/>
|
|
350
|
+
)}
|
|
351
|
+
<StyledModal isOpen={isOpen} onRequestClose={onCancel}>
|
|
352
|
+
<Dialog
|
|
353
|
+
isOpen={confirm}
|
|
354
|
+
category={Category.confirmation}
|
|
355
|
+
header="You've made changes to this option"
|
|
356
|
+
message="Would you like to save or discard your changes?"
|
|
357
|
+
actions={{
|
|
358
|
+
secondary: {
|
|
359
|
+
action: () => reset(),
|
|
360
|
+
title: 'Discard',
|
|
361
|
+
},
|
|
362
|
+
primary: {
|
|
363
|
+
action: () => handleSave(valuesRef.current),
|
|
364
|
+
title: 'Save',
|
|
365
|
+
},
|
|
366
|
+
}}
|
|
367
|
+
/>
|
|
368
|
+
<ReferencesModalContainer data-cy={'references-editor'}>
|
|
369
|
+
<ModalHeader>
|
|
370
|
+
<CloseButton data-cy="modal-close-button" onClick={onCancel} />
|
|
371
|
+
</ModalHeader>
|
|
372
|
+
<ModalBody>
|
|
373
|
+
<ReferencesSidebar>
|
|
374
|
+
<ModalSidebarHeader>
|
|
375
|
+
<ModalSidebarTitle>References</ModalSidebarTitle>
|
|
376
|
+
</ModalSidebarHeader>
|
|
377
|
+
<ReferencesSidebarContent ref={ref}>
|
|
378
|
+
<ReferencesInnerWrapper>
|
|
379
|
+
{sortedItems.slice(startIndex, endIndex + 1).map((item) => (
|
|
380
|
+
<ReferenceButton
|
|
381
|
+
key={item.id}
|
|
382
|
+
id={item.id}
|
|
383
|
+
className={isSelected(item) ? 'selected' : ''}
|
|
384
|
+
onClick={() => handleItemClick(item)}
|
|
385
|
+
ref={isSelected(item) ? selectionRef : null}
|
|
386
|
+
>
|
|
387
|
+
<IconContainer>
|
|
388
|
+
<CitationCountIcon />
|
|
389
|
+
{(citationCounts.get(item.id) || 0) > 0 ? (
|
|
390
|
+
<CitationCount data-tooltip-content="Number of times used in the document">
|
|
391
|
+
{citationCounts.get(item.id)}
|
|
392
|
+
</CitationCount>
|
|
393
|
+
) : (
|
|
394
|
+
<CitationCount className="unused">0</CitationCount>
|
|
395
|
+
)}
|
|
396
|
+
</IconContainer>
|
|
397
|
+
<ReferenceLine item={item} />
|
|
398
|
+
</ReferenceButton>
|
|
399
|
+
))}
|
|
400
|
+
</ReferencesInnerWrapper>
|
|
401
|
+
</ReferencesSidebarContent>
|
|
402
|
+
<ImportFromFileFooter>
|
|
403
|
+
<ImportFromFileButton
|
|
404
|
+
type="button"
|
|
405
|
+
data-cy="import-from-file-button"
|
|
406
|
+
onClick={() => setImporting(true)}
|
|
407
|
+
>
|
|
408
|
+
<AddAuthorIcon />
|
|
409
|
+
Import from file
|
|
410
|
+
</ImportFromFileButton>
|
|
411
|
+
</ImportFromFileFooter>
|
|
412
|
+
</ReferencesSidebar>
|
|
413
|
+
<ScrollableModalContent>
|
|
414
|
+
{importSuccessCount !== null ? (
|
|
415
|
+
<ImportSuccessPlaceholder count={importSuccessCount} />
|
|
416
|
+
) : (
|
|
417
|
+
selection && (
|
|
418
|
+
<ReferenceForm
|
|
419
|
+
values={normalize(selection)}
|
|
420
|
+
showDelete={
|
|
421
|
+
!citationCounts.get(selection.id) &&
|
|
422
|
+
isNewItem(selection, ['id', 'type']) // disable the delete button for the new citations
|
|
423
|
+
}
|
|
424
|
+
onChange={handleChange}
|
|
425
|
+
onCancel={onCancel}
|
|
426
|
+
onDelete={handleDelete}
|
|
427
|
+
onSave={handleSave}
|
|
428
|
+
actionsRef={actionsRef}
|
|
429
|
+
/>
|
|
430
|
+
)
|
|
431
|
+
)}
|
|
432
|
+
</ScrollableModalContent>
|
|
433
|
+
</ModalBody>
|
|
434
|
+
</ReferencesModalContainer>
|
|
435
|
+
</StyledModal>
|
|
436
|
+
</>
|
|
351
437
|
)
|
|
352
438
|
}
|
package/src/lib/view.ts
CHANGED
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import {
|
|
18
|
+
BibliographyItemAttrs,
|
|
18
19
|
ManuscriptEditorView,
|
|
20
|
+
ManuscriptNode,
|
|
19
21
|
ManuscriptNodeType,
|
|
20
22
|
schema,
|
|
21
23
|
} from '@manuscripts/transform'
|
|
@@ -98,3 +100,66 @@ export const deleteNode = (view: ManuscriptEditorView, id: string) => {
|
|
|
98
100
|
view.dispatch(view.state.tr.delete(pos, pos + node.nodeSize))
|
|
99
101
|
}
|
|
100
102
|
}
|
|
103
|
+
|
|
104
|
+
const createBibliographySection = (nodes: ManuscriptNode[]) =>
|
|
105
|
+
schema.nodes.bibliography_section.createAndFill({}, [
|
|
106
|
+
schema.nodes.section_title.create({}, schema.text('References')),
|
|
107
|
+
schema.nodes.bibliography_element.create({}, nodes),
|
|
108
|
+
]) as ManuscriptNode
|
|
109
|
+
|
|
110
|
+
export const insertBibliographyItems = (
|
|
111
|
+
view: ManuscriptEditorView,
|
|
112
|
+
items: BibliographyItemAttrs[]
|
|
113
|
+
) => {
|
|
114
|
+
const { doc } = view.state
|
|
115
|
+
let tr = view.state.tr
|
|
116
|
+
|
|
117
|
+
const biblioSection = utils.findChildrenByType(
|
|
118
|
+
doc,
|
|
119
|
+
schema.nodes.bibliography_element,
|
|
120
|
+
true
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
if (biblioSection.length) {
|
|
124
|
+
let insertPos = biblioSection[0].pos + 1
|
|
125
|
+
for (const attrs of items) {
|
|
126
|
+
const node = schema.nodes.bibliography_item.create(attrs)
|
|
127
|
+
tr = tr.insert(insertPos, node)
|
|
128
|
+
insertPos += node.nodeSize
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
const backmatter = utils.findChildrenByType(
|
|
132
|
+
doc,
|
|
133
|
+
schema.nodes.backmatter,
|
|
134
|
+
true
|
|
135
|
+
)
|
|
136
|
+
const backmatterEnd = backmatter[0]
|
|
137
|
+
? backmatter[0].node.nodeSize + backmatter[0].pos
|
|
138
|
+
: 0
|
|
139
|
+
|
|
140
|
+
const nodes = items.map((attrs) =>
|
|
141
|
+
schema.nodes.bibliography_item.create(attrs)
|
|
142
|
+
)
|
|
143
|
+
tr = tr.insert(
|
|
144
|
+
backmatterEnd ? backmatterEnd - 1 : tr.doc.content.size,
|
|
145
|
+
createBibliographySection(nodes)
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
view.dispatch(tr)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const saveBibliographyItem = (
|
|
152
|
+
view: ManuscriptEditorView,
|
|
153
|
+
attrs: BibliographyItemAttrs[]
|
|
154
|
+
) => {
|
|
155
|
+
if (attrs.length === 1) {
|
|
156
|
+
const item = attrs[0]
|
|
157
|
+
|
|
158
|
+
if (findChildByID(view, item.id)) {
|
|
159
|
+
updateNodeAttrs(view, schema.nodes.bibliography_item, item)
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
insertBibliographyItems(view, attrs)
|
|
165
|
+
}
|
package/src/versions.ts
CHANGED
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
BibliographyElementNode,
|
|
20
20
|
BibliographyItemAttrs,
|
|
21
21
|
BibliographyItemNode,
|
|
22
|
-
schema,
|
|
23
22
|
} from '@manuscripts/transform'
|
|
24
23
|
import { NodeSelection } from 'prosemirror-state'
|
|
25
24
|
|
|
@@ -32,7 +31,7 @@ import { handleEnterKey } from '../lib/navigation-utils'
|
|
|
32
31
|
import { findNodeByID } from '../lib/doc'
|
|
33
32
|
import { sanitize } from '../lib/dompurify'
|
|
34
33
|
|
|
35
|
-
import { deleteNode, findChildByID,
|
|
34
|
+
import { deleteNode, findChildByID, saveBibliographyItem } from '../lib/view'
|
|
36
35
|
import { getBibliographyPluginState } from '../plugins/bibliography'
|
|
37
36
|
import { commentsKey, setCommentSelection } from '../plugins/comments'
|
|
38
37
|
import { selectedSuggestionKey } from '../plugins/selected-suggestion'
|
|
@@ -269,8 +268,8 @@ export class BibliographyElementBlockView extends BlockView<
|
|
|
269
268
|
this.dom.appendChild(this.container)
|
|
270
269
|
}
|
|
271
270
|
|
|
272
|
-
private handleSave = (attrs: BibliographyItemAttrs) => {
|
|
273
|
-
|
|
271
|
+
private handleSave = (attrs: BibliographyItemAttrs[]) => {
|
|
272
|
+
saveBibliographyItem(this.view, attrs)
|
|
274
273
|
}
|
|
275
274
|
|
|
276
275
|
private handleDelete = (item: BibliographyItemAttrs) => {
|
|
@@ -16,13 +16,8 @@
|
|
|
16
16
|
|
|
17
17
|
import { ContextMenu, ContextMenuProps } from '@manuscripts/style-guide'
|
|
18
18
|
import { isDeleted } from '@manuscripts/track-changes-plugin'
|
|
19
|
-
import {
|
|
20
|
-
BibliographyItemAttrs,
|
|
21
|
-
ManuscriptNode,
|
|
22
|
-
schema,
|
|
23
|
-
} from '@manuscripts/transform'
|
|
19
|
+
import { BibliographyItemAttrs } from '@manuscripts/transform'
|
|
24
20
|
import { TextSelection } from 'prosemirror-state'
|
|
25
|
-
import { findChildrenByType } from 'prosemirror-utils'
|
|
26
21
|
|
|
27
22
|
import {
|
|
28
23
|
CitationEditor,
|
|
@@ -35,18 +30,12 @@ import {
|
|
|
35
30
|
import { handleComment } from '../lib/comments'
|
|
36
31
|
import { Crossref } from '../lib/crossref'
|
|
37
32
|
import { handleEnterKey } from '../lib/navigation-utils'
|
|
38
|
-
import { deleteNode,
|
|
33
|
+
import { deleteNode, saveBibliographyItem } from '../lib/view'
|
|
39
34
|
import { getBibliographyPluginState } from '../plugins/bibliography'
|
|
40
35
|
import { CitationView } from './citation'
|
|
41
36
|
import { createEditableNodeView } from './creators'
|
|
42
37
|
import ReactSubView from './ReactSubView'
|
|
43
38
|
|
|
44
|
-
const createBibliographySection = (node: ManuscriptNode) =>
|
|
45
|
-
schema.nodes.bibliography_section.createAndFill({}, [
|
|
46
|
-
schema.nodes.section_title.create({}, schema.text('References')),
|
|
47
|
-
schema.nodes.bibliography_element.create({}, node ? [node] : []),
|
|
48
|
-
]) as ManuscriptNode
|
|
49
|
-
|
|
50
39
|
export class CitationEditableView extends CitationView {
|
|
51
40
|
private editor: HTMLElement
|
|
52
41
|
private contextMenu: HTMLElement
|
|
@@ -216,12 +205,8 @@ export class CitationEditableView extends CitationView {
|
|
|
216
205
|
this.props.popper.destroy()
|
|
217
206
|
}
|
|
218
207
|
|
|
219
|
-
private handleSave = (attrs: BibliographyItemAttrs) => {
|
|
220
|
-
|
|
221
|
-
this.insertBibliographyNode(attrs)
|
|
222
|
-
} else {
|
|
223
|
-
updateNodeAttrs(this.view, schema.nodes.bibliography_item, attrs)
|
|
224
|
-
}
|
|
208
|
+
private handleSave = (attrs: BibliographyItemAttrs[]) => {
|
|
209
|
+
saveBibliographyItem(this.view, attrs)
|
|
225
210
|
}
|
|
226
211
|
|
|
227
212
|
private handleUncite = (id: string) => {
|
|
@@ -260,7 +245,7 @@ export class CitationEditableView extends CitationView {
|
|
|
260
245
|
if (existingItem) {
|
|
261
246
|
item.id = existingItem.id
|
|
262
247
|
} else {
|
|
263
|
-
this.
|
|
248
|
+
saveBibliographyItem(this.view, [item])
|
|
264
249
|
}
|
|
265
250
|
|
|
266
251
|
rids.push(item.id)
|
|
@@ -277,36 +262,6 @@ export class CitationEditableView extends CitationView {
|
|
|
277
262
|
private handleDelete = (item: BibliographyItemAttrs) => {
|
|
278
263
|
return deleteNode(this.view, item.id)
|
|
279
264
|
}
|
|
280
|
-
|
|
281
|
-
private insertBibliographyNode(attrs: BibliographyItemAttrs) {
|
|
282
|
-
const { doc, tr } = this.view.state
|
|
283
|
-
|
|
284
|
-
const biblioSection = findChildrenByType(
|
|
285
|
-
doc,
|
|
286
|
-
schema.nodes.bibliography_element,
|
|
287
|
-
true
|
|
288
|
-
)
|
|
289
|
-
|
|
290
|
-
const backmatter = findChildrenByType(doc, schema.nodes.backmatter, true)
|
|
291
|
-
const backmatterEnd = backmatter[0]
|
|
292
|
-
? backmatter[0].node.nodeSize + backmatter[0].pos
|
|
293
|
-
: 0
|
|
294
|
-
|
|
295
|
-
const node = schema.nodes.bibliography_item.create(attrs)
|
|
296
|
-
|
|
297
|
-
if (biblioSection.length) {
|
|
298
|
-
this.view.dispatch(tr.insert(biblioSection[0].pos + 1, node))
|
|
299
|
-
} else {
|
|
300
|
-
this.view.dispatch(
|
|
301
|
-
tr.insert(
|
|
302
|
-
backmatterEnd ? backmatterEnd - 1 : tr.doc.content.size,
|
|
303
|
-
createBibliographySection(node)
|
|
304
|
-
)
|
|
305
|
-
)
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return false
|
|
309
|
-
}
|
|
310
265
|
}
|
|
311
266
|
|
|
312
267
|
export default createEditableNodeView(CitationEditableView)
|