@manuscripts/body-editor 3.17.5 → 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.
Files changed (43) hide show
  1. package/dist/cjs/components/references/ReferenceLine.js +14 -1
  2. package/dist/cjs/components/references/ReferencesModal.js +155 -131
  3. package/dist/cjs/icons.js +2 -2
  4. package/dist/cjs/lib/normalize.js +31 -1
  5. package/dist/cjs/lib/paste.js +0 -1
  6. package/dist/cjs/plugins/add-subtitle.js +1 -1
  7. package/dist/cjs/plugins/bibliography.js +7 -1
  8. package/dist/cjs/plugins/translations.js +1 -1
  9. package/dist/cjs/versions.js +1 -1
  10. package/dist/cjs/views/bibliography_element.js +44 -2
  11. package/dist/cjs/views/figure_element.js +1 -1
  12. package/dist/cjs/views/headshot_grid.js +1 -1
  13. package/dist/es/components/references/ReferenceLine.js +14 -1
  14. package/dist/es/components/references/ReferencesModal.js +156 -132
  15. package/dist/es/icons.js +1 -1
  16. package/dist/es/lib/normalize.js +30 -1
  17. package/dist/es/lib/paste.js +0 -1
  18. package/dist/es/plugins/add-subtitle.js +2 -2
  19. package/dist/es/plugins/bibliography.js +7 -1
  20. package/dist/es/plugins/translations.js +2 -2
  21. package/dist/es/versions.js +1 -1
  22. package/dist/es/views/bibliography_element.js +45 -3
  23. package/dist/es/views/figure_element.js +2 -2
  24. package/dist/es/views/headshot_grid.js +2 -2
  25. package/dist/types/components/references/ReferenceLine.d.ts +1 -0
  26. package/dist/types/icons.d.ts +1 -1
  27. package/dist/types/lib/normalize.d.ts +30 -1
  28. package/dist/types/versions.d.ts +1 -1
  29. package/dist/types/views/bibliography_element.d.ts +5 -1
  30. package/package.json +1 -1
  31. package/src/components/references/ReferenceLine.tsx +16 -1
  32. package/src/components/references/ReferencesModal.tsx +178 -140
  33. package/src/icons.ts +1 -1
  34. package/src/lib/normalize.ts +36 -1
  35. package/src/lib/paste.ts +0 -1
  36. package/src/plugins/add-subtitle.ts +2 -2
  37. package/src/plugins/bibliography.ts +10 -3
  38. package/src/plugins/translations.ts +2 -2
  39. package/src/versions.ts +1 -1
  40. package/src/views/bibliography_element.ts +61 -4
  41. package/src/views/figure_element.ts +2 -2
  42. package/src/views/headshot_grid.ts +2 -2
  43. package/styles/AdvancedEditor.css +29 -2
@@ -1,4 +1,5 @@
1
- import { AddAuthorIcon, Category, CitationCountIcon, CloseButton, Dialog, ModalBody, ModalContainer, ModalHeader, ModalSidebar, ModalSidebarHeader, ModalSidebarTitle, ScrollableModalContent, SidebarContent, StyledModal, useScrollDetection, withListNavigation, withNavigableListItem, } from '@manuscripts/style-guide';
1
+ import { AddIcon, AddAuthorIcon, Category, CitationCountIcon, CloseButton, Dialog, ModalBody, ModalContainer, ModalHeader, ModalSidebar, ModalSidebarHeader, ModalSidebarTitle, ScrollableModalContent, SidebarContent, StyledModal, useScrollDetection, withListNavigation, withNavigableListItem, } from '@manuscripts/style-guide';
2
+ import { generateNodeID, schema, } from '@manuscripts/transform';
2
3
  import isEqual from 'lodash/isEqual';
3
4
  import React, { useEffect, useMemo, useRef, useState } from 'react';
4
5
  import styled from 'styled-components';
@@ -6,135 +7,19 @@ import { ReferenceForm, } from './ReferenceForm/ReferenceForm';
6
7
  import { ReferenceLine } from './ReferenceLine';
7
8
  import { ImportBibliographyModal } from './ImportBibliographyModal';
8
9
  import { ImportSuccessPlaceholder } from './ImportSuccessPlaceholder';
