@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.
Files changed (50) hide show
  1. package/dist/cjs/components/references/CitationEditor.js +13 -19
  2. package/dist/cjs/components/references/ImportBibliography.js +77 -0
  3. package/dist/cjs/components/references/ImportBibliographyForm.js +1 -1
  4. package/dist/cjs/components/references/ImportBibliographyModal.js +12 -81
  5. package/dist/cjs/components/references/ImportReferencesConfirmation.js +113 -0
  6. package/dist/cjs/components/references/ImportSuccessPlaceholder.js +56 -0
  7. package/dist/cjs/components/references/ReferenceSearch.js +2 -5
  8. package/dist/cjs/components/references/ReferencesEditor.js +18 -2
  9. package/dist/cjs/components/references/ReferencesModal.js +86 -33
  10. package/dist/cjs/lib/view.js +39 -1
  11. package/dist/cjs/versions.js +1 -1
  12. package/dist/cjs/views/bibliography_element.js +1 -2
  13. package/dist/cjs/views/citation_editable.js +2 -29
  14. package/dist/es/components/references/CitationEditor.js +13 -19
  15. package/dist/es/components/references/ImportBibliography.js +70 -0
  16. package/dist/es/components/references/ImportBibliographyForm.js +1 -1
  17. package/dist/es/components/references/ImportBibliographyModal.js +13 -79
  18. package/dist/es/components/references/ImportReferencesConfirmation.js +73 -0
  19. package/dist/es/components/references/ImportSuccessPlaceholder.js +49 -0
  20. package/dist/es/components/references/ReferenceSearch.js +3 -6
  21. package/dist/es/components/references/ReferencesEditor.js +19 -3
  22. package/dist/es/components/references/ReferencesModal.js +88 -35
  23. package/dist/es/lib/view.js +36 -0
  24. package/dist/es/versions.js +1 -1
  25. package/dist/es/views/bibliography_element.js +2 -3
  26. package/dist/es/views/citation_editable.js +3 -30
  27. package/dist/types/components/references/CitationEditor.d.ts +1 -1
  28. package/dist/types/components/references/ImportBibliography.d.ts +7 -0
  29. package/dist/types/components/references/ImportReferencesConfirmation.d.ts +8 -0
  30. package/dist/types/components/references/ImportSuccessPlaceholder.d.ts +5 -0
  31. package/dist/types/components/references/ReferenceSearch.d.ts +0 -1
  32. package/dist/types/components/references/ReferencesEditor.d.ts +4 -1
  33. package/dist/types/components/references/ReferencesModal.d.ts +1 -0
  34. package/dist/types/lib/view.d.ts +3 -1
  35. package/dist/types/versions.d.ts +1 -1
  36. package/dist/types/views/citation_editable.d.ts +0 -1
  37. package/package.json +1 -1
  38. package/src/components/references/CitationEditor.tsx +16 -25
  39. package/src/components/references/ImportBibliography.tsx +119 -0
  40. package/src/components/references/ImportBibliographyForm.tsx +1 -1
  41. package/src/components/references/ImportBibliographyModal.tsx +34 -110
  42. package/src/components/references/ImportReferencesConfirmation.tsx +133 -0
  43. package/src/components/references/ImportSuccessPlaceholder.tsx +93 -0
  44. package/src/components/references/ReferenceSearch.tsx +0 -7
  45. package/src/components/references/ReferencesEditor.tsx +35 -6
  46. package/src/components/references/ReferencesModal.tsx +164 -78
  47. package/src/lib/view.ts +65 -0
  48. package/src/versions.ts +1 -1
  49. package/src/views/bibliography_element.ts +3 -4
  50. 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 { BibliographyItemAttrs } from '@manuscripts/transform'
17
- import React, { useReducer, useState } from 'react'
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 = items.findIndex(isSelected)
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(items.length - 1, base + pageSize))
203
- }, [selectionIndex, items])
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(items.length - 1, endIndex + pageSize)
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, items])
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
- if (items.length <= 0) {
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
- <StyledModal isOpen={isOpen} onRequestClose={onCancel}>
281
- <Dialog
282
- isOpen={confirm}
283
- category={Category.confirmation}
284
- header="You've made changes to this option"
285
- message="Would you like to save or discard your changes?"
286
- actions={{
287
- secondary: {
288
- action: () => reset(),
289
- title: 'Discard',
290
- },
291
- primary: {
292
- action: () => handleSave(valuesRef.current),
293
- title: 'Save',
294
- },
295
- }}
296
- />
297
- <ReferencesModalContainer data-cy={'references-editor'}>
298
- <ModalHeader>
299
- <CloseButton onClick={onCancel} />
300
- </ModalHeader>
301
- <ModalBody>
302
- <ReferencesSidebar>
303
- <ModalSidebarHeader>
304
- <ModalSidebarTitle>References</ModalSidebarTitle>
305
- </ModalSidebarHeader>
306
- <ReferencesSidebarContent ref={ref}>
307
- <ReferencesInnerWrapper>
308
- {items.slice(startIndex, endIndex + 1).map((item) => (
309
- <ReferenceButton
310
- key={item.id}
311
- id={item.id}
312
- className={isSelected(item) ? 'selected' : ''}
313
- onClick={() => handleItemClick(item)}
314
- ref={isSelected(item) ? selectionRef : null}
315
- >
316
- <IconContainer>
317
- <CitationCountIcon />
318
- {(citationCounts.get(item.id) || 0) > 0 ? (
319
- <CitationCount data-tooltip-content="Number of times used in the document">
320
- {citationCounts.get(item.id)}
321
- </CitationCount>
322
- ) : (
323
- <CitationCount className="unused">0</CitationCount>
324
- )}
325
- </IconContainer>
326
- <ReferenceLine item={item} />
327
- </ReferenceButton>
328
- ))}
329
- </ReferencesInnerWrapper>
330
- </ReferencesSidebarContent>
331
- </ReferencesSidebar>
332
- <ScrollableModalContent>
333
- {selection && (
334
- <ReferenceForm
335
- values={normalize(selection)}
336
- showDelete={
337
- !citationCounts.get(selection.id) &&
338
- isNewItem(selection, ['id', 'type']) // disable the delete button for the new citations
339
- }
340
- onChange={handleChange}
341
- onCancel={onCancel}
342
- onDelete={handleDelete}
343
- onSave={handleSave}
344
- actionsRef={actionsRef}
345
- />
346
- )}
347
- </ScrollableModalContent>
348
- </ModalBody>
349
- </ReferencesModalContainer>
350
- </StyledModal>
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
@@ -1,3 +1,3 @@
1
1
  //THIS FILE WAS GENERATED BY versions.mjs
2
- export const VERSION = '3.16.1';
2
+ export const VERSION = '3.16.2';
3
3
  export const MATHJAX_VERSION = '3.2.2';
@@ -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, updateNodeAttrs } from '../lib/view'
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
- updateNodeAttrs(this.view, schema.nodes.bibliography_item, attrs)
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, findChildByID, updateNodeAttrs } from '../lib/view'
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
- if (!findChildByID(this.view, attrs.id)) {
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.insertBibliographyNode(item)
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)