@manuscripts/body-editor 3.19.0 → 3.19.1
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/ReferenceForm/ReferenceForm.js +22 -40
- package/dist/cjs/components/references/ReferenceForm/styled-components.js +1 -13
- package/dist/cjs/components/references/ReferencesEditor.js +26 -1
- package/dist/cjs/components/references/ReferencesModal.js +71 -7
- package/dist/cjs/menus.js +12 -0
- package/dist/cjs/versions.js +1 -1
- package/dist/es/components/references/ReferenceForm/ReferenceForm.js +21 -40
- package/dist/es/components/references/ReferenceForm/styled-components.js +0 -12
- package/dist/es/components/references/ReferencesEditor.js +21 -0
- package/dist/es/components/references/ReferencesModal.js +73 -9
- package/dist/es/menus.js +12 -0
- package/dist/es/versions.js +1 -1
- package/dist/types/components/references/ReferenceForm/ReferenceForm.d.ts +3 -3
- package/dist/types/components/references/ReferenceForm/styled-components.d.ts +0 -1
- package/dist/types/components/references/ReferencesEditor.d.ts +3 -0
- package/dist/types/versions.d.ts +1 -1
- package/package.json +2 -2
- package/src/components/references/ReferenceForm/ReferenceForm.tsx +21 -82
- package/src/components/references/ReferenceForm/styled-components.ts +0 -13
- package/src/components/references/ReferencesEditor.tsx +38 -0
- package/src/components/references/ReferencesModal.tsx +116 -14
- package/src/lib/view.ts +1 -0
- package/src/menus.tsx +12 -0
- package/src/versions.ts +1 -1
|
@@ -32,7 +32,12 @@ import {
|
|
|
32
32
|
useScrollDetection,
|
|
33
33
|
withListNavigation,
|
|
34
34
|
withNavigableListItem,
|
|
35
|
+
ButtonGroup,
|
|
36
|
+
DeleteIcon,
|
|
37
|
+
LinkIcon,
|
|
38
|
+
outlineStyle,
|
|
35
39
|
} from '@manuscripts/style-guide'
|
|
40
|
+
import { Button, IconButton } from '@manuscripts/style-guide/mui'
|
|
36
41
|
import {
|
|
37
42
|
BibliographyItemAttrs,
|
|
38
43
|
generateNodeID,
|
|
@@ -40,11 +45,12 @@ import {
|
|
|
40
45
|
} from '@manuscripts/transform'
|
|
41
46
|
import isEqual from 'lodash/isEqual'
|
|
42
47
|
import React, { useEffect, useMemo, useRef, useState } from 'react'
|
|
43
|
-
import styled from 'styled-components'
|
|
48
|
+
import styled, { css } from 'styled-components'
|
|
44
49
|
|
|
45
50
|
import {
|
|
46
51
|
ReferenceForm,
|
|
47
52
|
ReferenceFormActions,
|
|
53
|
+
validateReference,
|
|
48
54
|
} from './ReferenceForm/ReferenceForm'
|
|
49
55
|
import { ReferenceLine } from './ReferenceLine'
|
|
50
56
|
import { ImportBibliographyModal } from './ImportBibliographyModal'
|
|
@@ -87,6 +93,7 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
87
93
|
|
|
88
94
|
const [selection, setSelection] = useState<BibliographyItemAttrs>()
|
|
89
95
|
const [isNew, setIsNew] = useState<boolean>(false)
|
|
96
|
+
const [showDeleteDialog, setShowDeleteDialog] = useState(false)
|
|
90
97
|
const selectionRef = useRef<HTMLDivElement>(null)
|
|
91
98
|
|
|
92
99
|
const sortedItems = useMemo(
|
|
@@ -173,6 +180,12 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
173
180
|
return extraKeys.length > 0
|
|
174
181
|
}
|
|
175
182
|
|
|
183
|
+
const canDeleteSelectedItem =
|
|
184
|
+
(selection &&
|
|
185
|
+
!citationCounts.get(selection.id) &&
|
|
186
|
+
isNewItem(selection, ['id', 'type'])) ??
|
|
187
|
+
false
|
|
188
|
+
|
|
176
189
|
const handleSave = (values: BibliographyItemAttrs | undefined) => {
|
|
177
190
|
if (!values || !selection) {
|
|
178
191
|
return
|
|
@@ -221,8 +234,14 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
221
234
|
setSelection(item)
|
|
222
235
|
}
|
|
223
236
|
|
|
237
|
+
const [canSave, setCanSave] = useState(false)
|
|
238
|
+
|
|
224
239
|
const handleChange = (values: BibliographyItemAttrs) => {
|
|
225
240
|
valuesRef.current = values
|
|
241
|
+
const errors = validateReference(values)
|
|
242
|
+
const isValid = Object.keys(errors).length === 0
|
|
243
|
+
const dirty = actionsRef.current?.isDirty() ?? false
|
|
244
|
+
setCanSave(isValid && dirty)
|
|
226
245
|
}
|
|
227
246
|
|
|
228
247
|
const handleImportSave = (data: BibliographyItemAttrs[]) => {
|
|
@@ -257,6 +276,25 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
257
276
|
},
|
|
258
277
|
}}
|
|
259
278
|
/>
|
|
279
|
+
<Dialog
|
|
280
|
+
isOpen={showDeleteDialog}
|
|
281
|
+
category={Category.confirmation}
|
|
282
|
+
header="Delete Reference"
|
|
283
|
+
message="Are you sure you want to delete this reference from the list?"
|
|
284
|
+
actions={{
|
|
285
|
+
secondary: {
|
|
286
|
+
action: () => {
|
|
287
|
+
handleDelete()
|
|
288
|
+
setShowDeleteDialog(false)
|
|
289
|
+
},
|
|
290
|
+
title: 'Delete',
|
|
291
|
+
},
|
|
292
|
+
primary: {
|
|
293
|
+
action: () => setShowDeleteDialog(false),
|
|
294
|
+
title: 'Cancel',
|
|
295
|
+
},
|
|
296
|
+
}}
|
|
297
|
+
/>
|
|
260
298
|
<ReferencesModalContainer data-cy={'references-editor'}>
|
|
261
299
|
<ModalHeader>
|
|
262
300
|
<CloseButton data-cy="modal-close-button" onClick={onCancel} />
|
|
@@ -286,9 +324,11 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
286
324
|
<span>New Reference</span>
|
|
287
325
|
</NewReferenceButton>
|
|
288
326
|
<ReferencesInnerWrapper>
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
327
|
+
{sortedItems.length ? (
|
|
328
|
+
<ExistingReferencesHeading>
|
|
329
|
+
Existing References
|
|
330
|
+
</ExistingReferencesHeading>
|
|
331
|
+
) : null}
|
|
292
332
|
{sortedItems.slice(startIndex, endIndex + 1).map((item) => (
|
|
293
333
|
<ReferenceButton
|
|
294
334
|
key={item.id}
|
|
@@ -311,6 +351,25 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
311
351
|
showUncited={!citationCounts.get(item.id)}
|
|
312
352
|
item={item}
|
|
313
353
|
/>
|
|
354
|
+
{isSelected(item) && (
|
|
355
|
+
<ButtonGroup>
|
|
356
|
+
<IconButton
|
|
357
|
+
component={'a'}
|
|
358
|
+
href={`https://doi.org/${item.DOI}`}
|
|
359
|
+
target={'_blank'}
|
|
360
|
+
size={'small'}
|
|
361
|
+
>
|
|
362
|
+
<DOILinkIcon fill={'#6E6E6E'} />
|
|
363
|
+
</IconButton>
|
|
364
|
+
<IconButton
|
|
365
|
+
disabled={!canDeleteSelectedItem}
|
|
366
|
+
size={'small'}
|
|
367
|
+
onClick={() => setShowDeleteDialog(true)}
|
|
368
|
+
>
|
|
369
|
+
<DeleteIcon fill={'#6E6E6E'} />
|
|
370
|
+
</IconButton>
|
|
371
|
+
</ButtonGroup>
|
|
372
|
+
)}
|
|
314
373
|
</ReferenceButton>
|
|
315
374
|
))}
|
|
316
375
|
</ReferencesInnerWrapper>
|
|
@@ -326,27 +385,32 @@ export const ReferencesModal: React.FC<ReferencesModalProps> = ({
|
|
|
326
385
|
</ImportFromFileButton>
|
|
327
386
|
</ImportFromFileFooter>
|
|
328
387
|
</ReferencesSidebar>
|
|
329
|
-
<
|
|
388
|
+
<ReferencesContent>
|
|
330
389
|
{importSuccessCount !== null ? (
|
|
331
390
|
<ImportSuccessPlaceholder count={importSuccessCount} />
|
|
332
391
|
) : (
|
|
333
392
|
selection && (
|
|
334
393
|
<ReferenceForm
|
|
335
394
|
values={normalizeBlblioItem(selection)}
|
|
336
|
-
showDelete={
|
|
337
|
-
!citationCounts.get(selection.id) &&
|
|
338
|
-
isNewItem(selection, ['id', 'type']) // disable the delete button for the new citations
|
|
339
|
-
}
|
|
340
395
|
onChange={handleChange}
|
|
341
|
-
onCancel={onCancel}
|
|
342
|
-
onDelete={handleDelete}
|
|
343
396
|
onSave={handleSave}
|
|
344
397
|
actionsRef={actionsRef}
|
|
345
398
|
/>
|
|
346
399
|
)
|
|
347
400
|
)}
|
|
348
|
-
</
|
|
401
|
+
</ReferencesContent>
|
|
349
402
|
</ModalBody>
|
|
403
|
+
<Footer>
|
|
404
|
+
<TertiaryButton variant="tertiary" onClick={onCancel}>
|
|
405
|
+
Close
|
|
406
|
+
</TertiaryButton>
|
|
407
|
+
<Button
|
|
408
|
+
disabled={!canSave}
|
|
409
|
+
onClick={() => actionsRef.current?.submit()}
|
|
410
|
+
>
|
|
411
|
+
Save Changes
|
|
412
|
+
</Button>
|
|
413
|
+
</Footer>
|
|
350
414
|
</ReferencesModalContainer>
|
|
351
415
|
</StyledModal>
|
|
352
416
|
</>
|
|
@@ -361,8 +425,13 @@ const ReferencesSidebar = styled(ModalSidebar)`
|
|
|
361
425
|
width: 70%;
|
|
362
426
|
`
|
|
363
427
|
|
|
428
|
+
const ReferencesContent = styled(ScrollableModalContent)`
|
|
429
|
+
padding-top: 32px;
|
|
430
|
+
`
|
|
431
|
+
|
|
364
432
|
const ReferencesSidebarContent = styled(SidebarContent)`
|
|
365
433
|
overflow-y: auto;
|
|
434
|
+
padding-top: 8px;
|
|
366
435
|
`
|
|
367
436
|
|
|
368
437
|
const ReferencesInnerWrapper = withListNavigation(styled.div`
|
|
@@ -372,7 +441,7 @@ const ReferencesInnerWrapper = withListNavigation(styled.div`
|
|
|
372
441
|
|
|
373
442
|
const CitationCountIconStyled = styled(CitationCountIcon)``
|
|
374
443
|
|
|
375
|
-
const
|
|
444
|
+
const referenceButtonStyles = css`
|
|
376
445
|
cursor: pointer;
|
|
377
446
|
display: flex;
|
|
378
447
|
width: 100%;
|
|
@@ -384,6 +453,7 @@ const ReferenceButton = withNavigableListItem(styled.button`
|
|
|
384
453
|
border: none;
|
|
385
454
|
border-radius: 0;
|
|
386
455
|
text-align: inherit;
|
|
456
|
+
color: #353535;
|
|
387
457
|
|
|
388
458
|
padding: ${(props) => props.theme.grid.unit * 4}px 0;
|
|
389
459
|
border-top: 1px solid transparent;
|
|
@@ -408,6 +478,13 @@ const ReferenceButton = withNavigableListItem(styled.button`
|
|
|
408
478
|
padding: ${(props) => props.theme.grid.unit * 2}px;
|
|
409
479
|
border-radius: 6px;
|
|
410
480
|
}
|
|
481
|
+
`
|
|
482
|
+
|
|
483
|
+
const ReferenceButton = withNavigableListItem(styled.div.attrs({
|
|
484
|
+
role: 'button',
|
|
485
|
+
tabIndex: 0,
|
|
486
|
+
})`
|
|
487
|
+
${referenceButtonStyles}
|
|
411
488
|
`)
|
|
412
489
|
|
|
413
490
|
const IconContainer = styled.div`
|
|
@@ -433,10 +510,14 @@ const CitationCount = styled.div`
|
|
|
433
510
|
}
|
|
434
511
|
`
|
|
435
512
|
|
|
436
|
-
const NewReferenceButton = styled
|
|
513
|
+
const NewReferenceButton = styled.button`
|
|
514
|
+
${referenceButtonStyles}
|
|
515
|
+
|
|
437
516
|
svg {
|
|
438
517
|
margin-right: 8px;
|
|
439
518
|
}
|
|
519
|
+
|
|
520
|
+
${outlineStyle}
|
|
440
521
|
`
|
|
441
522
|
const ExistingReferencesHeading = styled.h3`
|
|
442
523
|
font-size: 18px;
|
|
@@ -474,3 +555,24 @@ const ImportFromFileButton = styled.button`
|
|
|
474
555
|
fill: #6e6e6e;
|
|
475
556
|
}
|
|
476
557
|
`
|
|
558
|
+
|
|
559
|
+
const Footer = styled.div`
|
|
560
|
+
display: flex;
|
|
561
|
+
justify-content: flex-end;
|
|
562
|
+
padding: 16px 32px;
|
|
563
|
+
gap: 16px;
|
|
564
|
+
`
|
|
565
|
+
|
|
566
|
+
const TertiaryButton = styled(Button)`
|
|
567
|
+
&.MuiButton-textSecondary {
|
|
568
|
+
color: #0d79d0;
|
|
569
|
+
|
|
570
|
+
&:hover {
|
|
571
|
+
background-color: rgba(13, 121, 208, 0.04);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
`
|
|
575
|
+
|
|
576
|
+
const DOILinkIcon = styled(LinkIcon)`
|
|
577
|
+
transform: rotate(-45deg);
|
|
578
|
+
`
|
package/src/lib/view.ts
CHANGED
package/src/menus.tsx
CHANGED
|
@@ -66,6 +66,7 @@ import { isEditAllowed } from './lib/utils'
|
|
|
66
66
|
import { getEditorProps } from './plugins/editor-props'
|
|
67
67
|
import { useEditor } from './useEditor'
|
|
68
68
|
import { openInsertAwardModal } from './components/awards/AwardModal'
|
|
69
|
+
import { openReferencesEditor } from './components/references/ReferencesEditor'
|
|
69
70
|
|
|
70
71
|
export const getEditorMenus = (
|
|
71
72
|
editor: ReturnType<typeof useEditor>
|
|
@@ -652,6 +653,17 @@ export const getEditorMenus = (
|
|
|
652
653
|
run: doCommand(insertInlineCitation),
|
|
653
654
|
isHidden: !templateAllows(state, schema.nodes.citation),
|
|
654
655
|
},
|
|
656
|
+
{
|
|
657
|
+
id: 'insert-reference-section',
|
|
658
|
+
label: 'New reference',
|
|
659
|
+
shortcut: {
|
|
660
|
+
mac: 'Option+CommandOrControl+N',
|
|
661
|
+
pc: 'CommandOrControl+Option+N',
|
|
662
|
+
},
|
|
663
|
+
isEnabled: isEditAllowed(state),
|
|
664
|
+
run: doCommand(openReferencesEditor),
|
|
665
|
+
isHidden: !templateAllows(state, schema.nodes.bibliography_item),
|
|
666
|
+
},
|
|
655
667
|
{
|
|
656
668
|
id: 'insert-cross-reference',
|
|
657
669
|
label: 'Cross-reference',
|
package/src/versions.ts
CHANGED