@manuscripts/body-editor 1.6.20 → 1.7.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.
@@ -0,0 +1,114 @@
1
+ /*!
2
+ * © 2019 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { isAffiliationNode, isContributorNode, } from '@manuscripts/transform';
17
+ import { Plugin, PluginKey } from 'prosemirror-state';
18
+ import { Decoration, DecorationSet } from 'prosemirror-view';
19
+ import { getActualAttrs, isDeleted, isPendingInsert, } from '../lib/track-changes-utils';
20
+ export const affiliationsKey = new PluginKey('affiliations');
21
+ export const buildPluginState = (doc) => {
22
+ const contributors = [];
23
+ const affiliations = [];
24
+ doc.descendants((node, pos) => {
25
+ if (isDeleted(node)) {
26
+ return;
27
+ }
28
+ if (isAffiliationNode(node)) {
29
+ affiliations.push([node, pos]);
30
+ }
31
+ if (isContributorNode(node)) {
32
+ contributors.push([node, pos]);
33
+ }
34
+ });
35
+ const iAffiliations = new Set();
36
+ contributors
37
+ .sort(([a], [b]) => {
38
+ return (Number(getActualAttrs(a).priority) - Number(getActualAttrs(b).priority));
39
+ })
40
+ .forEach(([author]) => {
41
+ getActualAttrs(author).affiliations.forEach((aff) => {
42
+ iAffiliations.add(aff);
43
+ });
44
+ });
45
+ const indexedAffiliationIds = new Map([...iAffiliations].map((id, i) => [id, i + 1]));
46
+ return {
47
+ indexedAffiliationIds,
48
+ contributors,
49
+ affiliations,
50
+ };
51
+ };
52
+ let count = 0;
53
+ export default () => {
54
+ return new Plugin({
55
+ key: affiliationsKey,
56
+ state: {
57
+ init(config, instance) {
58
+ return buildPluginState(instance.doc);
59
+ },
60
+ apply(tr, value, oldState, newState) {
61
+ const prevPluginState = affiliationsKey.getState(oldState);
62
+ if (!tr.docChanged && prevPluginState) {
63
+ return prevPluginState;
64
+ }
65
+ else {
66
+ return buildPluginState(newState.doc);
67
+ }
68
+ },
69
+ },
70
+ appendTransaction(transactions, oldState, newState) {
71
+ const { indexedAffiliationIds } = affiliationsKey.getState(newState);
72
+ const oldPluginState = affiliationsKey.getState(oldState);
73
+ const { tr } = newState;
74
+ const affiliations = [];
75
+ newState.doc.descendants((node, pos) => {
76
+ if (isDeleted(node)) {
77
+ return;
78
+ }
79
+ if (isAffiliationNode(node)) {
80
+ affiliations.push([node, pos]);
81
+ }
82
+ });
83
+ for (const [id] of oldPluginState.indexedAffiliationIds.entries()) {
84
+ if (!indexedAffiliationIds.has(id)) {
85
+ const affiliation = affiliations.find(([node]) => node.attrs.id === id);
86
+ if (affiliation && !isPendingInsert(affiliation[0])) {
87
+ tr.delete(affiliation[1], affiliation[1] + affiliation[0].nodeSize);
88
+ }
89
+ }
90
+ }
91
+ tr.setMeta('origin', 'affiliations');
92
+ return tr;
93
+ },
94
+ props: {
95
+ decorations: (state) => {
96
+ const decorations = [];
97
+ const allNodes = [];
98
+ state.doc.descendants((node, pos) => {
99
+ if (isAffiliationNode(node) || isContributorNode(node)) {
100
+ allNodes.push([node, pos]);
101
+ }
102
+ });
103
+ if (allNodes.length) {
104
+ allNodes.forEach(([node, pos]) => {
105
+ decorations.push(Decoration.node(pos, pos + node.nodeSize, {}, {
106
+ refresh: count++,
107
+ }));
108
+ });
109
+ }
110
+ return DecorationSet.create(state.doc, decorations);
111
+ },
112
+ },
113
+ });
114
+ };
@@ -0,0 +1,71 @@
1
+ /*!
2
+ * © 2019 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { getActualAttrs } from '../lib/track-changes-utils';
17
+ import { affiliationsKey } from '../plugins/affiliations';
18
+ import { BaseNodeView } from './base_node_view';
19
+ import { createNodeView } from './creators';
20
+ export class AffiliationView extends BaseNodeView {
21
+ constructor() {
22
+ super(...arguments);
23
+ this.initialise = () => {
24
+ this.createDOM();
25
+ };
26
+ this.updateContents = () => {
27
+ var _a;
28
+ const attrs = this.node.attrs;
29
+ const pluginState = affiliationsKey.getState(this.view.state);
30
+ this.dom.innerHTML = this.formatAddress(getActualAttrs(this.node));
31
+ if (pluginState === null || pluginState === void 0 ? void 0 : pluginState.indexedAffiliationIds) {
32
+ const order = pluginState.indexedAffiliationIds.get(attrs.id);
33
+ this.dom.innerHTML = order
34
+ ? `<b>${order}</b> ${this.dom.innerHTML}`
35
+ : this.dom.innerHTML;
36
+ this.dom.setAttribute('style', 'order: ' + (order || (pluginState === null || pluginState === void 0 ? void 0 : pluginState.affiliations.length) + 1));
37
+ }
38
+ if ((_a = attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
39
+ this.dom.setAttribute('data-track-status', attrs.dataTracked[0].status);
40
+ this.dom.setAttribute('data-track-op', attrs.dataTracked[0].operation);
41
+ }
42
+ else {
43
+ this.dom.removeAttribute('data-track-status');
44
+ this.dom.removeAttribute('data-track-type');
45
+ }
46
+ };
47
+ this.createDOM = () => {
48
+ this.dom = document.createElement('div');
49
+ this.dom.classList.add('affiliation');
50
+ this.dom.setAttribute('id', this.node.attrs.id);
51
+ this.updateContents();
52
+ };
53
+ this.ignoreMutation = () => true;
54
+ this.stopEvent = () => true;
55
+ this.formatAddress = (affiliation) => {
56
+ const { department, institution, addressLine1, city, county, country, postCode, } = affiliation;
57
+ return [
58
+ department,
59
+ institution,
60
+ addressLine1,
61
+ city,
62
+ county,
63
+ country,
64
+ postCode,
65
+ ]
66
+ .filter(Boolean)
67
+ .join(', ');
68
+ };
69
+ }
70
+ }
71
+ export default createNodeView(AffiliationView);
@@ -0,0 +1,17 @@
1
+ import BlockView from './block_view';
2
+ import { createNodeView } from './creators';
3
+ export class AffiliationsView extends BlockView {
4
+ constructor() {
5
+ super(...arguments);
6
+ this.ignoreMutation = () => true;
7
+ this.stopEvent = () => true;
8
+ this.createElement = () => {
9
+ this.contentDOM = document.createElement(this.elementType);
10
+ this.contentDOM.className = 'block';
11
+ this.contentDOM.setAttribute('contenteditable', 'false');
12
+ this.dom.setAttribute('contenteditable', 'false');
13
+ this.dom.appendChild(this.contentDOM);
14
+ };
15
+ }
16
+ }
17
+ export default createNodeView(AffiliationsView);
@@ -1,28 +1,167 @@
1
- import { BaseNodeView } from './base_node_view';
1
+ import { SecondaryButton } from '@manuscripts/style-guide';
2
+ import { isContributorNode } from '@manuscripts/transform';
3
+ import { getActualAttrs } from '../lib/track-changes-utils';
4
+ import { affiliationsKey } from '../plugins/affiliations';
5
+ import BlockView from './block_view';
2
6
  import { createNodeView } from './creators';
3
7
  import ReactSubView from './ReactSubView';
4
- export class ContributorsView extends BaseNodeView {
8
+ export class ContributorsView extends BlockView {
5
9
  constructor() {
6
10
  super(...arguments);
7
11
  this.initialise = () => {
8
12
  this.createDOM();
13
+ this.createGutter('block-gutter', this.gutterButtons().filter(Boolean));
14
+ this.createElement();
15
+ this.createGutter('action-gutter', this.actionGutterButtons().filter(Boolean));
16
+ this.updateContents();
17
+ };
18
+ this.updateContents = () => {
19
+ this.updateClasses();
20
+ this.updateAttributes();
21
+ this.container.innerHTML = '';
22
+ this.buildAuthors();
23
+ this.createEditButton();
24
+ this.createLegend();
25
+ };
26
+ this.buildAuthors = () => {
27
+ var _a;
28
+ const authors = [];
29
+ const authorsWrapper = document.createElement('div');
30
+ authorsWrapper.classList.add('contributors-list');
31
+ (_a = this.node.content) === null || _a === void 0 ? void 0 : _a.forEach((node) => {
32
+ if (isContributorNode(node)) {
33
+ authors.push(node);
34
+ }
35
+ });
36
+ authors
37
+ .sort((a, b) => Number(a.attrs.priority) - Number(b.attrs.priority))
38
+ .forEach((author, i) => {
39
+ if (getActualAttrs(author).role !== 'author') {
40
+ return;
41
+ }
42
+ const jointAuthors = this.isJointFirstAuthor(authors, i);
43
+ authorsWrapper.appendChild(this.buildAuthor(author, jointAuthors));
44
+ });
45
+ this.container.appendChild(authorsWrapper);
46
+ };
47
+ this.buildAuthor = (node, isJointFirstAuthor) => {
48
+ var _a;
49
+ const pluginState = affiliationsKey.getState(this.view.state);
50
+ const attrs = node.attrs;
51
+ const displayAttr = getActualAttrs(node);
52
+ const container = document.createElement('button');
53
+ container.classList.add('contributor');
54
+ container.setAttribute('id', attrs.id);
55
+ container.setAttribute('contenteditable', 'false');
56
+ if ((_a = attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
57
+ container.setAttribute('data-track-status', attrs.dataTracked[0].status);
58
+ container.setAttribute('data-track-op', attrs.dataTracked[0].operation);
59
+ }
60
+ else {
61
+ container.removeAttribute('data-track-status');
62
+ container.removeAttribute('data-track-type');
63
+ }
64
+ const can = this.props.getCapabilities();
65
+ const disableEditButton = !can.editMetadata;
66
+ const { bibliographicName, isCorresponding, email, id } = displayAttr;
67
+ container.addEventListener('click', (e) => {
68
+ e.preventDefault();
69
+ if (!disableEditButton) {
70
+ this.props.openAuthorEditing();
71
+ this.props.selectAuthorForEditing(id);
72
+ }
73
+ });
74
+ const name = this.buildNameLiteral(bibliographicName);
75
+ container.innerHTML =
76
+ isCorresponding && email
77
+ ? `<span class="name">${name} (${email})</span>`
78
+ : `<span class="name">${name}</span>`;
79
+ const noteText = [];
80
+ if (pluginState === null || pluginState === void 0 ? void 0 : pluginState.indexedAffiliationIds) {
81
+ displayAttr.affiliations.map((af) => {
82
+ const index = pluginState === null || pluginState === void 0 ? void 0 : pluginState.indexedAffiliationIds.get(af);
83
+ if (index) {
84
+ noteText.push(index.toString());
85
+ }
86
+ });
87
+ }
88
+ if (isJointFirstAuthor) {
89
+ container.appendChild(this.createNote('†', 'Joint contributor'));
90
+ }
91
+ if (noteText) {
92
+ container.appendChild(this.createNote(noteText.join(',')));
93
+ }
94
+ if (displayAttr.isCorresponding) {
95
+ container.appendChild(this.createNote('*', 'Corresponding author'));
96
+ }
97
+ return container;
98
+ };
99
+ this.initials = (given) => given
100
+ ? given
101
+ .trim()
102
+ .split(' ')
103
+ .map((part) => part.substr(0, 1).toUpperCase() + '.')
104
+ .join('')
105
+ : '';
106
+ this.buildNameLiteral = ({ given = '', family = '', suffix = '' }) => {
107
+ if (!given && !family) {
108
+ return 'Unknown Author';
109
+ }
110
+ return [this.initials(given), family, suffix]
111
+ .filter((part) => part)
112
+ .join(' ');
113
+ };
114
+ this.isJointFirstAuthor = (authors, index) => {
115
+ const author = index === 0 ? authors[index] : authors[index - 1];
116
+ return Boolean(author.attrs.isJointContributor);
117
+ };
118
+ this.createElement = () => {
119
+ this.inner = document.createElement('div');
120
+ this.inner.classList.add('authors-container', 'block');
121
+ this.dom.appendChild(this.inner);
122
+ this.container = document.createElement('div');
123
+ this.container.classList.add('contributors');
124
+ this.inner.appendChild(this.container);
9
125
  };
10
126
  this.createDOM = () => {
11
127
  this.dom = document.createElement('div');
12
- this.dom.classList.add('contributors');
128
+ this.dom.classList.add('block-container', `block-${this.node.type.name}`);
129
+ };
130
+ this.createEditButton = () => {
13
131
  const can = this.props.getCapabilities();
14
- const { components: { AuthorsInlineViewContainer }, subscribeStore, } = this.props;
15
- this.metadata = ReactSubView(this.props, AuthorsInlineViewContainer, {
16
- showAuthorEditButton: true,
17
- disableEditButton: !can.editMetadata,
18
- subscribe: subscribeStore,
19
- }, this.node, this.getPos, this.view, 'metadata-container');
20
- if (this.metadata) {
21
- this.dom.appendChild(this.metadata);
132
+ const button = ReactSubView(this.props, SecondaryButton, {
133
+ mini: true,
134
+ onClick: this.props.openAuthorEditing,
135
+ className: 'edit-authors-button',
136
+ disabled: !can.editMetadata,
137
+ children: 'Edit Authors',
138
+ }, this.node, this.getPos, this.view);
139
+ this.container.appendChild(button);
140
+ };
141
+ this.createLegend = () => {
142
+ const state = affiliationsKey.getState(this.view.state);
143
+ if (state === null || state === void 0 ? void 0 : state.contributors) {
144
+ const isThereJointContributor = state.contributors.find(([contributor]) => contributor.attrs.isJointContributor);
145
+ if (isThereJointContributor) {
146
+ const element = document.createElement('p');
147
+ element.classList.add('contributors-legend');
148
+ element.innerHTML =
149
+ '<span class="symbol">†</span>These authors contributed equally to this work.';
150
+ this.container.appendChild(element);
151
+ }
22
152
  }
23
153
  };
24
154
  this.ignoreMutation = () => true;
25
155
  this.stopEvent = () => true;
26
156
  }
157
+ createNote(text = '', title = '') {
158
+ const el = document.createElement('span');
159
+ el.innerHTML = text;
160
+ if (title) {
161
+ el.setAttribute('title', title);
162
+ }
163
+ el.classList.add('contributor-note');
164
+ return el;
165
+ }
27
166
  }
28
167
  export default createNodeView(ContributorsView);
@@ -26,6 +26,7 @@ import { UnsupportedFormatFileIcon, } from '@manuscripts/style-guide';
26
26
  import { createElement } from 'react';
27
27
  import ReactDOM from 'react-dom';
28
28
  import { FigureOptions, } from '../components/views/FigureDropdown';
29
+ import { getActualAttrs } from '../lib/track-changes-utils';
29
30
  import { createEditableNodeView } from './creators';
30
31
  import { FigureView } from './figure';
31
32
  import { figureUploader } from './figure_uploader';
@@ -44,12 +45,8 @@ export class FigureEditableView extends FigureView {
44
45
  };
45
46
  this.updateContents = () => {
46
47
  var _a, _b;
47
- let attrs = this.node.attrs;
48
+ const attrs = getActualAttrs(this.node);
48
49
  if ((_a = this.node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
49
- if (this.node.attrs.dataTracked[0].status === 'rejected' &&
50
- this.node.attrs.dataTracked[0].operation === 'set_attrs') {
51
- attrs = this.node.attrs.dataTracked[0].oldAttrs;
52
- }
53
50
  this.dom.setAttribute('data-track-status', this.node.attrs.dataTracked[0].status);
54
51
  this.dom.setAttribute('data-track-op', this.node.attrs.dataTracked[0].operation);
55
52
  }
@@ -13,6 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { TextSelection } from 'prosemirror-state';
16
17
  import { DeleteKeywordDialog, } from '../components/keywords/DeleteKeywordDialog';
17
18
  import { getChangeClasses } from '../lib/track-changes-utils';
18
19
  import { BaseNodeView } from './base_node_view';
@@ -61,7 +62,7 @@ export class KeywordView extends BaseNodeView {
61
62
  const pos = this.getPos();
62
63
  const handleDelete = () => {
63
64
  const tr = this.view.state.tr;
64
- tr.delete(pos, pos + keyword.nodeSize);
65
+ tr.setSelection(TextSelection.near(this.view.state.doc.resolve(0))).delete(pos, pos + keyword.nodeSize + 1);
65
66
  this.view.dispatch(tr);
66
67
  };
67
68
  const componentProps = {
@@ -53,6 +53,8 @@ export interface EditorProps {
53
53
  retrySync: (componentIDs: string[]) => Promise<void>;
54
54
  environment?: string;
55
55
  collabProvider?: CollabProvider;
56
+ openAuthorEditing: () => void;
57
+ selectAuthorForEditing: (authorId: string) => void;
56
58
  }
57
59
  export declare const createEditorState: (props: EditorProps) => EditorState;
58
60
  export declare const createEditorView: (props: EditorProps, root: HTMLElement, state: EditorState, dispatch: Dispatch) => EditorView;
@@ -139,6 +139,8 @@ declare const _default: (props: EditorProps, dispatch: Dispatch) => {
139
139
  citation: import("../types").NodeViewCreator<import("../views/citation_editable").CitationEditableView>;
140
140
  cross_reference: import("../types").NodeViewCreator<import("../views/cross_reference_editable").CrossReferenceEditableView>;
141
141
  contributors: import("../types").NodeViewCreator<import("../views/contributors").ContributorsView<any>>;
142
+ affiliations: import("../types").NodeViewCreator<import("../views/affiliations").AffiliationsView<any>>;
143
+ affiliation: import("../types").NodeViewCreator<import("../views/affiliation").AffiliationView<any>>;
142
144
  equation: import("../types").NodeViewCreator<import("../views/equation_editable").EquationEditableView>;
143
145
  equation_element: import("../types").NodeViewCreator<{
144
146
  gutterButtons: () => HTMLElement[];
@@ -27,4 +27,5 @@ export * from './toolbar';
27
27
  export * from './plugins/highlight';
28
28
  export { commentScroll, isThereSelector, isHighlightComment, } from './plugins/comment_annotation';
29
29
  export * from './lib/utils';
30
+ export * from './lib/track-changes-utils';
30
31
  export * from './useEditor';
@@ -13,6 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { ManuscriptNode } from '@manuscripts/transform';
16
17
  import { Node as ProsemirrorNode } from 'prosemirror-model';
17
18
  export declare function isRejectedInsert(node: ProsemirrorNode): boolean;
18
19
  export declare function isDeleted(node: ProsemirrorNode): boolean;
@@ -21,3 +22,4 @@ export declare function isPending(node: ProsemirrorNode): boolean;
21
22
  export declare function isPendingSetAttrs(node: ProsemirrorNode): boolean;
22
23
  export declare function getChangeClasses(node: ProsemirrorNode): string[];
23
24
  export declare function isTracked(node: ProsemirrorNode): boolean;
25
+ export declare function getActualAttrs<T extends ManuscriptNode>(node: T): T["attrs"];
@@ -0,0 +1,26 @@
1
+ /*!
2
+ * © 2019 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { AffiliationNode, ContributorNode, ManuscriptNode } from '@manuscripts/transform';
17
+ import { Plugin, PluginKey } from 'prosemirror-state';
18
+ interface PluginState {
19
+ indexedAffiliationIds: Map<string, number>;
20
+ contributors: Array<[ContributorNode, number]>;
21
+ affiliations: Array<[AffiliationNode, number]>;
22
+ }
23
+ export declare const affiliationsKey: PluginKey<PluginState>;
24
+ export declare const buildPluginState: (doc: ManuscriptNode) => PluginState;
25
+ declare const _default: () => Plugin<PluginState>;
26
+ export default _default;
@@ -13,6 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { TrackedAttrs } from '@manuscripts/track-changes-plugin';
16
17
  import { ManuscriptEditorState, ManuscriptEditorView, ManuscriptNode, ManuscriptNodeView, ManuscriptTransaction } from '@manuscripts/transform';
17
18
  import { Decoration } from 'prosemirror-view';
18
19
  export type EditorAction = (state: ManuscriptEditorState, dispatch?: (tr: ManuscriptTransaction) => void, view?: ManuscriptEditorView) => boolean;
@@ -24,3 +25,6 @@ export type ChangeReceiver = (op: string, id?: string, data?: ManuscriptNode | n
24
25
  export interface SyncError {
25
26
  _id: string;
26
27
  }
28
+ export type TrackableAttributes<T extends ManuscriptNode> = T['attrs'] & {
29
+ dataTracked?: TrackedAttrs[];
30
+ };
@@ -0,0 +1,31 @@
1
+ /*!
2
+ * © 2019 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { Capabilities } from '@manuscripts/style-guide';
17
+ import { AffiliationNode, ManuscriptNodeView } from '@manuscripts/transform';
18
+ import { BaseNodeProps, BaseNodeView } from './base_node_view';
19
+ export interface Props extends BaseNodeProps {
20
+ getCapabilities: () => Capabilities;
21
+ }
22
+ export declare class AffiliationView<PropsType extends BaseNodeProps> extends BaseNodeView<PropsType> implements ManuscriptNodeView {
23
+ initialise: () => void;
24
+ updateContents: () => void;
25
+ protected createDOM: () => void;
26
+ ignoreMutation: () => boolean;
27
+ stopEvent: () => boolean;
28
+ formatAddress: (affiliation: AffiliationNode['attrs']) => string;
29
+ }
30
+ declare const _default: (props: BaseNodeProps, dispatch?: import("..").Dispatch | undefined) => import("../types").NodeViewCreator<AffiliationView<any>>;
31
+ export default _default;
@@ -0,0 +1,9 @@
1
+ import BlockView from './block_view';
2
+ import { EditableBlockProps } from './editable_block';
3
+ export declare class AffiliationsView<PropsType extends EditableBlockProps> extends BlockView<PropsType> {
4
+ ignoreMutation: () => boolean;
5
+ stopEvent: () => boolean;
6
+ createElement: () => void;
7
+ }
8
+ declare const _default: (props: import("./base_node_view").BaseNodeProps, dispatch?: import("..").Dispatch | undefined) => import("../types").NodeViewCreator<AffiliationsView<any>>;
9
+ export default _default;
@@ -1,15 +1,31 @@
1
- import { ManuscriptNodeView } from '@manuscripts/transform';
2
- import React from 'react';
3
- import { BaseNodeView } from './base_node_view';
1
+ import { Capabilities } from '@manuscripts/style-guide';
2
+ import { ContributorNode } from '@manuscripts/transform';
3
+ import BlockView from './block_view';
4
4
  import { EditableBlockProps } from './editable_block';
5
5
  export interface ContributorsProps extends EditableBlockProps {
6
- components: Record<string, React.ComponentType<unknown>>;
7
- subscribeStore: unknown;
6
+ getCapabilities: () => Capabilities;
7
+ openAuthorEditing: () => void;
8
+ selectAuthorForEditing: (authorId: string) => void;
8
9
  }
9
- export declare class ContributorsView<PropsType extends ContributorsProps> extends BaseNodeView<PropsType> implements ManuscriptNodeView {
10
- private metadata;
10
+ export declare class ContributorsView<PropsType extends ContributorsProps> extends BlockView<PropsType> {
11
11
  initialise: () => void;
12
- protected createDOM: () => void;
12
+ updateContents: () => void;
13
+ buildAuthors: () => void;
14
+ container: HTMLElement;
15
+ inner: HTMLElement;
16
+ buildAuthor: (node: ContributorNode, isJointFirstAuthor: boolean) => HTMLButtonElement;
17
+ createNote(text?: string, title?: string): HTMLSpanElement;
18
+ initials: (given: string) => string;
19
+ buildNameLiteral: ({ given, family, suffix }: {
20
+ given?: string | undefined;
21
+ family?: string | undefined;
22
+ suffix?: string | undefined;
23
+ }) => string;
24
+ isJointFirstAuthor: (authors: ContributorNode[], index: number) => boolean;
25
+ createElement: () => void;
26
+ createDOM: () => void;
27
+ createEditButton: () => void;
28
+ createLegend: () => void;
13
29
  ignoreMutation: () => boolean;
14
30
  stopEvent: () => boolean;
15
31
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@manuscripts/body-editor",
3
3
  "description": "Prosemirror components for editing and viewing manuscripts",
4
- "version": "1.6.20",
4
+ "version": "1.7.0",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -31,9 +31,9 @@
31
31
  "@manuscripts/assets": "^0.6.4",
32
32
  "@manuscripts/json-schema": "^2.2.2",
33
33
  "@manuscripts/library": "1.3.2",
34
- "@manuscripts/style-guide": "1.7.3",
34
+ "@manuscripts/style-guide": "1.7.4",
35
35
  "@manuscripts/track-changes-plugin": "^1.7.5",
36
- "@manuscripts/transform": "2.0.4",
36
+ "@manuscripts/transform": "2.1.1",
37
37
  "astrocite-eutils": "^0.16.4",
38
38
  "axios": "^1.6.7",
39
39
  "codemirror": "^5.58.1",