@manuscripts/body-editor 2.0.30 → 2.0.31

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.
@@ -15,7 +15,7 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.threeDotIcon = exports.deleteIcon = exports.alertIcon = exports.editAttrsTrackingIcon = exports.commentIcon = exports.editIcon = void 0;
18
+ exports.sectionCategoryIcon = exports.threeDotIcon = exports.deleteIcon = exports.alertIcon = exports.editAttrsTrackingIcon = exports.commentIcon = exports.editIcon = void 0;
19
19
  exports.editIcon = `
20
20
  <svg
21
21
  width="14"
@@ -170,3 +170,6 @@ exports.threeDotIcon = ` <svg width="4" height="16" viewBox="0 0 4 16" fill="non
170
170
  <circle cx="2" cy="14" r="2" fill="#6E6E6E"></circle>
171
171
  </svg>
172
172
  `;
173
+ exports.sectionCategoryIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="19" viewBox="0 0 16 19" fill="none">
174
+ <path d="M0.5 4C0.5 2.067 2.067 0.5 4 0.5H12C13.933 0.5 15.5 2.067 15.5 4V16.0505C15.5 17.1991 14.2619 17.9215 13.2619 17.3563L8.73809 14.7994C8.28008 14.5405 7.71992 14.5405 7.26191 14.7994L2.73809 17.3563C1.73815 17.9215 0.5 17.1991 0.5 16.0505V4Z" fill="white" stroke="#6E6E6E"/>
175
+ </svg>`;
@@ -38,6 +38,7 @@ const paragraphs_1 = __importDefault(require("../plugins/paragraphs"));
38
38
  const persist_1 = __importDefault(require("../plugins/persist"));
39
39
  const placeholder_1 = __importDefault(require("../plugins/placeholder"));
40
40
  const section_title_1 = __importDefault(require("../plugins/section_title"));
41
+ const section_category_1 = __importDefault(require("../plugins/section-category"));
41
42
  const sections_1 = __importDefault(require("../plugins/sections"));
42
43
  const selected_suggestion_1 = __importDefault(require("../plugins/selected-suggestion"));
43
44
  const table_footnote_1 = __importDefault(require("../plugins/table-footnote"));
@@ -75,6 +76,7 @@ exports.default = (props) => {
75
76
  (0, table_footnote_1.default)(),
76
77
  (0, editor_props_1.default)(props),
77
78
  (0, doi_1.default)(),
79
+ (0, section_category_1.default)(props),
78
80
  ];