9
- const ReferencesModalContainer = styled(ModalContainer) `
10
- min-width: 960px;
11
- `;
12
- const ReferencesSidebar = styled(ModalSidebar) `
13
- width: 70%;
14
- `;
15
- const ReferencesSidebarContent = styled(SidebarContent) `
16
- overflow-y: auto;
17
- `;
18
- const ImportFromFileFooter = styled.div `
19
- padding: 16px;
20
- `;
21
- const ImportFromFileButton = styled.button `
22
- display: flex;
23
- width: 100%;
24
- padding: 8px 24px;
25
- justify-content: center;
26
- align-items: center;
27
- gap: 8px;
28
- border-radius: 4px;
29
- border: 1px dashed #c9c9c9;
30
- background: #fafafa;
31
- cursor: pointer;
32
- font-family: ${(props) => props.theme.font.family.sans};
33
- font-size: 14px;
34
- color: #353535;
35
-
36
- svg {
37
- width: 20px;
38
- height: 20px;
39
- }
40
-
41
- svg rect {
42
- fill: #6e6e6e;
43
- }
44
- `;
45
- const ReferencesInnerWrapper = withListNavigation(styled.div `
46
- width: 100%;
47
- padding: 12px 0;
48
- `);
49
- const ReferenceButton = withNavigableListItem(styled.div `
50
- cursor: pointer;
51
- display: flex;
52
- justify-content: flex-start;
53
- padding: ${(props) => props.theme.grid.unit * 4}px 0;
54
- border-top: 1px solid transparent;
55
- border-bottom: 1px solid transparent;
56
-
57
- path {
58
- fill: #c9c9c9;
59
- }
60
-
61
- &:hover {
62
- background: ${(props) => props.theme.colors.background.info};
63
- }
64
-
65
- &.selected {
66
- background: ${(props) => props.theme.colors.background.info};
67
- border-top-color: #bce7f6;
68
- border-bottom-color: #bce7f6;
69
- }
70
-
71
- .tooltip {
72
- max-width: ${(props) => props.theme.grid.unit * 25}px;
73
- padding: ${(props) => props.theme.grid.unit * 2}px;
74
- border-radius: 6px;
75
- }
76
- `);
77
- const IconContainer = styled.div `
78
- padding-right: ${(props) => props.theme.grid.unit * 5}px;
79
- position: relative;
80
- `;
81
- const CitationCount = styled.div `
82
- border-radius: 50%;
83
- width: 12px;
84
- height: 12px;
85
- position: absolute;
86
- color: #ffffff;
87
- background-color: #bce7f6;
88
- text-align: center;
89
- vertical-align: top;
90
- top: 0;
91
- left: 16px;
92
- font-size: 9px;
93
-
94
- &.unused {
95
- background-color: #fe8f1f;
96
- }
97
- `;
10
+ import { normalizeBlblioItem } from '../../lib/normalize';
98
11
  const selectionTopOffset = 10;
99
12
  const pageSize = 12;
100
13
  const topTrigger = 0.2;
101
14
  const bottomTrigger = 0.8;
102
15
  const dropLimit = 36;
