@manuscripts/body-editor 3.17.3 → 3.18.0
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 +13 -19
- package/dist/cjs/components/references/ReferenceLine.js +14 -1
- package/dist/cjs/components/references/ReferencesModal.js +155 -131
- package/dist/cjs/configs/editor-views.js +1 -0
- package/dist/cjs/icons.js +2 -2
- package/dist/cjs/lib/context-menu.js +4 -1
- package/dist/cjs/lib/normalize.js +31 -1
- package/dist/cjs/lib/paste.js +0 -1
- package/dist/cjs/menus.js +1 -1
- package/dist/cjs/node-type-icons.js +1 -0
- package/dist/cjs/plugins/add-subtitle.js +1 -1
- package/dist/cjs/plugins/bibliography.js +7 -1
- package/dist/cjs/plugins/section_category.js +5 -2
- package/dist/cjs/plugins/translations.js +9 -21
- package/dist/cjs/versions.js +1 -1
- package/dist/cjs/views/bibliography_element.js +44 -2
- package/dist/cjs/views/figure_element.js +1 -1
- package/dist/cjs/views/headshot_grid.js +1 -1
- package/dist/es/commands.js +13 -19
- package/dist/es/components/references/ReferenceLine.js +14 -1
- package/dist/es/components/references/ReferencesModal.js +156 -132
- package/dist/es/configs/editor-views.js +1 -0
- package/dist/es/icons.js +1 -1
- package/dist/es/lib/context-menu.js +4 -1
- package/dist/es/lib/normalize.js +30 -1
- package/dist/es/lib/paste.js +0 -1
- package/dist/es/menus.js +1 -1
- package/dist/es/node-type-icons.js +1 -0
- package/dist/es/plugins/add-subtitle.js +2 -2
- package/dist/es/plugins/bibliography.js +7 -1
- package/dist/es/plugins/section_category.js +6 -3
- package/dist/es/plugins/translations.js +11 -23
- package/dist/es/versions.js +1 -1
- package/dist/es/views/bibliography_element.js +45 -3
- package/dist/es/views/figure_element.js +2 -2
- package/dist/es/views/headshot_grid.js +2 -2
- package/dist/types/commands.d.ts +2 -2
- package/dist/types/components/references/ReferenceLine.d.ts +1 -0
- package/dist/types/icons.d.ts +1 -1
- package/dist/types/lib/normalize.d.ts +30 -1
- package/dist/types/versions.d.ts +1 -1
- package/dist/types/views/bibliography_element.d.ts +5 -1
- package/package.json +2 -2
- package/src/commands.ts +22 -35
- package/src/components/references/ReferenceLine.tsx +16 -1
- package/src/components/references/ReferencesModal.tsx +178 -140
- package/src/configs/editor-views.ts +1 -0
- package/src/icons.ts +1 -1
- package/src/lib/context-menu.ts +4 -1
- package/src/lib/normalize.ts +36 -1
- package/src/lib/paste.ts +0 -1
- package/src/menus.tsx +1 -1
- package/src/node-type-icons.tsx +1 -0
- package/src/plugins/add-subtitle.ts +2 -2
- package/src/plugins/bibliography.ts +10 -3
- package/src/plugins/section_category.ts +7 -2
- package/src/plugins/translations.ts +18 -29
- package/src/versions.ts +1 -1
- package/src/views/bibliography_element.ts +61 -4
- package/src/views/figure_element.ts +2 -2
- package/src/views/headshot_grid.ts +2 -2
- package/styles/AdvancedEditor.css +29 -2
- package/styles/Editor.css +7 -0
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import {
|
|
17
|
+
AddIcon,
|
|
17
18
|
AddAuthorIcon,
|
|
18
19
|
Category,
|
|
19
20
|
CitationCountIcon,
|
|
@@ -32,7 +33,11 @@ import {
|
|
|
32
33
|
withListNavigation,
|
|
33
34
|
withNavigableListItem,
|
|
34
35
|
} from '@manuscripts/style-guide'
|
|
35
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
BibliographyItemAttrs,
|
|
38
|
+
generateNodeID,
|
|
39
|
+
schema,
|
|
40
|
+
} from '@manuscripts/transform'
|
|
36
41
|
import isEqual from 'lodash/isEqual'
|
|
37
42
|
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
|
38
43
|
import styled from 'styled-components'
|
|
@@ -44,104 +49,7 @@ import {
|
|
|
44
49
|
import { ReferenceLine } from './ReferenceLine'
|
|
45
50
|
import { ImportBibliographyModal } from './ImportBibliographyModal'
|
|
46
51
|
import { ImportSuccessPlaceholder } from './ImportSuccessPlaceholder'
|
|
47
|
-
|
|
48
|
-
const ReferencesModalContainer = styled(ModalContainer)`
|
|
49
|
-
min-width: 960px;
|
|
50
|
-
`
|
|
51
|
-
|
|
52
|
-
const ReferencesSidebar = styled(ModalSidebar)`
|
|
53
|
-
width: 70%;
|
|
54
|
-
`
|
|
55
|
-
|
|
56
|
-
const ReferencesSidebarContent = styled(SidebarContent)`
|
|
57
|
-
overflow-y: auto;
|
|
58
|
-
`
|
|
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
|
-
|
|
89
|
-
const ReferencesInnerWrapper = withListNavigation(styled.div`
|
|
90
|
-
width: 100%;
|
|
91
|
-
padding: 12px 0;
|
|
92
|
-
`)
|
|
93
|
-
|
|
94
|
-
const ReferenceButton = withNavigableListItem(styled.div`
|
|
95
|
-
cursor: pointer;
|
|
96
|
-
display: flex;
|
|
97
|
-
justify-content: flex-start;
|
|
98
|
-
padding: ${(props) => props.theme.grid.unit * 4}px 0;
|
|
99
|
-
border-top: 1px solid transparent;
|
|
100
|
-
border-bottom: 1px solid transparent;
|
|
101
|
-
|
|
102
|
-
path {
|
|
103
|
-
fill: #c9c9c9;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
&:hover {
|
|
107
|
-
background: ${(props) => props.theme.colors.background.info};
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
&.selected {
|
|
111
|
-
background: ${(props) => props.theme.colors.background.info};
|
|
112
|
-
border-top-color: #bce7f6;
|
|
113
|
-
border-bottom-color: #bce7f6;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
.tooltip {
|
|
117
|
-
max-width: ${(props) => props.theme.grid.unit * 25}px;
|
|
118
|
-
padding: ${(props) => props.theme.grid.unit * 2}px;
|
|
119
|
-
border-radius: 6px;
|
|
120
|
-
}
|
|
121
|
-
`)
|
|
122
|
-
|
|
123
|
-
const IconContainer = styled.div`
|
|
124
|
-
padding-right: ${(props) => props.theme.grid.unit * 5}px;
|
|
125
|
-
position: relative;
|
|
126
|
-
`
|
|
127
|
-
|
|
128
|
-
const CitationCount = styled.div`
|
|
129
|
-
border-radius: 50%;
|
|
130
|
-
width: 12px;
|
|
131
|
-
height: 12px;
|
|
132
|
-
position: absolute;
|
|
133
|
-
color: #ffffff;
|
|
134
|
-
background-color: #bce7f6;
|
|
135
|
-
text-align: center;
|
|
136
|
-
vertical-align: top;
|
|
137
|
-
top: 0;
|
|
138
|
-
left: 16px;
|
|
139
|
-
font-size: 9px;
|
|
140
|
-
|
|
141
|
-
&.unused {
|
|
142
|
-
background-color: #fe8f1f;
|
|
143
|
-
}
|
|
144
|
-
`
|
|
52
|
+
import { normalizeBlblioItem } from '../../lib/normalize'
|
|
145
53
|
|
|
146
54
|
const selectionTopOffset = 10 // to be able to place the selected item in the middle and allow for some scroll at the top
|
|
147
55
|
const pageSize = 12
|
|
@@ -149,36 +57,6 @@ const topTrigger = 0.2 // says: notify when x% of the offsetHeight remains hidde
|
|
|
149
57
|
const bottomTrigger = 0.8 // says: notify when x% of the offsetHeight remains hidden at the bottom
|
|
150
58
|
const dropLimit = 36 // basically maximum amount of items that can exist at the same time
|
|
151
59
|
|
|
152
|
-
const normalize = (item: BibliographyItemAttrs) => ({
|
|
153
|
-
id: item.id,
|
|
154
|
-
type: item.type,
|
|
155
|
-
author: item.author || [],
|
|
156
|
-
editor: item.editor || [],
|
|
157
|
-
issued: item.issued,
|
|
158
|
-
['container-title']: item['container-title'] || '',
|
|
159
|
-
['collection-title']: item['collection-title'] || '',
|
|
160
|
-
DOI: item.DOI || '',
|
|
161
|
-
URL: item.URL || '',
|
|
162
|
-
volume: item.volume || '',
|
|
163
|
-
issue: item.issue || '',
|
|
164
|
-
supplement: item.supplement || '',
|
|
165
|
-
edition: item.edition || '',
|
|
166
|
-
page: item.page || '',
|
|
167
|
-
['number-of-pages']: item['number-of-pages'] || '',
|
|
168
|
-
title: item.title || '',
|
|
169
|
-
literal: item.literal || '',
|
|
170
|
-
std: item.std || '',
|
|
171
|
-
publisher: item.publisher || '',
|
|
172
|
-
['publisher-place']: item['publisher-place'] || '',
|
|
173
|
-
event: item.event || '',
|
|
174
|
-
['event-place']: item['event-place'] || '',
|
|
175
|
-
['event-date']: item['event-date'],
|
|
176
|
-
institution: item.institution || '',
|
|
177
|
-
locator: item.locator || '',
|
|
178
|
-
accessed: item.accessed,
|
|
179
|
-
comment: item.comment || '',
|
|
180
|
-
})
|
|
181
|
-
|
|
182
60
|
export interface ReferencesModalProps {
|
|
183
61
|
isOpen: boolean
|
|
184
62
|
onCancel: () => void
|
|
@@ -208,6 +86,7 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
208
86
|
const valuesRef = useRef<BibliographyItemAttrs>(undefined)
|
|
209
87
|
|
|
210
88
|
const [selection, setSelection] = useState<BibliographyItemAttrs>()
|
|
89
|
+
const [isNew, setIsNew] = useState<boolean>(false)
|
|
211
90
|
const selectionRef = useRef<HTMLDivElement>(null)
|
|
212
91
|
|
|
213
92
|
const sortedItems = useMemo(
|
|
@@ -230,7 +109,16 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
230
109
|
const selectionIndex = sortedItems.findIndex(isSelected)
|
|
231
110
|
|
|
232
111
|
useEffect(() => {
|
|
233
|
-
|
|
112
|
+
if (item) {
|
|
113
|
+
setSelection(item)
|
|
114
|
+
setIsNew(false)
|
|
115
|
+
} else {
|
|
116
|
+
setIsNew(true)
|
|
117
|
+
setSelection({
|
|
118
|
+
id: generateNodeID(schema.nodes.bibliography_item),
|
|
119
|
+
type: 'article-journal',
|
|
120
|
+
})
|
|
121
|
+
}
|
|
234
122
|
}, [item])
|
|
235
123
|
|
|
236
124
|
useEffect(() => {
|
|
@@ -297,11 +185,12 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
297
185
|
const currentCitationCount = citationCounts.get(item.id)
|
|
298
186
|
|
|
299
187
|
if (currentCitationCount === undefined) {
|
|
300
|
-
citationCounts.set(item.id,
|
|
188
|
+
citationCounts.set(item.id, 0) // update the citation count in the Map
|
|
301
189
|
}
|
|
302
190
|
|
|
303
191
|
onSave(item)
|
|
304
192
|
setSelection(item)
|
|
193
|
+
setIsNew(false)
|
|
305
194
|
setConfirm(false)
|
|
306
195
|
}
|
|
307
196
|
|
|
@@ -313,15 +202,22 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
313
202
|
setSelection(undefined)
|
|
314
203
|
}
|
|
315
204
|
|
|
205
|
+
const hasChanged = () => {
|
|
206
|
+
const values = valuesRef.current
|
|
207
|
+
return (
|
|
208
|
+
values && selection && !isEqual(values, normalizeBlblioItem(selection))
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
|
|
316
212
|
const clearImportSuccess = () => setImportSuccessCount(null)
|
|
317
213
|
|
|
318
214
|
const handleItemClick = (item: BibliographyItemAttrs) => {
|
|
319
215
|
clearImportSuccess()
|
|
320
|
-
|
|
321
|
-
if (values && selection && !isEqual(values, normalize(selection))) {
|
|
216
|
+
if (hasChanged()) {
|
|
322
217
|
setConfirm(true)
|
|
323
218
|
return
|
|
324
219
|
}
|
|
220
|
+
setIsNew(false)
|
|
325
221
|
setSelection(item)
|
|
326
222
|
}
|
|
327
223
|
|
|
@@ -336,10 +232,6 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
336
232
|
setImportSuccessCount(data.length)
|
|
337
233
|
}
|
|
338
234
|
|
|
339
|
-
if (sortedItems.length <= 0) {
|
|
340
|
-
return <></>
|
|
341
|
-
}
|
|
342
|
-
|
|
343
235
|
return (
|
|
344
236
|
<>
|
|
345
237
|
{importing && (
|
|
@@ -375,7 +267,28 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
375
267
|
<ModalSidebarTitle>References</ModalSidebarTitle>
|
|
376
268
|
</ModalSidebarHeader>
|
|
377
269
|
<ReferencesSidebarContent ref={ref}>
|
|
270
|
+
<NewReferenceButton
|
|
271
|
+
onClick={() => {
|
|
272
|
+
if (hasChanged()) {
|
|
273
|
+
setConfirm(true)
|
|
274
|
+
return
|
|
275
|
+
}
|
|
276
|
+
setIsNew(true)
|
|
277
|
+
setSelection({
|
|
278
|
+
id: generateNodeID(schema.nodes.bibliography_item),
|
|
279
|
+
type: 'article-journal',
|
|
280
|
+
})
|
|
281
|
+
}}
|
|
282
|
+
className={isNew ? 'selected' : ''}
|
|
283
|
+
disabled={isNew}
|
|
284
|
+
>
|
|
285
|
+
<AddIcon />
|
|
286
|
+
<span>New Reference</span>
|
|
287
|
+
</NewReferenceButton>
|
|
378
288
|
<ReferencesInnerWrapper>
|
|
289
|
+
<ExistingReferencesHeading>
|
|
290
|
+
Existing References
|
|
291
|
+
</ExistingReferencesHeading>
|
|
379
292
|
{sortedItems.slice(startIndex, endIndex + 1).map((item) => (
|
|
380
293
|
<ReferenceButton
|
|
381
294
|
key={item.id}
|
|
@@ -385,7 +298,7 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
385
298
|
ref={isSelected(item) ? selectionRef : null}
|
|
386
299
|
>
|
|
387
300
|
<IconContainer>
|
|
388
|
-
<
|
|
301
|
+
<CitationCountIconStyled />
|
|
389
302
|
{(citationCounts.get(item.id) || 0) > 0 ? (
|
|
390
303
|
<CitationCount data-tooltip-content="Number of times used in the document">
|
|
391
304
|
{citationCounts.get(item.id)}
|
|
@@ -394,7 +307,10 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
394
307
|
<CitationCount className="unused">0</CitationCount>
|
|
395
308
|
)}
|
|
396
309
|
</IconContainer>
|
|
397
|
-
<ReferenceLine
|
|
310
|
+
<ReferenceLine
|
|
311
|
+
showUncited={!citationCounts.get(item.id)}
|
|
312
|
+
item={item}
|
|
313
|
+
/>
|
|
398
314
|
</ReferenceButton>
|
|
399
315
|
))}
|
|
400
316
|
</ReferencesInnerWrapper>
|
|
@@ -416,7 +332,7 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
416
332
|
) : (
|
|
417
333
|
selection && (
|
|
418
334
|
<ReferenceForm
|
|
419
|
-
values={
|
|
335
|
+
values={normalizeBlblioItem(selection)}
|
|
420
336
|
showDelete={
|
|
421
337
|
!citationCounts.get(selection.id) &&
|
|
422
338
|
isNewItem(selection, ['id', 'type']) // disable the delete button for the new citations
|
|
@@ -436,3 +352,125 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
436
352
|
</>
|
|
437
353
|
)
|
|
438
354
|
}
|
|
355
|
+
|
|
356
|
+
const ReferencesModalContainer = styled(ModalContainer)`
|
|
357
|
+
min-width: 960px;
|
|
358
|
+
`
|
|
359
|
+
|
|
360
|
+
const ReferencesSidebar = styled(ModalSidebar)`
|
|
361
|
+
width: 70%;
|
|
362
|
+
`
|
|
363
|
+
|
|
364
|
+
const ReferencesSidebarContent = styled(SidebarContent)`
|
|
365
|
+
overflow-y: auto;
|
|
366
|
+
`
|
|
367
|
+
|
|
368
|
+
const ReferencesInnerWrapper = withListNavigation(styled.div`
|
|
369
|
+
width: 100%;
|
|
370
|
+
padding: 12px 0;
|
|
371
|
+
`)
|
|
372
|
+
|
|
373
|
+
const CitationCountIconStyled = styled(CitationCountIcon)``
|
|
374
|
+
|
|
375
|
+
const ReferenceButton = withNavigableListItem(styled.button`
|
|
376
|
+
cursor: pointer;
|
|
377
|
+
display: flex;
|
|
378
|
+
width: 100%;
|
|
379
|
+
justify-content: flex-start;
|
|
380
|
+
font: inherit;
|
|
381
|
+
appearance: none;
|
|
382
|
+
-webkit-appearance: none;
|
|
383
|
+
background: none;
|
|
384
|
+
border: none;
|
|
385
|
+
border-radius: 0;
|
|
386
|
+
text-align: inherit;
|
|
387
|
+
|
|
388
|
+
padding: ${(props) => props.theme.grid.unit * 4}px 0;
|
|
389
|
+
border-top: 1px solid transparent;
|
|
390
|
+
border-bottom: 1px solid transparent;
|
|
391
|
+
|
|
392
|
+
${CitationCountIconStyled} path {
|
|
393
|
+
fill: #c9c9c9;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
&:hover {
|
|
397
|
+
background: ${(props) => props.theme.colors.background.info};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
&.selected {
|
|
401
|
+
background: ${(props) => props.theme.colors.background.info};
|
|
402
|
+
border-top-color: #bce7f6;
|
|
403
|
+
border-bottom-color: #bce7f6;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.tooltip {
|
|
407
|
+
max-width: ${(props) => props.theme.grid.unit * 25}px;
|
|
408
|
+
padding: ${(props) => props.theme.grid.unit * 2}px;
|
|
409
|
+
border-radius: 6px;
|
|
410
|
+
}
|
|
411
|
+
`)
|
|
412
|
+
|
|
413
|
+
const IconContainer = styled.div`
|
|
414
|
+
padding-right: ${(props) => props.theme.grid.unit * 5}px;
|
|
415
|
+
position: relative;
|
|
416
|
+
`
|
|
417
|
+
|
|
418
|
+
const CitationCount = styled.div`
|
|
419
|
+
border-radius: 50%;
|
|
420
|
+
width: 12px;
|
|
421
|
+
height: 12px;
|
|
422
|
+
position: absolute;
|
|
423
|
+
color: #ffffff;
|
|
424
|
+
background-color: #bce7f6;
|
|
425
|
+
text-align: center;
|
|
426
|
+
vertical-align: top;
|
|
427
|
+
top: 0;
|
|
428
|
+
left: 16px;
|
|
429
|
+
font-size: 9px;
|
|
430
|
+
|
|
431
|
+
&.unused {
|
|
432
|
+
background-color: #fe8f1f;
|
|
433
|
+
}
|
|
434
|
+
`
|
|
435
|
+
|
|
436
|
+
const NewReferenceButton = styled(ReferenceButton)`
|
|
437
|
+
svg {
|
|
438
|
+
margin-right: 8px;
|
|
439
|
+
}
|
|
440
|
+
`
|
|
441
|
+
const ExistingReferencesHeading = styled.h3`
|
|
442
|
+
font-size: 18px;
|
|
443
|
+
font-style: normal;
|
|
444
|
+
font-weight: 400;
|
|
445
|
+
padding: 8px 0 20px;
|
|
446
|
+
margin: 0;
|
|
447
|
+
color: #6e6e6e;
|
|
448
|
+
`
|
|
449
|
+
const ImportFromFileFooter = styled.div`
|
|
450
|
+
padding: 16px;
|
|
451
|
+
`
|
|
452
|
+
|
|
453
|
+
const ImportFromFileButton = styled.button`
|
|
454
|
+
display: flex;
|
|
455
|
+
width: 100%;
|
|
456
|
+
padding: 8px 24px;
|
|
457
|
+
justify-content: center;
|
|
458
|
+
align-items: center;
|
|
459
|
+
gap: 8px;
|
|
460
|
+
border-radius: 4px;
|
|
461
|
+
border: 1px dashed #c9c9c9;
|
|
462
|
+
background: #fafafa;
|
|
463
|
+
cursor: pointer;
|
|
464
|
+
font-family: ${(props) => props.theme.font.family.sans};
|
|
465
|
+
font-size: 14px;
|
|
466
|
+
color: #353535;
|
|
467
|
+
|
|
468
|
+
svg {
|
|
469
|
+
width: 20px;
|
|
470
|
+
height: 20px;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
svg rect {
|
|
474
|
+
fill: #6e6e6e;
|
|
475
|
+
}
|
|
476
|
+
`
|
|
@@ -137,6 +137,7 @@ export default (
|
|
|
137
137
|
headshot_element: headshotElement(props, dispatch),
|
|
138
138
|
headshot_image: headshotImage(props, dispatch),
|
|
139
139
|
abstracts: abstracts(props),
|
|
140
|
+
abstract: section(props),
|
|
140
141
|
trans_abstract: transAbstract(props),
|
|
141
142
|
trans_graphical_abstract: transGraphicalAbstract(props),
|
|
142
143
|
attachment: attachment(props, dispatch),
|
package/src/icons.ts
CHANGED
|
@@ -47,7 +47,7 @@ import { renderToStaticMarkup } from 'react-dom/server'
|
|
|
47
47
|
|
|
48
48
|
const renderIcon = (c: React.FC) => renderToStaticMarkup(createElement(c))
|
|
49
49
|
|
|
50
|
-
export const
|
|
50
|
+
export const addIcon = renderIcon(AddAuthorIcon)
|
|
51
51
|
export const arrowDown = renderIcon(ArrowDownCircleIcon)
|
|
52
52
|
export const arrowUp = renderIcon(ArrowUpIcon)
|
|
53
53
|
export const alertIcon = renderIcon(AlertIcon)
|
package/src/lib/context-menu.ts
CHANGED
|
@@ -397,7 +397,10 @@ export class ContextMenu {
|
|
|
397
397
|
this.createMenuSection((section: HTMLElement) => {
|
|
398
398
|
let nodeName = nodeNames.get(type) || ''
|
|
399
399
|
if (type === schema.nodes.section_title) {
|
|
400
|
-
|
|
400
|
+
const containerType = $pos.parent.type
|
|
401
|
+
nodeName =
|
|
402
|
+
nodeNames.get(containerType) ??
|
|
403
|
+
(nodeNames.get(schema.nodes.section) as string)
|
|
401
404
|
}
|
|
402
405
|
section.appendChild(
|
|
403
406
|
this.createMenuItem(`Delete ${nodeName}`, () => {
|
package/src/lib/normalize.ts
CHANGED
|
@@ -14,7 +14,12 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
BibliographyItemAttrs,
|
|
19
|
+
generateNodeID,
|
|
20
|
+
Nodes,
|
|
21
|
+
schema,
|
|
22
|
+
} from '@manuscripts/transform'
|
|
18
23
|
|
|
19
24
|
import { AffiliationAttrs, ContributorAttrs } from './authors'
|
|
20
25
|
|
|
@@ -68,3 +73,33 @@ export const checkID = <T extends WithID>(attrs: T, nodeType: Nodes) => {
|
|
|
68
73
|
id: attrs.id || generateNodeID(schema.nodes[nodeType]),
|
|
69
74
|
}
|
|
70
75
|
}
|
|
76
|
+
|
|
77
|
+
export const normalizeBlblioItem = (item: BibliographyItemAttrs) => ({
|
|
78
|
+
id: item.id,
|
|
79
|
+
type: item.type,
|
|
80
|
+
author: item.author || [],
|
|
81
|
+
editor: item.editor || [],
|
|
82
|
+
issued: item.issued,
|
|
83
|
+
['container-title']: item['container-title'] || '',
|
|
84
|
+
['collection-title']: item['collection-title'] || '',
|
|
85
|
+
DOI: item.DOI || '',
|
|
86
|
+
URL: item.URL || '',
|
|
87
|
+
volume: item.volume || '',
|
|
88
|
+
issue: item.issue || '',
|
|
89
|
+
supplement: item.supplement || '',
|
|
90
|
+
edition: item.edition || '',
|
|
91
|
+
page: item.page || '',
|
|
92
|
+
['number-of-pages']: item['number-of-pages'] || '',
|
|
93
|
+
title: item.title || '',
|
|
94
|
+
literal: item.literal || '',
|
|
95
|
+
std: item.std || '',
|
|
96
|
+
publisher: item.publisher || '',
|
|
97
|
+
['publisher-place']: item['publisher-place'] || '',
|
|
98
|
+
event: item.event || '',
|
|
99
|
+
['event-place']: item['event-place'] || '',
|
|
100
|
+
['event-date']: item['event-date'],
|
|
101
|
+
institution: item.institution || '',
|
|
102
|
+
locator: item.locator || '',
|
|
103
|
+
accessed: item.accessed,
|
|
104
|
+
comment: item.comment || '',
|
|
105
|
+
})
|
package/src/lib/paste.ts
CHANGED
|
@@ -109,7 +109,6 @@ export const transformPastedHTML = (html: string) => {
|
|
|
109
109
|
const doc = new DOMParser().parseFromString(html, 'text/html')
|
|
110
110
|
wrapHeadingWithSection(doc)
|
|
111
111
|
wrapTableWithFigure(doc)
|
|
112
|
-
console.log(doc.body.innerHTML)
|
|
113
112
|
return doc.body.innerHTML
|
|
114
113
|
}
|
|
115
114
|
|
package/src/menus.tsx
CHANGED
|
@@ -563,7 +563,7 @@ export const getEditorMenus = (
|
|
|
563
563
|
const abstractSection = allAbstractsCategories.find(
|
|
564
564
|
(s) => s.id === ABSTRACT_ID
|
|
565
565
|
)
|
|
566
|
-
const ABSTRACT_GRAPHICAL_ID = '
|
|
566
|
+
const ABSTRACT_GRAPHICAL_ID = 'graphical'
|
|
567
567
|
const graphicalAbstractSection = allAbstractsCategories.find(
|
|
568
568
|
(s) => s.id === ABSTRACT_GRAPHICAL_ID
|
|
569
569
|
)
|
package/src/node-type-icons.tsx
CHANGED
|
@@ -69,6 +69,7 @@ const icons: Map<
|
|
|
69
69
|
[nodes.paragraph, OutlineParagraphIcon],
|
|
70
70
|
[nodes.pullquote_element, OutlinePullQuoteIcon],
|
|
71
71
|
[nodes.section, OutlineSectionIcon],
|
|
72
|
+
[nodes.abstract, OutlineSectionIcon],
|
|
72
73
|
[nodes.table_element, OutlineTableIcon],
|
|
73
74
|
[nodes.graphical_abstract_section, OutlineSectionIcon],
|
|
74
75
|
[nodes.trans_graphical_abstract, OutlineSectionIcon],
|
|
@@ -20,14 +20,14 @@ import { Decoration, DecorationSet } from 'prosemirror-view'
|
|
|
20
20
|
import { v4 as uuidv4 } from 'uuid'
|
|
21
21
|
|
|
22
22
|
import { EditorProps } from '../configs/ManuscriptsEditor'
|
|
23
|
-
import {
|
|
23
|
+
import { addIcon } from '../icons'
|
|
24
24
|
import { handleEnterKey } from '../lib/navigation-utils'
|
|
25
25
|
import { findInsertionPosition } from '../lib/utils'
|
|
26
26
|
|
|
27
27
|
const createAddSubtitleButton = (handler: () => void) => {
|
|
28
28
|
const button = document.createElement('span')
|
|
29
29
|
button.className = 'add-subtitle'
|
|
30
|
-
button.innerHTML = `${
|
|
30
|
+
button.innerHTML = `${addIcon} <span class="add-subtitle-text">Add subtitle</span>`
|
|
31
31
|
|
|
32
32
|
button.tabIndex = 0
|
|
33
33
|
const activate = (event: MouseEvent | KeyboardEvent) => {
|
|
@@ -120,7 +120,7 @@ const buildBibliographyPluginState = (
|
|
|
120
120
|
$new.engine = $old.engine
|
|
121
121
|
$new.renderedCitations = $old.renderedCitations
|
|
122
122
|
} else {
|
|
123
|
-
const citationCounts = new Map()
|
|
123
|
+
const citationCounts = new Map<string, number>()
|
|
124
124
|
const rids = nodes.flatMap((e) => e[0].attrs.rids)
|
|
125
125
|
rids.forEach((rid) => {
|
|
126
126
|
const count = citationCounts.get(rid) || 0
|
|
@@ -142,10 +142,17 @@ const buildBibliographyPluginState = (
|
|
|
142
142
|
csl.style,
|
|
143
143
|
'en-US'
|
|
144
144
|
)
|
|
145
|
-
|
|
145
|
+
const uncitedIds: string[] = []
|
|
146
|
+
bibliographyItems.forEach((item, id) => {
|
|
147
|
+
if (!rids.includes(id)) {
|
|
148
|
+
uncitedIds.push(id)
|
|
149
|
+
}
|
|
150
|
+
})
|
|
146
151
|
//create new citations since citeproc modifies the ones passed
|
|
147
152
|
const citationTexts = engine.rebuildProcessorState(
|
|
148
|
-
nodes.map(([node]) => buildCiteprocCitation(node.attrs))
|
|
153
|
+
nodes.map(([node]) => buildCiteprocCitation(node.attrs)),
|
|
154
|
+
'html',
|
|
155
|
+
uncitedIds
|
|
149
156
|
)
|
|
150
157
|
|
|
151
158
|
$new.version = String(version++)
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import {
|
|
17
17
|
getGroupCategories,
|
|
18
|
+
isAbstractNode,
|
|
18
19
|
isSectionNode,
|
|
19
20
|
schema,
|
|
20
21
|
SectionCategory,
|
|
@@ -154,7 +155,8 @@ const buildPluginState = (
|
|
|
154
155
|
if (node.type === schema.nodes.box_element) {
|
|
155
156
|
return false
|
|
156
157
|
}
|
|
157
|
-
|
|
158
|
+
|
|
159
|
+
if (isSectionNode(node) || isAbstractNode(node)) {
|
|
158
160
|
const categoryID = node.attrs.category
|
|
159
161
|
const category = categories.get(categoryID)
|
|
160
162
|
const $pos = state.doc.resolve(pos)
|
|
@@ -191,7 +193,10 @@ const buildPluginState = (
|
|
|
191
193
|
}
|
|
192
194
|
|
|
193
195
|
const getUsedSectionCategoryIDs = (state: EditorState): Set<string> => {
|
|
194
|
-
const sections =
|
|
196
|
+
const sections = [
|
|
197
|
+
...findChildrenByType(state.doc, schema.nodes.section),
|
|
198
|
+
...findChildrenByType(state.doc, schema.nodes.abstract),
|
|
199
|
+
]
|
|
195
200
|
const used = new Set<string>()
|
|
196
201
|
sections.forEach(({ node }) => {
|
|
197
202
|
if (node.attrs.category) {
|