79
81
  if (props.collabProvider) {
80
82
  allPlugins.push((0, prosemirror_collab_1.collab)({ version: props.collabProvider.currentVersion }));
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ /*!
3
+ * © 2024 Atypon Systems LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.getCategoryName = exports.isBackMatterSection = exports.isUnique = exports.isEditableSectionCategoryID = exports.uniqueSectionCategories = exports.uneditableSectionCategories = void 0;
19
+ exports.uneditableSectionCategories = [
20
+ 'MPSectionCategory:bibliography',
21
+ 'MPSectionCategory:keywords',
22
+ 'MPSectionCategory:list-of-figures',
23
+ 'MPSectionCategory:list-of-tables',
24
+ 'MPSectionCategory:toc',
25
+ ];
26
+ exports.uniqueSectionCategories = [
27
+ 'MPSectionCategory:abstract-graphical',
28
+ 'MPSectionCategory:abstract',
29
+ ];
30
+ const isEditableSectionCategoryID = (id) => !exports.uneditableSectionCategories.includes(id);
31
+ exports.isEditableSectionCategoryID = isEditableSectionCategoryID;
32
+ const isUnique = (categoryId) => {
33
+ return exports.uniqueSectionCategories.includes(categoryId);
34
+ };
35
+ exports.isUnique = isUnique;
36
+ const isBackMatterSection = (groupId) => {
37
+ return groupId === 'MPSectionCategory:backmatter';
38
+ };
39
+ exports.isBackMatterSection = isBackMatterSection;
40
+ const getCategoryName = (categories, id) => {
41
+ const category = categories.find((item) => item._id === id);
42
+ return category ? category.name : '';
43
+ };
44
+ exports.getCategoryName = getCategoryName;
@@ -60,7 +60,7 @@ const findParentElement = (selection, validIds) => (0, prosemirror_utils_1.findP
60
60
  exports.findParentElement = findParentElement;
61
61
  const isChildOfNodeTypes = (doc, pos, parentNodeTypes) => {
62
62
  const resolvedPos = doc.resolve(pos);
63
- for (let depth = resolvedPos.depth - 1; depth >= 0; depth--) {
63
+ for (let depth = resolvedPos.depth; depth >= 0; depth--) {
64
64
  if (parentNodeTypes.includes(resolvedPos.node(depth).type)) {
65
65
  return true;
66
66
  }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sectionCategoryKey = void 0;
4
+ const prosemirror_state_1 = require("prosemirror-state");
5
+ const prosemirror_view_1 = require("prosemirror-view");
6
+ const section_category_utils_1 = require("./section-category-utils");
7
+ exports.sectionCategoryKey = new prosemirror_state_1.PluginKey('section-category');
8
+ exports.default = (props) => new prosemirror_state_1.Plugin({
9
+ key: exports.sectionCategoryKey,
10
+ state: {
11
+ init: (_, state) => (0, section_category_utils_1.buildPluginState)(state, props),
12
+ apply: (tr, value, oldState, newState) => (0, section_category_utils_1.buildPluginState)(newState, props),
13
+ },
14
+ props: {
15
+ decorations: (state) => { var _a; return ((_a = exports.sectionCategoryKey.getState(state)) === null || _a === void 0 ? void 0 : _a.decorations) || prosemirror_view_1.DecorationSet.empty; },
16
+ },
17
+ });
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildPluginState = exports.sectionCategoryKey = void 0;
4
+ const transform_1 = require("@manuscripts/transform");
5
+ const prosemirror_state_1 = require("prosemirror-state");
6
+ const prosemirror_view_1 = require("prosemirror-view");
7
+ const assets_1 = require("../../assets");
8
+ const popper_1 = require("../../lib/popper");
9
+ const section_categories_1 = require("../../lib/section-categories");
10
+ const utils_1 = require("../../lib/utils");
11
+ exports.sectionCategoryKey = new prosemirror_state_1.PluginKey('section-category');
12
+ const popper = new popper_1.PopperManager();
13
+ function changeNodeAttrs(view, node, type, pos) {
14
+ view.dispatch(view.state.tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, node.attrs), { category: type })));
15
+ }
16
+ function createMenuItem(contents, handler, isDisabled = false, isSelected = false) {
17
+ const item = document.createElement('button');
18
+ item.className = `menu-item ${isDisabled ? 'disabled' : ''} ${isSelected ? 'selected' : ''}`;
19
+ item.textContent = contents;
20
+ item.addEventListener('mousedown', (event) => {
21
+ handler(event);
22
+ popper.destroy();
23
+ });
24
+ return item;
25
+ }
26
+ function createMenu(view, props, node, pos, currCategory) {
27
+ const menu = document.createElement('div');
28
+ menu.className = 'section-category menu';
29
+ const existingCatsCounted = getExistingCatsCounted(view.state);
30
+ const categories = getSortedSectionCategories(view.state, node, props.sectionCategories, pos, existingCatsCounted);
31
+ categories.forEach((category) => {
32
+ const item = createMenuItem(category.name, () => changeNodeAttrs(view, node, category._id, pos), category.isDisabled, currCategory === category._id);
33
+ menu.appendChild(item);
34
+ });
35
+ document.addEventListener('mousedown', (event) => {
36
+ if (!menu.contains(event.target)) {
37
+ popper.destroy();
38
+ }
39
+ });
40
+ return menu;
41
+ }
42
+ function createButton(view, props, node, pos, category, canEdit = true) {
43
+ const arrow = document.createElement('div');
44
+ arrow.className = 'section-category popper-arrow';
45
+ const button = document.createElement('button');
46
+ button.innerHTML = assets_1.sectionCategoryIcon;
47
+ button.className = `section-category-button ${category && 'assigned'}`;
48
+ if (canEdit) {
49
+ button.addEventListener('mousedown', () => {
50
+ popper.destroy();
51
+ const menu = createMenu(view, props, node, pos, category);
52
+ popper.show(button, menu, 'bottom-end', false, [
53
+ { name: 'offset', options: { offset: [0, -10] } },
54
+ ]);
55
+ });
56
+ }
57
+ else {
58
+ button.addEventListener('mouseenter', () => {
59
+ const tooltip = document.createElement('div');
60
+ tooltip.className = 'section-category tooltip';
61
+ tooltip.textContent = 'Category:';
62
+ const span = document.createElement('span');
63
+ span.textContent = (0, section_categories_1.getCategoryName)(props.sectionCategories, category);
64
+ tooltip.appendChild(span);
65
+ tooltip.appendChild(arrow);
66
+ popper.show(button, tooltip, 'left', false, [
67
+ { name: 'offset', options: { offset: [0, 10] } },
68
+ { name: 'arrow', options: { element: arrow } },
69
+ ]);
70
+ });
71
+ button.addEventListener('mouseleave', () => {
72
+ popper.destroy();
73
+ });
74
+ }
75
+ return button;
76
+ }
77
+ function buildPluginState(state, props) {
78
+ const decorations = [];
79
+ const can = props.getCapabilities();
80
+ state.doc.descendants((node, pos) => {
81
+ if ((0, transform_1.isSectionNode)(node)) {
82
+ const attrs = node.attrs;
83
+ if ((0, section_categories_1.isEditableSectionCategoryID)(attrs.category) &&
84
+ !(0, section_categories_1.isUnique)(attrs.category)) {
85
+ decorations.push(prosemirror_view_1.Decoration.widget(pos + 1, (view) => createButton(view, props, node, pos, attrs.category, can === null || can === void 0 ? void 0 : can.editArticle)));
86
+ }
87
+ }
88
+ });
89
+ return { decorations: prosemirror_view_1.DecorationSet.create(state.doc, decorations) };
90
+ }
91
+ exports.buildPluginState = buildPluginState;
92
+ function getExistingCatsCounted(state) {
93
+ const existingCatsCounted = {};
94
+ state.doc.descendants((node) => {
95
+ var _a;
96
+ if (node.type.name === 'section' &&
97
+ ((_a = node.attrs.category) === null || _a === void 0 ? void 0 : _a.startsWith('MPSectionCategory:'))) {
98
+ existingCatsCounted[node.attrs.category] =
99
+ (existingCatsCounted[node.attrs.category] || 0) + 1;
100
+ }
101
+ });
102
+ return existingCatsCounted;
103
+ }
104
+ function getSortedSectionCategories(state, container, sectionCategories, pos, existingCatsCounted) {
105
+ var _a;
106
+ let groupIDToUse = '';
107
+ if (container.attrs.category) {
108
+ const sectionCategory = sectionCategories.find(({ _id }) => _id === container.attrs.category);
109
+ if (sectionCategory) {
110
+ groupIDToUse = (_a = sectionCategory.groupIDs) === null || _a === void 0 ? void 0 : _a[0];
111
+ }
112
+ }
113
+ else {
114
+ const isChildOfBody = (0, utils_1.isChildOfNodeTypes)(state.doc, pos, [
115
+ transform_1.schema.nodes.body,
116
+ ]);
117
+ if (isChildOfBody) {
118
+ groupIDToUse = 'MPSectionCategory:body';
119
+ }
120
+ else {
121
+ groupIDToUse = 'MPSectionCategory:backmatter';
122
+ }
123
+ }
124
+ if (!groupIDToUse) {
125
+ return [];
126
+ }
127
+ return sectionCategories
128
+ .filter((category) => { var _a; return (_a = category.groupIDs) === null || _a === void 0 ? void 0 : _a.includes(groupIDToUse); })
129
+ .map((category) => {
130
+ var _a, _b;
131
+ return (Object.assign(Object.assign({}, category), { isDisabled: Boolean(existingCatsCounted[category._id] &&
132
+ (0, section_categories_1.isBackMatterSection)((_b = (_a = category.groupIDs) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : '')) }));
133
+ });
134
+ }
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MATHJAX_VERSION = exports.VERSION = void 0;
4
- exports.VERSION = '2.0.30';
4
+ exports.VERSION = '2.0.31';
5
5
  exports.MATHJAX_VERSION = '3.2.2';
@@ -85,7 +85,6 @@ class InlineFootnoteView extends base_node_view_1.BaseNodeView {
85
85
  return;
86
86
  }
87
87
  const fnState = footnotes_1.footnotesKey.getState(this.view.state);
88
- console.log(fnState);
89
88
  if (fnState) {
90
89
  this.activateModal({
91
90
  notes: Array.from(fnState.unusedFootnotes.values()).map((n) => ({
package/dist/es/assets.js CHANGED
@@ -167,3 +167,6 @@ export const threeDotIcon = ` <svg width="4" height="16" viewBox="0 0 4 16" fill
167
167
  <circle cx="2" cy="14" r="2" fill="#6E6E6E"></circle>
168
168
  </svg>
169
169
  `;
170
+ export const sectionCategoryIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="19" viewBox="0 0 16 19" fill="none">
171
+ <path d="M0.5 4C0.5 2.067 2.067 0.5 4 0.5H12C13.933 0.5 15.5 2.067 15.5 4V16.0505C15.5 17.1991 14.2619 17.9215 13.2619 17.3563L8.73809 14.7994C8.28008 14.5405 7.71992 14.5405 7.26191 14.7994L2.73809 17.3563C1.73815 17.9215 0.5 17.1991 0.5 16.0505V4Z" fill="white" stroke="#6E6E6E"/>
172
+ </svg>`;
@@ -33,6 +33,7 @@ import paragraphs from '../plugins/paragraphs';
33
33
  import persist from '../plugins/persist';
34
34
  import placeholder from '../plugins/placeholder';
35
35
  import section_title from '../plugins/section_title';
36
+ import section_category from '../plugins/section-category';
36
37
  import sections from '../plugins/sections';
37
38
  import selected_suggestion from '../plugins/selected-suggestion';
38
39
  import table_footnote from '../plugins/table-footnote';
@@ -70,6 +71,7 @@ export default (props) => {
70
71
  table_footnote(),
71
72
  editorProps(props),
72
73
  doi(),
74
+ section_category(props),
73
75
  ];
74
76
  if (props.collabProvider) {
75
77
  allPlugins.push(collab({ version: props.collabProvider.currentVersion }));
@@ -0,0 +1,37 @@
1
+ /*!
2
+ * © 2024 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
+ export const uneditableSectionCategories = [
17
+ 'MPSectionCategory:bibliography',
18
+ 'MPSectionCategory:keywords',
19
+ 'MPSectionCategory:list-of-figures',
20
+ 'MPSectionCategory:list-of-tables',
21
+ 'MPSectionCategory:toc',
22
+ ];
23
+ export const uniqueSectionCategories = [
24
+ 'MPSectionCategory:abstract-graphical',
25
+ 'MPSectionCategory:abstract',
26
+ ];
27
+ export const isEditableSectionCategoryID = (id) => !uneditableSectionCategories.includes(id);
28
+ export const isUnique = (categoryId) => {
29
+ return uniqueSectionCategories.includes(categoryId);
30
+ };
31
+ export const isBackMatterSection = (groupId) => {
32
+ return groupId === 'MPSectionCategory:backmatter';
33
+ };
34
+ export const getCategoryName = (categories, id) => {
35
+ const category = categories.find((item) => item._id === id);
36
+ return category ? category.name : '';
37
+ };
@@ -52,7 +52,7 @@ export const findParentElement = (selection, validIds) => findParentNode((node)
52
52
  })(selection);
53
53
  export const isChildOfNodeTypes = (doc, pos, parentNodeTypes) => {
54
54
  const resolvedPos = doc.resolve(pos);
55
- for (let depth = resolvedPos.depth - 1; depth >= 0; depth--) {
55
+ for (let depth = resolvedPos.depth; depth >= 0; depth--) {
56
56
  if (parentNodeTypes.includes(resolvedPos.node(depth).type)) {
57
57
  return true;
58
58
  }
@@ -0,0 +1,14 @@
1
+ import { Plugin, PluginKey } from 'prosemirror-state';
2
+ import { DecorationSet } from 'prosemirror-view';
3
+ import { buildPluginState } from './section-category-utils';
4
+ export const sectionCategoryKey = new PluginKey('section-category');
5
+ export default (props) => new Plugin({
6
+ key: sectionCategoryKey,
7
+ state: {
8
+ init: (_, state) => buildPluginState(state, props),
9
+ apply: (tr, value, oldState, newState) => buildPluginState(newState, props),
10
+ },
11
+ props: {
12
+ decorations: (state) => { var _a; return ((_a = sectionCategoryKey.getState(state)) === null || _a === void 0 ? void 0 : _a.decorations) || DecorationSet.empty; },
13
+ },
14
+ });
@@ -0,0 +1,130 @@
1
+ import { isSectionNode, schema } from '@manuscripts/transform';
2
+ import { PluginKey } from 'prosemirror-state';
3
+ import { Decoration, DecorationSet } from 'prosemirror-view';
4
+ import { sectionCategoryIcon } from '../../assets';
5
+ import { PopperManager } from '../../lib/popper';
6
+ import { getCategoryName, isBackMatterSection, isEditableSectionCategoryID, isUnique, } from '../../lib/section-categories';
7
+ import { isChildOfNodeTypes } from '../../lib/utils';
8
+ export const sectionCategoryKey = new PluginKey('section-category');
9
+ const popper = new PopperManager();
10
+ function changeNodeAttrs(view, node, type, pos) {
11
+ view.dispatch(view.state.tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, node.attrs), { category: type })));
12
+ }
13
+ function createMenuItem(contents, handler, isDisabled = false, isSelected = false) {
14
+ const item = document.createElement('button');
15
+ item.className = `menu-item ${isDisabled ? 'disabled' : ''} ${isSelected ? 'selected' : ''}`;
16
+ item.textContent = contents;
17
+ item.addEventListener('mousedown', (event) => {
18
+ handler(event);
19
+ popper.destroy();
20
+ });
21
+ return item;
22
+ }
23
+ function createMenu(view, props, node, pos, currCategory) {
24
+ const menu = document.createElement('div');
25
+ menu.className = 'section-category menu';
26
+ const existingCatsCounted = getExistingCatsCounted(view.state);
27
+ const categories = getSortedSectionCategories(view.state, node, props.sectionCategories, pos, existingCatsCounted);
28
+ categories.forEach((category) => {
29
+ const item = createMenuItem(category.name, () => changeNodeAttrs(view, node, category._id, pos), category.isDisabled, currCategory === category._id);
30
+ menu.appendChild(item);
31
+ });
32
+ document.addEventListener('mousedown', (event) => {
33
+ if (!menu.contains(event.target)) {
34
+ popper.destroy();
35
+ }
36
+ });
37
+ return menu;
38
+ }
39
+ function createButton(view, props, node, pos, category, canEdit = true) {
40
+ const arrow = document.createElement('div');
41
+ arrow.className = 'section-category popper-arrow';
42
+ const button = document.createElement('button');
43
+ button.innerHTML = sectionCategoryIcon;
44
+ button.className = `section-category-button ${category && 'assigned'}`;
45
+ if (canEdit) {
46
+ button.addEventListener('mousedown', () => {
47
+ popper.destroy();
48
+ const menu = createMenu(view, props, node, pos, category);
49
+ popper.show(button, menu, 'bottom-end', false, [
50
+ { name: 'offset', options: { offset: [0, -10] } },
51
+ ]);
52
+ });
53
+ }
54
+ else {
55
+ button.addEventListener('mouseenter', () => {
56
+ const tooltip = document.createElement('div');
57
+ tooltip.className = 'section-category tooltip';
58
+ tooltip.textContent = 'Category:';
59
+ const span = document.createElement('span');
60
+ span.textContent = getCategoryName(props.sectionCategories, category);
61
+ tooltip.appendChild(span);
62
+ tooltip.appendChild(arrow);
63
+ popper.show(button, tooltip, 'left', false, [
64
+ { name: 'offset', options: { offset: [0, 10] } },
65
+ { name: 'arrow', options: { element: arrow } },
66
+ ]);
67
+ });
68
+ button.addEventListener('mouseleave', () => {
69
+ popper.destroy();
70
+ });
71
+ }
72
+ return button;
73
+ }
74
+ export function buildPluginState(state, props) {
75
+ const decorations = [];
76
+ const can = props.getCapabilities();
77
+ state.doc.descendants((node, pos) => {
78
+ if (isSectionNode(node)) {
79
+ const attrs = node.attrs;
80
+ if (isEditableSectionCategoryID(attrs.category) &&
81
+ !isUnique(attrs.category)) {
82
+ decorations.push(Decoration.widget(pos + 1, (view) => createButton(view, props, node, pos, attrs.category, can === null || can === void 0 ? void 0 : can.editArticle)));
83
+ }
84
+ }
85
+ });
86
+ return { decorations: DecorationSet.create(state.doc, decorations) };
87
+ }
88
+ function getExistingCatsCounted(state) {
89
+ const existingCatsCounted = {};
90
+ state.doc.descendants((node) => {
91
+ var _a;
92
+ if (node.type.name === 'section' &&
93
+ ((_a = node.attrs.category) === null || _a === void 0 ? void 0 : _a.startsWith('MPSectionCategory:'))) {
94
+ existingCatsCounted[node.attrs.category] =
95
+ (existingCatsCounted[node.attrs.category] || 0) + 1;
96
+ }
97
+ });
98
+ return existingCatsCounted;
99
+ }
100
+ function getSortedSectionCategories(state, container, sectionCategories, pos, existingCatsCounted) {
101
+ var _a;
102
+ let groupIDToUse = '';
103
+ if (container.attrs.category) {
104
+ const sectionCategory = sectionCategories.find(({ _id }) => _id === container.attrs.category);
105
+ if (sectionCategory) {
106
+ groupIDToUse = (_a = sectionCategory.groupIDs) === null || _a === void 0 ? void 0 : _a[0];
107
+ }
108
+ }
109
+ else {
110
+ const isChildOfBody = isChildOfNodeTypes(state.doc, pos, [
111
+ schema.nodes.body,
112
+ ]);
113
+ if (isChildOfBody) {
114
+ groupIDToUse = 'MPSectionCategory:body';
115
+ }
116
+ else {
117
+ groupIDToUse = 'MPSectionCategory:backmatter';
118
+ }
119
+ }
120
+ if (!groupIDToUse) {
121
+ return [];
122
+ }
123
+ return sectionCategories
124
+ .filter((category) => { var _a; return (_a = category.groupIDs) === null || _a === void 0 ? void 0 : _a.includes(groupIDToUse); })
125
+ .map((category) => {
126
+ var _a, _b;
127
+ return (Object.assign(Object.assign({}, category), { isDisabled: Boolean(existingCatsCounted[category._id] &&
128
+ isBackMatterSection((_b = (_a = category.groupIDs) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : '')) }));
129
+ });
130
+ }
@@ -1,2 +1,2 @@
1
- export const VERSION = '2.0.30';
1
+ export const VERSION = '2.0.31';
2
2
  export const MATHJAX_VERSION = '3.2.2';
@@ -79,7 +79,6 @@ export class InlineFootnoteView extends BaseNodeView {
79
79
  return;
80
80
  }
81
81
  const fnState = footnotesKey.getState(this.view.state);
82
- console.log(fnState);
83
82
  if (fnState) {
84
83
  this.activateModal({
85
84
  notes: Array.from(fnState.unusedFootnotes.values()).map((n) => ({
@@ -19,3 +19,4 @@ export declare const editAttrsTrackingIcon = "\n <svg\n width=\"16\"\n hei
19
19
  export declare const alertIcon = "\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M6 12C2.68629 12 1.18852e-06 9.31371 1.47821e-06 6C1.7679e-06 2.68629 2.68629 1.39444e-07 6 4.29138e-07C9.31371 7.18831e-07 12 2.68629 12 6C12 9.31371 9.31371 12 6 12ZM6.74998 2.99996L6.75 6.37462C6.75 6.78819 6.41522 7.12243 6.00166 7.12334C5.58681 7.12426 5.25001 6.78821 5.25001 6.37335L5.25 3.00082C5.25 2.58629 5.58629 2.25037 6.00082 2.25083C6.4147 2.25128 6.74998 2.58607 6.74998 2.99996ZM6.75 8.99263C6.75 9.46884 6.47288 9.75 5.99853 9.75C5.52419 9.75 5.25 9.47179 5.25 8.99558C5.25 8.51937 5.52421 8.25 5.99855 8.25C6.47289 8.25 6.75 8.51642 6.75 8.99263Z\"\n fill=\"#FE8F1F\"\n />\n </svg>\n";
20
20
  export declare const deleteIcon = "\n <svg\n width=\"13\"\n height=\"17\"\n viewBox=\"0 0 13 15\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M2.00001 3C2 3.00135 2 3.00269 2 3.00404V13.004C2 13.5563 2.44772 14.004 3 14.004H10C10.5523 14.004 11 13.5563 11 13.004V3.00404C11 3.00269 11 3.00135 11 3C11.5978 3.34581 12 3.99215 12 4.73244V13.004C12 14.1086 11.1046 15.004 10 15.004H3C1.89543 15.004 1 14.1086 1 13.004V4.73244C1 3.99215 1.4022 3.34581 2.00001 3Z\"\n fill=\"#C9C9C9\"\n />\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M4.5 0C3.67157 0 3 0.671573 3 1.5V3.5C3 4.32843 3.67157 5 4.5 5H8.5C9.32843 5 10 4.32843 10 3.5V1.5C10 0.671573 9.32843 0 8.5 0H4.5ZM9 1.5C9 1.22386 8.77614 1 8.5 1H4.5C4.22386 1 4 1.22386 4 1.5C4 1.77614 4.22386 2 4.5 2H8.5C8.77614 2 9 1.77614 9 1.5Z\"\n fill=\"#C9C9C9\"\n />\n <rect\n y=\"2\"\n width=\"13\"\n height=\"3\"\n rx=\"1.5\"\n fill=\"#C9C9C9\"\n />\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M8 7.5C8 7.22386 8.22386 7 8.5 7C8.77614 7 9 7.22386 9 7.5V11.5C9 11.7761 8.77614 12 8.5 12C8.22386 12 8 11.7761 8 11.5V7.5Z\"\n fill=\"#C9C9C9\"\n />\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M4 7.5C4 7.22386 4.22386 7 4.5 7C4.77614 7 5 7.22386 5 7.5V11.5C5 11.7761 4.77614 12 4.5 12C4.22386 12 4 11.7761 4 11.5V7.5Z\"\n fill=\"#C9C9C9\"\n />\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M11.5 3C11.7761 3 12 3.22386 12 3.5C12 3.77614 11.7761 4 11.5 4L1.5 4C1.22386 4 1 3.77614 1 3.5C1 3.22386 1.22386 3 1.5 3L11.5 3Z\"\n fill=\"white\"\n />\n</svg>";
21
21
  export declare const threeDotIcon = " <svg width=\"4\" height=\"16\" viewBox=\"0 0 4 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<circle cx=\"2\" cy=\"2\" r=\"2\" fill=\"#6E6E6E\"></circle>\n<circle cx=\"2\" cy=\"8\" r=\"2\" fill=\"#6E6E6E\"></circle>\n<circle cx=\"2\" cy=\"14\" r=\"2\" fill=\"#6E6E6E\"></circle>\n</svg>\n";
22
+ export declare const sectionCategoryIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"19\" viewBox=\"0 0 16 19\" fill=\"none\">\n<path d=\"M0.5 4C0.5 2.067 2.067 0.5 4 0.5H12C13.933 0.5 15.5 2.067 15.5 4V16.0505C15.5 17.1991 14.2619 17.9215 13.2619 17.3563L8.73809 14.7994C8.28008 14.5405 7.71992 14.5405 7.26191 14.7994L2.73809 17.3563C1.73815 17.9215 0.5 17.1991 0.5 16.0505V4Z\" fill=\"white\" stroke=\"#6E6E6E\"/>\n</svg>";
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import 'prosemirror-view/style/prosemirror.css';
17
- import { UserProfile } from '@manuscripts/json-schema';
17
+ import { SectionCategory, UserProfile } from '@manuscripts/json-schema';
18
18
  import { Capabilities } from '@manuscripts/style-guide';
19
19
  import { ManuscriptNode } from '@manuscripts/transform';
20
20
  import { EditorState } from 'prosemirror-state';
@@ -45,6 +45,7 @@ export interface EditorProps {
45
45
  userID: string;
46
46
  debug: boolean;
47
47
  cslProps: CSLProps;
48
+ sectionCategories: SectionCategory[];
48
49
  collabProvider?: CollabProvider;
49
50
  navigate: NavigateFunction;
50
51
  location: Location;
@@ -0,0 +1,22 @@
1
+ /*!
2
+ * © 2024 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 { SectionCategory } from '@manuscripts/json-schema';
17
+ export declare const uneditableSectionCategories: string[];
18
+ export declare const uniqueSectionCategories: string[];
19
+ export declare const isEditableSectionCategoryID: (id: string) => boolean;
20
+ export declare const isUnique: (categoryId: string) => boolean;
21
+ export declare const isBackMatterSection: (groupId: string) => boolean;
22
+ export declare const getCategoryName: (categories: SectionCategory[], id: string) => string;
@@ -0,0 +1,13 @@
1
+ import { SectionCategory } from '@manuscripts/json-schema';
2
+ import { Plugin, PluginKey } from 'prosemirror-state';
3
+ import { DecorationSet } from 'prosemirror-view';
4
+ import { EditorProps } from '../../configs/ManuscriptsEditor';
5
+ export declare const sectionCategoryKey: PluginKey<PluginState>;
6
+ export interface PluginState {
7
+ decorations: DecorationSet;
8
+ }
9
+ export interface SectionCategoryProps extends EditorProps {
10
+ sectionCategories: SectionCategory[];
11
+ }
12
+ declare const _default: (props: SectionCategoryProps) => Plugin<PluginState>;
13
+ export default _default;
@@ -0,0 +1,12 @@
1
+ import { SectionCategory } from '@manuscripts/json-schema';
2
+ import { EditorState, PluginKey } from 'prosemirror-state';
3
+ import { DecorationSet } from 'prosemirror-view';
4
+ import { EditorProps } from '../../configs/ManuscriptsEditor';
5
+ export declare const sectionCategoryKey: PluginKey<PluginState>;
6
+ export interface PluginState {
7
+ decorations: DecorationSet;
8
+ }
9
+ export interface SectionCategoryProps extends EditorProps {
10
+ sectionCategories: SectionCategory[];
11
+ }
12
+ export declare function buildPluginState(state: EditorState, props: SectionCategoryProps): PluginState;
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "2.0.30";
1
+ export declare const VERSION = "2.0.31";
2
2
  export declare const MATHJAX_VERSION = "3.2.2";
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": "2.0.30",
4
+ "version": "2.0.31",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -30,11 +30,11 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@iarna/word-count": "^1.1.2",
33
- "@manuscripts/json-schema": "2.2.10",
33
+ "@manuscripts/json-schema": "2.2.11-LEAN-3647.0",
34
34
  "@manuscripts/library": "1.3.11",
35
- "@manuscripts/style-guide": "2.0.7",
35
+ "@manuscripts/style-guide": "2.0.8",
36
36
  "@manuscripts/track-changes-plugin": "1.7.17",
37
- "@manuscripts/transform": "2.3.25",
37
+ "@manuscripts/transform": "2.3.26",
38
38
  "@popperjs/core": "^2.11.8",
39
39
  "astrocite-eutils": "^0.16.4",
40
40
  "codemirror": "^5.58.1",
@@ -738,4 +738,114 @@ span.accepted .selected-suggestion,
738
738
 
739
739
  .ProseMirror td:hover > .table-context-menu-button, th:hover > .table-context-menu-button, .open-context-menu {
740
740
  visibility: visible !important;
741
- }
741
+ }
742
+
743
+ .section-category-button {
744
+ position: absolute;
745
+ right: 0;
746
+ top: 14px;
747
+ line-height: 1.6;
748
+ background: unset;
749
+ border: none;
750
+ opacity: 0;
751
+ padding: 0;
752
+ margin: 0 6px;
753
+ cursor: pointer;
754
+ z-index: 10;
755
+ }
756
+
757
+ .section-category-button svg {
758
+ width: 16px;
759
+ height: 20px;
760
+ position: relative;
761
+ }
762
+
763
+ .section-category-button:not(.assigned) path {
764
+ fill: #FFE0B2;
765
+ }
766
+
767
+ .section-category-button.assigned:after {
768
+ top: 2px;
769
+ right: 5px;
770
+ position: absolute;
771
+ content: '';
772
+ height: 8px;
773
+ width: 4px;
774
+ border-bottom: 2px solid #36B260;
775
+ border-right: 2px solid #36B260;
776
+ transform: rotate(45deg);
777
+ }
778
+
779
+ .ProseMirror .block-container:hover .section-category-button {
780
+ opacity: 1;
781
+ }
782
+ .section-category.menu {
783
+ border-radius: 8px;
784
+ border: 1px solid #E2E2E2;
785
+ box-shadow: 0px 4px 9px 0px rgba(0, 0, 0, 0.30);
786
+ }
787
+
788
+ .section-category.menu .menu-item {
789
+ padding: 7px 8px 8px 16px;
790
+ box-sizing: border-box;
791
+ min-width: 176px;
792
+ height: 37px;
793
+ padding-right: 40px;
794
+ font-family: Lato;
795
+ font-size: 14px;
796
+ font-style: normal;
797
+ font-weight: 400;
798
+ line-height: 24px;
799
+ position: relative;
800
+ background: none;
801
+ border: unset;
802
+ display: flex;
803
+ }
804
+
805
+ .section-category.menu .menu-item.selected:after {
806
+ top: 10.5px;
807
+ right: 19px;
808
+ position: absolute;
809
+ content: '';
810
+ height: 10px;
811
+ width: 5px;
812
+ border-bottom: 2px solid #36B260;
813
+ border-right: 2px solid #36B260;
814
+ transform: rotate(45deg);
815
+ }
816
+
817
+ .section-category.menu .menu-item.disabled {
818
+ opacity: 0.5;
819
+ cursor: not-allowed;
820
+ pointer-events: none;
821
+ }
822
+
823
+ .section-category.tooltip {
824
+ font-family: 'Lato, sans-serif';
825
+ padding: 8px;
826
+ display: flex;
827
+ align-items: center;
828
+ border-radius: 6px;
829
+ background: #E2E2E2;
830
+ font-size: 12px;
831
+ font-style: normal;
832
+ font-weight: 400;
833
+ color: #353535;
834
+ line-height: 16px;
835
+ }
836
+
837
+ .section-category.tooltip span {
838
+ color: #353535;
839
+ font-size: 12px;
840
+ font-style: normal;
841
+ font-weight: 700;
842
+ line-height: 16px;
843
+ margin-left: 3.2px;
844
+ }
845
+
846
+ .popper[data-popper-placement] .section-category.popper-arrow {
847
+ border-width: 10px;
848
+ right: -20px;
849
+ top: 6px;
850
+ pointer-events: none;
851
+ }