103
- const normalize = (item) => ({
104
- id: item.id,
105
- type: item.type,
106
- author: item.author || [],
107
- editor: item.editor || [],
108
- issued: item.issued,
109
- ['container-title']: item['container-title'] || '',
110
- ['collection-title']: item['collection-title'] || '',
111
- DOI: item.DOI || '',
112
- URL: item.URL || '',
113
- volume: item.volume || '',
114
- issue: item.issue || '',
115
- supplement: item.supplement || '',
116
- edition: item.edition || '',
117
- page: item.page || '',
118
- ['number-of-pages']: item['number-of-pages'] || '',
119
- title: item.title || '',
120
- literal: item.literal || '',
121
- std: item.std || '',
122
- publisher: item.publisher || '',
123
- ['publisher-place']: item['publisher-place'] || '',
124
- event: item.event || '',
125
- ['event-place']: item['event-place'] || '',
126
- ['event-date']: item['event-date'],
127
- institution: item.institution || '',
128
- locator: item.locator || '',
129
- accessed: item.accessed,
130
- comment: item.comment || '',
131
- });
132
16
  export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts, onSave, onDelete, handleImport, }) => {
133
17
  const [importing, setImporting] = useState(false);
134
18
  const [importSuccessCount, setImportSuccessCount] = useState(null);
135
19
  const [confirm, setConfirm] = useState(false);
136
20
  const valuesRef = useRef(undefined);
137
21
  const [selection, setSelection] = useState();
22
+ const [isNew, setIsNew] = useState(false);
138
23
  const selectionRef = useRef(null);
139
24
  const sortedItems = useMemo(() => [...items].sort((a, b) => {
140
25
  const aUncited = (citationCounts.get(a.id) ?? 0) === 0;
@@ -149,7 +34,17 @@ export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts,
149
34
  };
150
35
  const selectionIndex = sortedItems.findIndex(isSelected);
151
36
  useEffect(() => {
152
- setSelection(item);
37
+ if (item) {
38
+ setSelection(item);
39
+ setIsNew(false);
40
+ }
41
+ else {
42
+ setIsNew(true);
43
+ setSelection({
44
+ id: generateNodeID(schema.nodes.bibliography_item),
45
+ type: 'article-journal',
46
+ });
47
+ }
153
48
  }, [item]);
154
49
  useEffect(() => {
155
50
  setTimeout(() => {
@@ -199,10 +94,11 @@ export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts,
199
94
  };
200
95
  const currentCitationCount = citationCounts.get(item.id);
201
96
  if (currentCitationCount === undefined) {
202
- citationCounts.set(item.id, 1);
97
+ citationCounts.set(item.id, 0);
203
98
  }
204
99
  onSave(item);
205
100
  setSelection(item);
101
+ setIsNew(false);
206
102
  setConfirm(false);
207
103
  };
208
104
  const handleDelete = () => {
@@ -212,14 +108,18 @@ export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts,
212
108
  onDelete(selection);
213
109
  setSelection(undefined);
214
110
  };
111
+ const hasChanged = () => {
112
+ const values = valuesRef.current;
113
+ return (values && selection && !isEqual(values, normalizeBlblioItem(selection)));
114
+ };
215
115
  const clearImportSuccess = () => setImportSuccessCount(null);
216
116
  const handleItemClick = (item) => {
217
117
  clearImportSuccess();
218
- const values = valuesRef.current;
219
- if (values && selection && !isEqual(values, normalize(selection))) {
118
+ if (hasChanged()) {
220
119
  setConfirm(true);
221
120
  return;
222
121
  }
122
+ setIsNew(false);
223
123
  setSelection(item);
224
124
  };
225
125
  const handleChange = (values) => {
@@ -231,9 +131,6 @@ export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts,
231
131
  setSelection(undefined);
232
132
  setImportSuccessCount(data.length);
233
133
  };
234
- if (sortedItems.length <= 0) {
235
- return React.createElement(React.Fragment, null);
236
- }
237
134
  return (React.createElement(React.Fragment, null,
238
135
  importing && (React.createElement(ImportBibliographyModal, { onCancel: () => setImporting(false), onSave: handleImportSave })),
239
136
  React.createElement(StyledModal, { isOpen: isOpen, onRequestClose: onCancel },
@@ -255,15 +152,142 @@ export const ReferencesModal = ({ isOpen, onCancel, items, item, citationCounts,
255
152
  React.createElement(ModalSidebarHeader, null,
256
153
  React.createElement(ModalSidebarTitle, null, "References")),
257
154
  React.createElement(ReferencesSidebarContent, { ref: ref },
258
- React.createElement(ReferencesInnerWrapper, null, sortedItems.slice(startIndex, endIndex + 1).map((item) => (React.createElement(ReferenceButton, { key: item.id, id: item.id, className: isSelected(item) ? 'selected' : '', onClick: () => handleItemClick(item), ref: isSelected(item) ? selectionRef : null },
259
- React.createElement(IconContainer, null,
260
- React.createElement(CitationCountIcon, null),
261
- (citationCounts.get(item.id) || 0) > 0 ? (React.createElement(CitationCount, { "data-tooltip-content": "Number of times used in the document" }, citationCounts.get(item.id))) : (React.createElement(CitationCount, { className: "unused" }, "0"))),
262
- React.createElement(ReferenceLine, { item: item })))))),
155
+ React.createElement(NewReferenceButton, { onClick: () => {
156
+ if (hasChanged()) {
157
+ setConfirm(true);
158
+ return;
159
+ }
160
+ setIsNew(true);
161
+ setSelection({
162
+ id: generateNodeID(schema.nodes.bibliography_item),
163
+ type: 'article-journal',
164
+ });
165
+ }, className: isNew ? 'selected' : '', disabled: isNew },
166
+ React.createElement(AddIcon, null),
167
+ React.createElement("span", null, "New Reference")),
168
+ React.createElement(ReferencesInnerWrapper, null,
169
+ React.createElement(ExistingReferencesHeading, null, "Existing References"),
170
+ sortedItems.slice(startIndex, endIndex + 1).map((item) => (React.createElement(ReferenceButton, { key: item.id, id: item.id, className: isSelected(item) ? 'selected' : '', onClick: () => handleItemClick(item), ref: isSelected(item) ? selectionRef : null },
171
+ React.createElement(IconContainer, null,
172
+ React.createElement(CitationCountIconStyled, null),
173
+ (citationCounts.get(item.id) || 0) > 0 ? (React.createElement(CitationCount, { "data-tooltip-content": "Number of times used in the document" }, citationCounts.get(item.id))) : (React.createElement(CitationCount, { className: "unused" }, "0"))),
174
+ React.createElement(ReferenceLine, { showUncited: !citationCounts.get(item.id), item: item })))))),
263
175
  React.createElement(ImportFromFileFooter, null,
264
176
  React.createElement(ImportFromFileButton, { type: "button", "data-cy": "import-from-file-button", onClick: () => setImporting(true) },
265
177
  React.createElement(AddAuthorIcon, null),
266
178
  "Import from file"))),
267
- React.createElement(ScrollableModalContent, null, importSuccessCount !== null ? (React.createElement(ImportSuccessPlaceholder, { count: importSuccessCount })) : (selection && (React.createElement(ReferenceForm, { values: normalize(selection), showDelete: !citationCounts.get(selection.id) &&
179
+ React.createElement(ScrollableModalContent, null, importSuccessCount !== null ? (React.createElement(ImportSuccessPlaceholder, { count: importSuccessCount })) : (selection && (React.createElement(ReferenceForm, { values: normalizeBlblioItem(selection), showDelete: !citationCounts.get(selection.id) &&
268
180
  isNewItem(selection, ['id', 'type']), onChange: handleChange, onCancel: onCancel, onDelete: handleDelete, onSave: handleSave, actionsRef: actionsRef })))))))));
269
181
  };
182
+ const ReferencesModalContainer = styled(ModalContainer) `
183
+ min-width: 960px;
184
+ `;
185
+ const ReferencesSidebar = styled(ModalSidebar) `
186
+ width: 70%;
187
+ `;
188
+ const ReferencesSidebarContent = styled(SidebarContent) `
189
+ overflow-y: auto;
190
+ `;
191
+ const ReferencesInnerWrapper = withListNavigation(styled.div `
192
+ width: 100%;
193
+ padding: 12px 0;
194
+ `);
195
+ const CitationCountIconStyled = styled(CitationCountIcon) ``;
196
+ const ReferenceButton = withNavigableListItem(styled.button `
197
+ cursor: pointer;
198
+ display: flex;
199
+ width: 100%;
200
+ justify-content: flex-start;
201
+ font: inherit;
202
+ appearance: none;
203
+ -webkit-appearance: none;
204
+ background: none;
205
+ border: none;
206
+ border-radius: 0;
207
+ text-align: inherit;
208
+
209
+ padding: ${(props) => props.theme.grid.unit * 4}px 0;
210
+ border-top: 1px solid transparent;
211
+ border-bottom: 1px solid transparent;
212
+
213
+ ${CitationCountIconStyled} path {
214
+ fill: #c9c9c9;
215
+ }
216
+
217
+ &:hover {
218
+ background: ${(props) => props.theme.colors.background.info};
219
+ }
220
+
221
+ &.selected {
222
+ background: ${(props) => props.theme.colors.background.info};
223
+ border-top-color: #bce7f6;
224
+ border-bottom-color: #bce7f6;
225
+ }
226
+
227
+ .tooltip {
228
+ max-width: ${(props) => props.theme.grid.unit * 25}px;
229
+ padding: ${(props) => props.theme.grid.unit * 2}px;
230
+ border-radius: 6px;
231
+ }
232
+ `);
233
+ const IconContainer = styled.div `
234
+ padding-right: ${(props) => props.theme.grid.unit * 5}px;
235
+ position: relative;
236
+ `;
237
+ const CitationCount = styled.div `
238
+ border-radius: 50%;
239
+ width: 12px;
240
+ height: 12px;
241
+ position: absolute;
242
+ color: #ffffff;
243
+ background-color: #bce7f6;
244
+ text-align: center;
245
+ vertical-align: top;
246
+ top: 0;
247
+ left: 16px;
248
+ font-size: 9px;
249
+
250
+ &.unused {
251
+ background-color: #fe8f1f;
252
+ }
253
+ `;
254
+ const NewReferenceButton = styled(ReferenceButton) `
255
+ svg {
256
+ margin-right: 8px;
257
+ }
258
+ `;
259
+ const ExistingReferencesHeading = styled.h3 `
260
+ font-size: 18px;
261
+ font-style: normal;
262
+ font-weight: 400;
263
+ padding: 8px 0 20px;
264
+ margin: 0;
265
+ color: #6e6e6e;
266
+ `;
267
+ const ImportFromFileFooter = styled.div `
268
+ padding: 16px;
269
+ `;
270
+ const ImportFromFileButton = styled.button `
271
+ display: flex;
272
+ width: 100%;
273
+ padding: 8px 24px;
274
+ justify-content: center;
275
+ align-items: center;
276
+ gap: 8px;
277
+ border-radius: 4px;
278
+ border: 1px dashed #c9c9c9;
279
+ background: #fafafa;
280
+ cursor: pointer;
281
+ font-family: ${(props) => props.theme.font.family.sans};
282
+ font-size: 14px;
283
+ color: #353535;
284
+
285
+ svg {
286
+ width: 20px;
287
+ height: 20px;
288
+ }
289
+
290
+ svg rect {
291
+ fill: #6e6e6e;
292
+ }
293
+ `;
package/dist/es/icons.js CHANGED
@@ -2,7 +2,7 @@ import { AddAuthorIcon, AlertIcon, ArrowDownCircleIcon, ArrowUpIcon, CameraIcon,
2
2
  import { createElement } from 'react';
3
3
  import { renderToStaticMarkup } from 'react-dom/server';
4
4
  const renderIcon = (c) => renderToStaticMarkup(createElement(c));
5
- export const addAuthorIcon = renderIcon(AddAuthorIcon);
5
+ export const addIcon = renderIcon(AddAuthorIcon);
6
6
  export const arrowDown = renderIcon(ArrowDownCircleIcon);
7
7
  export const arrowUp = renderIcon(ArrowUpIcon);
8
8
  export const alertIcon = renderIcon(AlertIcon);
@@ -13,7 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { generateNodeID, schema } from '@manuscripts/transform';
16
+ import { generateNodeID, schema, } from '@manuscripts/transform';
17
17
  const trim = (value) => (value ?? '').trim();
18
18
  export const normalizeAffiliation = (a) => ({
19
19
  ...a,
@@ -56,3 +56,32 @@ export const checkID = (attrs, nodeType) => {
56
56
  id: attrs.id || generateNodeID(schema.nodes[nodeType]),
57
57
  };
58
58
  };
59
+ export const normalizeBlblioItem = (item) => ({
60
+ id: item.id,
61
+ type: item.type,
62
+ author: item.author || [],
63
+ editor: item.editor || [],
64
+ issued: item.issued,
65
+ ['container-title']: item['container-title'] || '',
66
+ ['collection-title']: item['collection-title'] || '',
67
+ DOI: item.DOI || '',
68
+ URL: item.URL || '',
69
+ volume: item.volume || '',
70
+ issue: item.issue || '',
71
+ supplement: item.supplement || '',
72
+ edition: item.edition || '',
73
+ page: item.page || '',
74
+ ['number-of-pages']: item['number-of-pages'] || '',
75
+ title: item.title || '',
76
+ literal: item.literal || '',
77
+ std: item.std || '',
78
+ publisher: item.publisher || '',
79
+ ['publisher-place']: item['publisher-place'] || '',
80
+ event: item.event || '',
81
+ ['event-place']: item['event-place'] || '',
82
+ ['event-date']: item['event-date'],
83
+ institution: item.institution || '',
84
+ locator: item.locator || '',
85
+ accessed: item.accessed,
86
+ comment: item.comment || '',
87
+ });
@@ -71,7 +71,6 @@ export const transformPastedHTML = (html) => {
71
71
  const doc = new DOMParser().parseFromString(html, 'text/html');
72
72
  wrapHeadingWithSection(doc);
73
73
  wrapTableWithFigure(doc);
74
- console.log(doc.body.innerHTML);
75
74
  return doc.body.innerHTML;
76
75
  };
77
76
  const wrapHeadingWithSection = (doc) => {
@@ -17,13 +17,13 @@ import { schema } from '@manuscripts/transform';
17
17
  import { Plugin, TextSelection } from 'prosemirror-state';
18
18
  import { Decoration, DecorationSet } from 'prosemirror-view';
19
19
  import { v4 as uuidv4 } from 'uuid';
20
- import { addAuthorIcon } from '../icons';
20
+ import { addIcon } from '../icons';
21
21
  import { handleEnterKey } from '../lib/navigation-utils';
22
22
  import { findInsertionPosition } from '../lib/utils';
23
23
  const createAddSubtitleButton = (handler) => {
24
24
  const button = document.createElement('span');
25
25
  button.className = 'add-subtitle';
26
- button.innerHTML = `${addAuthorIcon} <span class="add-subtitle-text">Add subtitle</span>`;
26
+ button.innerHTML = `${addIcon} <span class="add-subtitle-text">Add subtitle</span>`;
27
27
  button.tabIndex = 0;
28
28
  const activate = (event) => {
29
29
  event.preventDefault();
@@ -88,7 +88,13 @@ const buildBibliographyPluginState = (doc, csl, $old) => {
88
88
  return item;
89
89
  },
90
90
  }, csl.style, 'en-US');
91
- const citationTexts = engine.rebuildProcessorState(nodes.map(([node]) => buildCiteprocCitation(node.attrs)));
91
+ const uncitedIds = [];
92
+ bibliographyItems.forEach((item, id) => {
93
+ if (!rids.includes(id)) {
94
+ uncitedIds.push(id);
95
+ }
96
+ });
97
+ const citationTexts = engine.rebuildProcessorState(nodes.map(([node]) => buildCiteprocCitation(node.attrs)), 'html', uncitedIds);
92
98
  $new.version = String(version++);
93
99
  $new.citationCounts = citationCounts;
94
100
  $new.engine = engine;
@@ -17,7 +17,7 @@ import { isAbstractNode, isGraphicalAbstractSectionNode, isTransAbstractNode, is
17
17
  import { Plugin } from 'prosemirror-state';
18
18
  import { Decoration, DecorationSet } from 'prosemirror-view';
19
19
  import { insertTransAbstract, insertTransGraphicalAbstract } from '../commands';
20
- import { addAuthorIcon, translateIcon } from '../icons';
20
+ import { addIcon, translateIcon } from '../icons';
21
21
  import { getLanguage, getLanguageLabel } from '../lib/languages';
22
22
  import { createKeyboardInteraction, handleEnterKey, } from '../lib/navigation-utils';
23
23
  import { templateAllows } from '../lib/template';
@@ -83,7 +83,7 @@ export default (props) => new Plugin({
83
83
  $span.tabIndex = 0;
84
84
  $span.className = 'add-trans-abstract';
85
85
  $span.title = 'Add translation';
86
- $span.innerHTML = `${addAuthorIcon} <span class="add-trans-abstract-text">Add translation</span>`;
86
+ $span.innerHTML = `${addIcon} <span class="add-trans-abstract-text">Add translation</span>`;
87
87
  const handleActivate = (event) => {
88
88
  event.preventDefault();
89
89
  event.stopPropagation();
@@ -1,2 +1,2 @@
1
- export const VERSION = '3.17.5';
1
+ export const VERSION = '3.18.0';
2
2
  export const MATHJAX_VERSION = '3.2.2';
@@ -14,6 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { ContextMenu } from '@manuscripts/style-guide';
17
+ import { isCitationNode, } from '@manuscripts/transform';
17
18
  import { NodeSelection } from 'prosemirror-state';
18
19
  import { ReferencesEditor, } from '../components/references/ReferencesEditor';
19
20
  import { createCommentMarker, handleComment } from '../lib/comments';
@@ -21,13 +22,14 @@ import { handleEnterKey } from '../lib/navigation-utils';
21
22
  import { findNodeByID } from '../lib/doc';
22
23
  import { sanitize } from '../lib/dompurify';
23
24
  import { deleteNode, findChildByID, saveBibliographyItem } from '../lib/view';
24
- import { getBibliographyPluginState } from '../plugins/bibliography';
25
+ import { getBibliographyPluginState, } from '../plugins/bibliography';
25
26
  import { commentsKey, setCommentSelection } from '../plugins/comments';
26
27
  import { selectedSuggestionKey } from '../plugins/selected-suggestion';
27
28
  import BlockView from './block_view';
28
29
  import { createNodeView } from './creators';
29
30
  import ReactSubView from './ReactSubView';
30
31
  import { addTrackChangesAttributes, addTrackChangesClassNames, } from '@manuscripts/track-changes-plugin';
32
+ import { addIcon } from '../icons';
31
33
  export class BibliographyElementBlockView extends BlockView {
32
34
  constructor() {
33
35
  super(...arguments);
@@ -132,7 +134,7 @@ export class BibliographyElementBlockView extends BlockView {
132
134
  const componentProps = {
133
135
  items: Array.from(bib.bibliographyItems.values()),
134
136
  citationCounts: bib.citationCounts,
135
- item: bib.bibliographyItems.get(id),
137
+ item: id ? bib.bibliographyItems.get(id) : undefined,
136
138
  onSave: this.handleSave,
137
139
  onDelete: this.handleDelete,
138
140
  };
@@ -175,7 +177,18 @@ export class BibliographyElementBlockView extends BlockView {
175
177
  return;
176
178
  }
177
179
  this.version = bib.version;
180
+ this.renderBibs(bib);
181
+ this.createInlineModalButton();
182
+ this.updateSelections();
183
+ }
184
+ renderBibs(bib) {
178
185
  const nodes = new Map();
186
+ const rids = [];
187
+ this.view.state.doc.descendants((node) => {
188
+ if (isCitationNode(node)) {
189
+ rids.push(...node.attrs.rids);
190
+ }
191
+ });
179
192
  this.node.descendants((node) => {
180
193
  const id = node.attrs.id;
181
194
  nodes.set(id, node);
@@ -213,6 +226,12 @@ export class BibliographyElementBlockView extends BlockView {
213
226
  element.tabIndex = 0;
214
227
  const comment = createCommentMarker('div', id);
215
228
  element.prepend(comment);
229
+ if (!rids.includes(id)) {
230
+ const uncitedMarker = document.createElement('span');
231
+ uncitedMarker.innerHTML = 'UNCITED';
232
+ uncitedMarker.classList.add('uncited-reference-marker');
233
+ element.prepend(uncitedMarker);
234
+ }
216
235
  addTrackChangesAttributes(node.attrs, element);
217
236
  addTrackChangesClassNames(node.attrs, element);
218
237
  wrapper.append(element);
@@ -230,7 +249,30 @@ export class BibliographyElementBlockView extends BlockView {
230
249
  else {
231
250
  this.container.appendChild(wrapper);
232
251
  }
233
- this.updateSelections();
252
+ }
253
+ createInlineModalButton() {
254
+ const can = this.props.getCapabilities();
255
+ if (!can.editCitationsAndRefs) {
256
+ if (this.inlineModalButton) {
257
+ this.inlineModalButton.remove();
258
+ this.inlineModalButton = null;
259
+ }
260
+ return;
261
+ }
262
+ if (this.inlineModalButton) {
263
+ return;
264
+ }
265
+ const $span = document.createElement('span');
266
+ $span.tabIndex = 0;
267
+ $span.className = 'add-new-reference add-trans-abstract';
268
+ $span.title = 'Add New Reference';
269
+ $span.innerHTML = `${addIcon} <span type="button" tabindex="0" class="add-new-reference-text">Add new reference</span>`;
270
+ $span.addEventListener('click', (e) => {
271
+ this.showPopper();
272
+ });
273
+ $span.addEventListener('keydown', handleEnterKey(() => this.showPopper()));
274
+ this.inlineModalButton = $span;
275
+ this.dom.appendChild($span);
234
276
  }
235
277
  }
236
278
  export default createNodeView(BibliographyElementBlockView);
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { schema } from '@manuscripts/transform';
17
17
  import { TextSelection } from 'prosemirror-state';
18
- import { addAuthorIcon } from '../icons';
18
+ import { addIcon } from '../icons';
19
19
  import { handleEnterKey } from '../lib/navigation-utils';
20
20
  import { createNodeView } from './creators';
21
21
  import { ImageElementView } from './image_element';
@@ -68,7 +68,7 @@ export class FigureElementView extends ImageElementView {
68
68
  if (this.props.getCapabilities()?.editArticle) {
69
69
  this.addFigureBtn = Object.assign(document.createElement('button'), {
70
70
  className: 'add-button',
71
- innerHTML: addAuthorIcon,
71
+ innerHTML: addIcon,
72
72
  title: 'Add figure',
73
73
  });
74
74
  this.addFigureBtn.addEventListener('click', () => this.addFigure());
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { schema, } from '@manuscripts/transform';
17
17
  import { TextSelection } from 'prosemirror-state';
18
- import { addAuthorIcon } from '../icons';
18
+ import { addIcon } from '../icons';
19
19
  import { createKeyboardInteraction, handleEnterKey, } from '../lib/navigation-utils';
20
20
  import BlockView from './block_view';
21
21
  import { createNodeView } from './creators';
@@ -45,7 +45,7 @@ export class HeadshotGridView extends BlockView {
45
45
  this.addHeadshotButton.classList.add('add-headshot-element-button');
46
46
  this.addHeadshotButton.setAttribute('data-cy', 'headshot-add');
47
47
  this.addHeadshotButton.contentEditable = 'false';
48
- this.addHeadshotButton.innerHTML = addAuthorIcon;
48
+ this.addHeadshotButton.innerHTML = addIcon;
49
49
  const buttonText = document.createElement('span');
50
50
  buttonText.classList.add('add-headshot-element-text');
51
51
  buttonText.innerText = 'Add Headshot';
@@ -19,4 +19,5 @@ export declare const Metadata: import("styled-components/dist/types").IStyledCom
19
19
  export declare const MetadataContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
20
20
  export declare const ReferenceLine: React.FC<{
21
21
  item: BibliographyItemAttrs;
22
+ showUncited?: boolean;
22
23
  }>;
@@ -1,4 +1,4 @@
1
- export declare const addAuthorIcon: string;
1
+ export declare const addIcon: string;
2
2
  export declare const arrowDown: string;
3
3
  export declare const arrowUp: string;
4
4
  export declare const alertIcon: string;
@@ -13,7 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Nodes } from '@manuscripts/transform';
16
+ import { BibliographyItemAttrs, Nodes } from '@manuscripts/transform';
17
17
  import { AffiliationAttrs, ContributorAttrs } from './authors';
18
18
  export declare const normalizeAffiliation: (a: AffiliationAttrs) => AffiliationAttrs;
19
19
  export declare const normalizeAuthor: (author: ContributorAttrs) => ContributorAttrs;
@@ -23,4 +23,33 @@ type WithID = {
23
23
  export declare const checkID: <T extends WithID>(attrs: T, nodeType: Nodes) => T & {
24
24
  id: string;
25
25
  };
26
+ export declare const normalizeBlblioItem: (item: BibliographyItemAttrs) => {
27
+ id: string;
28
+ type: import("@manuscripts/transform").BibliographyItemType;
29
+ author: import("csl").Person[];
30
+ editor: import("csl").Person[];
31
+ issued: import("csl").Date | undefined;
32
+ "container-title": string;
33
+ "collection-title": string;
34
+ DOI: string;
35
+ URL: string;
36
+ volume: string;
37
+ issue: string;
38
+ supplement: string;
39
+ edition: string;
40
+ page: string;
41
+ "number-of-pages": string;
42
+ title: string;
43
+ literal: string;
44
+ std: string;
45
+ publisher: string;
46
+ "publisher-place": string;
47
+ event: string;
48
+ "event-place": string;
49
+ "event-date": import("csl").Date | undefined;
50
+ institution: string;
51
+ locator: string;
52
+ accessed: import("csl").Date | undefined;
53
+ comment: string;
54
+ };
26
55
  export {};
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "3.17.5";
1
+ export declare const VERSION = "3.18.0";
2
2
  export declare const MATHJAX_VERSION = "3.2.2";