@seafile/sdoc-editor 0.5.70 → 0.5.72
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/basic-sdk/editor/editable-article.js +4 -3
- package/dist/basic-sdk/extension/commons/file-insert-dialog/index.js +39 -13
- package/dist/basic-sdk/extension/commons/insert-element-dialog/index.js +12 -2
- package/dist/basic-sdk/extension/constants/element-type.js +2 -0
- package/dist/basic-sdk/extension/constants/index.js +3 -3
- package/dist/basic-sdk/extension/constants/menus-config.js +8 -2
- package/dist/basic-sdk/extension/plugins/index.js +5 -3
- package/dist/basic-sdk/extension/plugins/link/dialog/add-link-dialog/index.js +5 -2
- package/dist/basic-sdk/extension/plugins/link/plugin.js +26 -11
- package/dist/basic-sdk/extension/plugins/sdoc-link/hover-menu/index.js +4 -3
- package/dist/basic-sdk/extension/plugins/sdoc-link/plugin.js +3 -2
- package/dist/basic-sdk/extension/plugins/sdoc-link/render/render-elem.js +8 -2
- package/dist/basic-sdk/extension/plugins/{column → seatable-column}/helpers.js +59 -8
- package/dist/basic-sdk/extension/plugins/{column → seatable-column}/index.js +2 -4
- package/dist/basic-sdk/extension/plugins/seatable-column/menu/column-list-menu.css +35 -0
- package/dist/basic-sdk/extension/plugins/seatable-column/menu/column-list-menu.js +47 -0
- package/dist/basic-sdk/extension/plugins/seatable-column/menu/index.js +31 -0
- package/dist/basic-sdk/extension/plugins/seatable-column/model.js +12 -0
- package/dist/basic-sdk/extension/plugins/seatable-column/render-elem.js +48 -0
- package/dist/basic-sdk/extension/plugins/seatable-views/helpers.js +50 -0
- package/dist/basic-sdk/extension/plugins/seatable-views/index.js +14 -0
- package/dist/basic-sdk/extension/plugins/seatable-views/menu/index.js +40 -0
- package/dist/basic-sdk/extension/plugins/seatable-views/model.js +12 -0
- package/dist/basic-sdk/extension/plugins/seatable-views/plugin.js +52 -0
- package/dist/basic-sdk/extension/plugins/seatable-views/render-element/index.css +20 -0
- package/dist/basic-sdk/extension/plugins/seatable-views/render-element/index.js +8 -0
- package/dist/basic-sdk/extension/plugins/seatable-views/render-element/record-header.js +19 -0
- package/dist/basic-sdk/extension/plugins/seatable-views/render-element/record-item.js +22 -0
- package/dist/basic-sdk/extension/plugins/seatable-views/render-element/record-list.js +19 -0
- package/dist/basic-sdk/extension/plugins/seatable-views/render-element/seatable-view.js +57 -0
- package/dist/basic-sdk/extension/plugins/table/render/table-header/rows-header/index.js +0 -1
- package/dist/basic-sdk/extension/plugins/wiki-link/helpers.js +60 -0
- package/dist/basic-sdk/extension/plugins/wiki-link/index.js +9 -0
- package/dist/basic-sdk/extension/render/custom-element.js +16 -7
- package/dist/basic-sdk/extension/toolbar/header-toolbar/index.js +1 -6
- package/dist/basic-sdk/extension/toolbar/header-toolbar/insert-toolbar/index.js +3 -2
- package/dist/constants/index.js +2 -0
- package/dist/index.js +1 -2
- package/dist/pages/document-plugin-editor.js +25 -5
- package/package.json +1 -1
- package/public/locales/cs/sdoc-editor.json +2 -1
- package/public/locales/de/sdoc-editor.json +2 -1
- package/public/locales/en/sdoc-editor.json +4 -2
- package/public/locales/es/sdoc-editor.json +2 -1
- package/public/locales/es_AR/sdoc-editor.json +465 -0
- package/public/locales/es_MX/sdoc-editor.json +465 -0
- package/public/locales/fr/sdoc-editor.json +2 -1
- package/public/locales/it/sdoc-editor.json +2 -1
- package/public/locales/ru/sdoc-editor.json +5 -4
- package/public/locales/zh_CN/sdoc-editor.json +2 -1
- package/dist/basic-sdk/extension/plugins/column/menu/index.js +0 -28
- package/dist/basic-sdk/extension/plugins/column/model.js +0 -14
- package/dist/basic-sdk/extension/plugins/column/render-elem.js +0 -111
- package/dist/pages/document-plugin-viewer.js +0 -55
- package/public/locales/es-AR/sdoc-editor.json +0 -169
- package/public/locales/es-MX/sdoc-editor.json +0 -169
- /package/dist/basic-sdk/extension/plugins/{column → seatable-column}/constants/cell-types.js +0 -0
- /package/dist/basic-sdk/extension/plugins/{column → seatable-column}/constants/column.js +0 -0
- /package/dist/basic-sdk/extension/plugins/{column → seatable-column}/plugin.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useMemo, Fragment } from 'react';
|
|
2
2
|
import { Editable, ReactEditor, Slate } from '@seafile/slate-react';
|
|
3
|
-
import { Editor, Node, Transforms } from '@seafile/slate';
|
|
3
|
+
import { Editor, Node, Range, Transforms } from '@seafile/slate';
|
|
4
4
|
import scrollIntoView from 'scroll-into-view-if-needed';
|
|
5
5
|
import { renderLeaf, renderElement, ContextToolbar, SideToolbar } from '../extension';
|
|
6
6
|
import { getAboveBlockNode, getNextNode, getPrevNode, isSelectionAtBlockEnd, isSelectionAtBlockStart, getCurrentNode, isCurrentLineEmpty, isCurrentLineHasText } from '../extension/core';
|
|
@@ -89,8 +89,9 @@ const EditableArticle = _ref => {
|
|
|
89
89
|
if (getPrevNode(editor)) {
|
|
90
90
|
[prevNode, prevPath] = getPrevNode(editor);
|
|
91
91
|
}
|
|
92
|
-
// If the cursor is at the beginning, and the current line is not empty, is not a CODE_LINE, and the previous line is a CODE_LINE.
|
|
93
|
-
|
|
92
|
+
// If the cursor is collapsed at the beginning, and the current line is not empty, is not a CODE_LINE, and the previous line is a CODE_LINE.
|
|
93
|
+
const isCursorCollapsed = Range.isCollapsed(editor.selection);
|
|
94
|
+
if (isCursorCollapsed && prevNode && isSelectionAtBlockStart(editor) && !isCurrentLineEmpty(editor) && prevNode.type === CODE_LINE && currentNode.type !== CODE_LINE) {
|
|
94
95
|
if (!isCurrentLineHasText(currentNode)) {
|
|
95
96
|
const prevNodeText = Node.string(prevNode);
|
|
96
97
|
Transforms.removeNodes(editor, {
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
-
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { ReactEditor } from '@seafile/slate-react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
|
-
import { Editor } from '@seafile/slate';
|
|
5
|
+
import { Editor, Node } from '@seafile/slate';
|
|
6
6
|
import classNames from 'classnames';
|
|
7
7
|
import context from '../../../../context';
|
|
8
8
|
import { LocalStorage, isEnglish } from '../../../../utils';
|
|
9
9
|
import { EXTERNAL_EVENT } from '../../../../constants';
|
|
10
10
|
import EventBus from '../../../utils/event-bus';
|
|
11
|
-
import { INTERNAL_EVENT } from '../../../constants';
|
|
11
|
+
import { INTERNAL_EVENT, WIKI_EDITOR } from '../../../constants';
|
|
12
12
|
import { SDOC_LINK } from '../../constants';
|
|
13
13
|
import toaster from '../../../../components/toast';
|
|
14
14
|
import { insertSdocFileLink, insertTextWhenRemoveFileNameCollector, removeTempInput } from '../../plugins/sdoc-link/helpers';
|
|
15
|
+
import { insertWikiPageLink } from '../../plugins/wiki-link/helpers';
|
|
15
16
|
import './style.css';
|
|
16
17
|
const FileLinkInsertDialog = _ref => {
|
|
17
18
|
let {
|
|
@@ -19,7 +20,6 @@ const FileLinkInsertDialog = _ref => {
|
|
|
19
20
|
element,
|
|
20
21
|
closeDialog
|
|
21
22
|
} = _ref;
|
|
22
|
-
const eventBus = EventBus.getInstance();
|
|
23
23
|
const historyFileWrapperRef = useRef(document.querySelector('.sdoc-history-files-wrapper'));
|
|
24
24
|
const [files, setFiles] = useState([]);
|
|
25
25
|
const [position, setPosition] = useState({
|
|
@@ -31,6 +31,7 @@ const FileLinkInsertDialog = _ref => {
|
|
|
31
31
|
t
|
|
32
32
|
} = useTranslation();
|
|
33
33
|
const [header, setHeader] = useState(t('Recent_visited'));
|
|
34
|
+
const eventBus = EventBus.getInstance();
|
|
34
35
|
const deleteInputAndInsertText = useCallback(function () {
|
|
35
36
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
36
37
|
args[_key] = arguments[_key];
|
|
@@ -63,6 +64,17 @@ const FileLinkInsertDialog = _ref => {
|
|
|
63
64
|
const counterTopGap = 8;
|
|
64
65
|
popoverTop = top - popoverHeight - counterTopGap;
|
|
65
66
|
}
|
|
67
|
+
if (editor.editorType === WIKI_EDITOR) {
|
|
68
|
+
const wikiEditorContainer = document.querySelector('.sdoc-editor-container');
|
|
69
|
+
if (wikiEditorContainer) {
|
|
70
|
+
const {
|
|
71
|
+
left,
|
|
72
|
+
top
|
|
73
|
+
} = wikiEditorContainer.getBoundingClientRect();
|
|
74
|
+
popoverLeft -= left;
|
|
75
|
+
popoverTop -= top;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
66
78
|
setPosition({
|
|
67
79
|
top: popoverTop,
|
|
68
80
|
left: popoverLeft
|
|
@@ -81,9 +93,10 @@ const FileLinkInsertDialog = _ref => {
|
|
|
81
93
|
getPosition();
|
|
82
94
|
}, [getPosition]);
|
|
83
95
|
const getHistoryFiles = useCallback(e => {
|
|
84
|
-
const
|
|
96
|
+
const getItemKey = editor.editorType === WIKI_EDITOR ? 'wiki-recent-files' : 'sdoc-recent-files';
|
|
97
|
+
const files = LocalStorage.getItem(getItemKey) || [];
|
|
85
98
|
setFiles(files);
|
|
86
|
-
}, []);
|
|
99
|
+
}, [editor.editorType]);
|
|
87
100
|
useEffect(() => {
|
|
88
101
|
getHistoryFiles();
|
|
89
102
|
}, [getHistoryFiles]);
|
|
@@ -168,17 +181,23 @@ const FileLinkInsertDialog = _ref => {
|
|
|
168
181
|
}, []);
|
|
169
182
|
useEffect(() => {
|
|
170
183
|
if (!(element === null || element === void 0 ? void 0 : element.children)) return;
|
|
171
|
-
const searchText = element
|
|
184
|
+
const searchText = Node.string(element);
|
|
172
185
|
onSearch(searchText);
|
|
173
186
|
}, [element, onSearch]);
|
|
174
187
|
const onSelect = useCallback(fileInfo => {
|
|
175
188
|
const {
|
|
176
189
|
doc_uuid,
|
|
177
|
-
name
|
|
190
|
+
name,
|
|
191
|
+
wikiRepoId,
|
|
192
|
+
pageId
|
|
178
193
|
} = fileInfo;
|
|
179
194
|
removeTempInput(editor, element);
|
|
180
195
|
closeDialog();
|
|
181
|
-
|
|
196
|
+
if (editor.editorType === WIKI_EDITOR) {
|
|
197
|
+
insertWikiPageLink(editor, name, wikiRepoId, pageId);
|
|
198
|
+
} else {
|
|
199
|
+
insertSdocFileLink(editor, name, doc_uuid);
|
|
200
|
+
}
|
|
182
201
|
}, [closeDialog, editor, element]);
|
|
183
202
|
const onShowMore = useCallback(() => {
|
|
184
203
|
eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
|
|
@@ -189,10 +208,17 @@ const FileLinkInsertDialog = _ref => {
|
|
|
189
208
|
}, [editor, element, eventBus]);
|
|
190
209
|
const onCreateFile = useCallback(() => {
|
|
191
210
|
const eventBus = EventBus.getInstance();
|
|
192
|
-
|
|
211
|
+
const dispatchEventKey = editor.editorType === WIKI_EDITOR ? EXTERNAL_EVENT.CREATE_WIKI_PAGE : EXTERNAL_EVENT.CREATE_SDOC_FILE;
|
|
212
|
+
eventBus.dispatch(dispatchEventKey, {
|
|
193
213
|
newFileName: newFileName.trim()
|
|
194
214
|
});
|
|
195
|
-
}, [newFileName]);
|
|
215
|
+
}, [editor.editorType, newFileName]);
|
|
216
|
+
const createFileTipDefault = useMemo(() => {
|
|
217
|
+
return editor.editorType === WIKI_EDITOR ? 'New_page' : 'Create_a_new_sdoc_file';
|
|
218
|
+
}, [editor.editorType]);
|
|
219
|
+
const createFileName = useMemo(() => {
|
|
220
|
+
return editor.editorType === WIKI_EDITOR ? newFileName : "".concat(newFileName, ".sdoc");
|
|
221
|
+
}, [editor.editorType, newFileName]);
|
|
196
222
|
return /*#__PURE__*/React.createElement("div", {
|
|
197
223
|
className: "sdoc-history-files-content popover",
|
|
198
224
|
style: _objectSpread(_objectSpread({}, position), {}, {
|
|
@@ -225,7 +251,7 @@ const FileLinkInsertDialog = _ref => {
|
|
|
225
251
|
}), /*#__PURE__*/React.createElement("span", {
|
|
226
252
|
className: "new-file-name"
|
|
227
253
|
}, newFileName ? t('Create_file_name_sdoc', {
|
|
228
|
-
file_name_sdoc:
|
|
229
|
-
}) : t(
|
|
254
|
+
file_name_sdoc: createFileName
|
|
255
|
+
}) : t(createFileTipDefault))));
|
|
230
256
|
};
|
|
231
257
|
export default FileLinkInsertDialog;
|
|
@@ -18,6 +18,8 @@ const InsertElementDialog = _ref => {
|
|
|
18
18
|
const [slateNode, setSlateNode] = useState(null);
|
|
19
19
|
const [insertLinkCallback, setInsertLinkCallback] = useState(null);
|
|
20
20
|
const [validEditor, setValidEditor] = useState(editor);
|
|
21
|
+
const [linkTitle, setLinkTitle] = useState('');
|
|
22
|
+
const [handleSubmit, setHandleSubmit] = useState(() => void 0);
|
|
21
23
|
const uploadLocalImageInputRef = useRef();
|
|
22
24
|
const onFileChanged = useCallback(event => {
|
|
23
25
|
const files = event.target.files;
|
|
@@ -45,7 +47,10 @@ const InsertElementDialog = _ref => {
|
|
|
45
47
|
slateNode,
|
|
46
48
|
insertFileLinkCallback,
|
|
47
49
|
insertSdocFileLinkCallback,
|
|
48
|
-
editor: paramEditor
|
|
50
|
+
editor: paramEditor,
|
|
51
|
+
linkTitle,
|
|
52
|
+
// link shortcut wrapping link
|
|
53
|
+
handleSubmit
|
|
49
54
|
} = _ref2;
|
|
50
55
|
setInsertPosition(insertPosition);
|
|
51
56
|
setSlateNode(slateNode);
|
|
@@ -55,6 +60,8 @@ const InsertElementDialog = _ref => {
|
|
|
55
60
|
insertSdocFileLinkCallback,
|
|
56
61
|
insertFileLinkCallback
|
|
57
62
|
});
|
|
63
|
+
setLinkTitle(linkTitle);
|
|
64
|
+
setHandleSubmit(handleSubmit);
|
|
58
65
|
// Apply for comment editor, as it has a different editor instance
|
|
59
66
|
setValidEditor(paramEditor || editor);
|
|
60
67
|
if (type === LOCAL_IMAGE) {
|
|
@@ -70,13 +77,16 @@ const InsertElementDialog = _ref => {
|
|
|
70
77
|
setDialogType('');
|
|
71
78
|
setInsertLinkCallback(null);
|
|
72
79
|
setValidEditor(null);
|
|
80
|
+
setLinkTitle('');
|
|
73
81
|
}, []);
|
|
74
82
|
const props = {
|
|
75
83
|
insertPosition,
|
|
76
84
|
slateNode,
|
|
77
85
|
editor: validEditor,
|
|
78
86
|
element,
|
|
79
|
-
closeDialog
|
|
87
|
+
closeDialog,
|
|
88
|
+
linkTitle,
|
|
89
|
+
handleSubmit
|
|
80
90
|
};
|
|
81
91
|
switch (dialogType) {
|
|
82
92
|
case ELEMENT_TYPE.TABLE:
|
|
@@ -20,6 +20,7 @@ export const TABLE_ROW = 'table_row';
|
|
|
20
20
|
export const TABLE_CELL = 'table_cell';
|
|
21
21
|
export const LINK = 'link';
|
|
22
22
|
export const SDOC_LINK = 'sdoc_link';
|
|
23
|
+
export const WIKI_LINK = 'wiki_link';
|
|
23
24
|
export const FILE_LINK = 'file_link';
|
|
24
25
|
export const IMAGE = 'image';
|
|
25
26
|
export const IMAGE_BLOCK = 'image_block';
|
|
@@ -29,6 +30,7 @@ export const MENTION_TEMP = 'mention_temp';
|
|
|
29
30
|
export const FILE_LINK_INSET_INPUT_TEMP = 'file_link_insert_input_temp';
|
|
30
31
|
export const QUICK_INSERT = 'quick_insert';
|
|
31
32
|
export const COLUMN = 'column';
|
|
33
|
+
export const SEATABLE_VIEW = 'seatable_view';
|
|
32
34
|
|
|
33
35
|
// font
|
|
34
36
|
export const FONT_SIZE = 'font-size';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// extension plugin
|
|
2
2
|
import * as ELEMENT_TYPE from './element-type';
|
|
3
3
|
// eslint-disable-next-line no-duplicate-imports
|
|
4
|
-
import { BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, IMAGE_BLOCK, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES, CALL_OUT, MENTION, MENTION_TEMP, FILE_LINK_INSET_INPUT_TEMP, QUICK_INSERT } from './element-type';
|
|
4
|
+
import { BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, IMAGE_BLOCK, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES, CALL_OUT, MENTION, MENTION_TEMP, FILE_LINK_INSET_INPUT_TEMP, QUICK_INSERT, COLUMN, SEATABLE_VIEW } from './element-type';
|
|
5
5
|
export { DEFAULT_COLORS, STANDARD_COLORS, DEFAULT_RECENT_USED_LIST, DEFAULT_FONT_COLOR, RECENT_USED_HIGHLIGHT_COLORS_KEY, RECENT_USED_FONT_COLORS_KEY, RECENT_USED_TABLE_CELL_BACKGROUND_COLORS_KEY, DEFAULT_LAST_USED_FONT_COLOR, DEFAULT_LAST_USED_HIGHLIGHT_COLOR, DEFAULT_LAST_USED_TABLE_CELL_BACKGROUND_COLOR } from './color';
|
|
6
6
|
export { FONT_SIZE, DEFAULT_FONT, FONT, GOOGLE_FONT_CLASS, RECENT_USED_FONTS_KEY, SDOC_FONT_SIZE } from './font';
|
|
7
7
|
export { DIFF_TYPE, ADDED_STYLE, DELETED_STYLE } from './diff-view';
|
|
@@ -38,7 +38,7 @@ export const FILE_TYPE = {
|
|
|
38
38
|
[FILE_LINK]: 'file',
|
|
39
39
|
[SDOC_LINK]: 'sdoc'
|
|
40
40
|
};
|
|
41
|
-
export const SUPPORTED_SIDE_OPERATION_TYPE = [PARAGRAPH, SUBTITLE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, CHECK_LIST_ITEM, CODE_BLOCK, TABLE, BLOCKQUOTE, CALL_OUT, IMAGE_BLOCK];
|
|
41
|
+
export const SUPPORTED_SIDE_OPERATION_TYPE = [PARAGRAPH, SUBTITLE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, CHECK_LIST_ITEM, CODE_BLOCK, TABLE, BLOCKQUOTE, CALL_OUT, IMAGE_BLOCK, COLUMN];
|
|
42
42
|
export const MOUSE_ENTER_EVENT_DISABLED_MAP = {
|
|
43
43
|
[PARAGRAPH]: [CALL_OUT],
|
|
44
44
|
[TITLE]: [CALL_OUT],
|
|
@@ -57,4 +57,4 @@ export const MOUSE_ENTER_EVENT_DISABLED_MAP = {
|
|
|
57
57
|
[CALL_OUT]: [CALL_OUT]
|
|
58
58
|
};
|
|
59
59
|
export const ROOT_ELEMENT_TYPES = [PARAGRAPH, TITLE, SUBTITLE, CHECK_LIST_ITEM, ORDERED_LIST, UNORDERED_LIST, BLOCKQUOTE, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, CALL_OUT, TABLE, CODE_BLOCK, IMAGE_BLOCK];
|
|
60
|
-
export { ELEMENT_TYPE, BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, IMAGE_BLOCK, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES, CALL_OUT, MENTION, MENTION_TEMP, FILE_LINK_INSET_INPUT_TEMP, QUICK_INSERT };
|
|
60
|
+
export { ELEMENT_TYPE, BLOCKQUOTE, TITLE, SUBTITLE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, PARAGRAPH, ORDERED_LIST, UNORDERED_LIST, LIST_ITEM, CHECK_LIST_ITEM, CODE_BLOCK, CODE_LINE, TABLE, TABLE_CELL, TABLE_ROW, LINK, SDOC_LINK, FILE_LINK, IMAGE, IMAGE_BLOCK, TOP_LEVEL_TYPES, INLINE_LEVEL_TYPES, CALL_OUT, MENTION, MENTION_TEMP, FILE_LINK_INSET_INPUT_TEMP, QUICK_INSERT, SEATABLE_VIEW };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RECENT_USED_HIGHLIGHT_COLORS_KEY, DEFAULT_LAST_USED_HIGHLIGHT_COLOR, RECENT_USED_FONT_COLORS_KEY, DEFAULT_FONT_COLOR, DEFAULT_LAST_USED_FONT_COLOR } from './color';
|
|
2
|
-
import { BLOCKQUOTE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, ORDERED_LIST, UNORDERED_LIST, CHECK_LIST_ITEM, CODE_BLOCK, LINK, IMAGE, TABLE, SDOC_LINK, FILE_LINK, PARAGRAPH, CALL_OUT, COLUMN } from './element-type';
|
|
2
|
+
import { BLOCKQUOTE, HEADER, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, ORDERED_LIST, UNORDERED_LIST, CHECK_LIST_ITEM, CODE_BLOCK, LINK, IMAGE, TABLE, SDOC_LINK, FILE_LINK, PARAGRAPH, CALL_OUT, COLUMN, SEATABLE_VIEW } from './element-type';
|
|
3
3
|
export const UNDO = 'undo';
|
|
4
4
|
export const REDO = 'redo';
|
|
5
5
|
export const CLEAR_FORMAT = 'clear_format';
|
|
@@ -195,7 +195,13 @@ export const MENUS_CONFIG_MAP = {
|
|
|
195
195
|
[COLUMN]: {
|
|
196
196
|
id: "sdoc".concat(COLUMN),
|
|
197
197
|
iconClass: 'sdocfont sdoc-choose-column',
|
|
198
|
-
text: '
|
|
198
|
+
text: 'SeaTable_column'
|
|
199
|
+
},
|
|
200
|
+
[SEATABLE_VIEW]: {
|
|
201
|
+
id: SEATABLE_VIEW,
|
|
202
|
+
iconClass: 'sdocfont sdoc-header4',
|
|
203
|
+
type: SEATABLE_VIEW,
|
|
204
|
+
text: 'SeaTable_view'
|
|
199
205
|
}
|
|
200
206
|
};
|
|
201
207
|
|
|
@@ -18,9 +18,11 @@ import CalloutPlugin from './callout';
|
|
|
18
18
|
import SearchReplacePlugin from './search-replace';
|
|
19
19
|
import MentionPlugin from './mention';
|
|
20
20
|
import QuickInsertPlugin from './quick-insert';
|
|
21
|
-
import
|
|
21
|
+
import WikiLinkPlugin from './wiki-link';
|
|
22
|
+
import SeaTableColumnPlugin from './seatable-column';
|
|
23
|
+
import SeaTableViewsPlugin from './seatable-views';
|
|
22
24
|
const Plugins = [MarkDownPlugin, HtmlPlugin, HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, TextPlugin, TextAlignPlugin, FontPlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin, SearchReplacePlugin];
|
|
23
|
-
const WikiPlugins = [
|
|
25
|
+
const WikiPlugins = [...Plugins, QuickInsertPlugin, WikiLinkPlugin];
|
|
24
26
|
const CommentPlugins = [MarkDownPlugin, HtmlPlugin, ParagraphPlugin, TextPlugin, ListPlugin, ImagePlugin, LinkPlugin, MentionPlugin, BlockquotePlugin];
|
|
25
27
|
export default Plugins;
|
|
26
|
-
export { MarkDownPlugin, HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, TextPlugin, HtmlPlugin, TextAlignPlugin, FontPlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin, SearchReplacePlugin, MentionPlugin, QuickInsertPlugin, CommentPlugins, WikiPlugins,
|
|
28
|
+
export { MarkDownPlugin, HeaderPlugin, LinkPlugin, BlockquotePlugin, ListPlugin, CheckListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, TextPlugin, HtmlPlugin, TextAlignPlugin, FontPlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin, CalloutPlugin, SearchReplacePlugin, MentionPlugin, QuickInsertPlugin, CommentPlugins, WikiPlugins, WikiLinkPlugin, SeaTableColumnPlugin, SeaTableViewsPlugin };
|
|
@@ -10,7 +10,9 @@ const AddLinkDialog = _ref => {
|
|
|
10
10
|
element,
|
|
11
11
|
insertPosition,
|
|
12
12
|
slateNode,
|
|
13
|
-
closeDialog
|
|
13
|
+
closeDialog,
|
|
14
|
+
linkTitle,
|
|
15
|
+
handleSubmit
|
|
14
16
|
} = _ref;
|
|
15
17
|
const {
|
|
16
18
|
t
|
|
@@ -21,7 +23,7 @@ const AddLinkDialog = _ref => {
|
|
|
21
23
|
title: oldTitle,
|
|
22
24
|
href: oldURL
|
|
23
25
|
} = element || {
|
|
24
|
-
title: '',
|
|
26
|
+
title: linkTitle || '',
|
|
25
27
|
href: ''
|
|
26
28
|
};
|
|
27
29
|
const initTitle = useMemo(() => oldTitle ? oldTitle : getEditorString(editor, editor.selection), [editor, oldTitle]);
|
|
@@ -48,6 +50,7 @@ const AddLinkDialog = _ref => {
|
|
|
48
50
|
} else {
|
|
49
51
|
insertLink(editor, title, url, insertPosition, slateNode);
|
|
50
52
|
}
|
|
53
|
+
handleSubmit && handleSubmit();
|
|
51
54
|
closeDialog();
|
|
52
55
|
|
|
53
56
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Transforms, Node, Editor, Range, Element } from '@seafile/slate';
|
|
1
|
+
import { Transforms, Node, Editor, Range, Element, Text } from '@seafile/slate';
|
|
2
2
|
import isUrl from 'is-url';
|
|
3
3
|
import isHotkey from 'is-hotkey';
|
|
4
4
|
import context from '../../../../context';
|
|
5
5
|
import { insertSdocFileLink } from '../sdoc-link/helpers';
|
|
6
6
|
import { genLinkNode, isSdocFile } from './helpers';
|
|
7
|
-
import { getNodeType, getSelectedNodeByType } from '../../core';
|
|
7
|
+
import { getNodeType, getSelectedElems, getSelectedNodeByType } from '../../core';
|
|
8
8
|
import { isImage, isSameDomain } from '../../utils';
|
|
9
9
|
import { ELEMENT_TYPE, LINK, ORDERED_LIST, UNORDERED_LIST } from '../../constants';
|
|
10
10
|
import EventBus from '../../../utils/event-bus';
|
|
@@ -68,18 +68,33 @@ const withLink = editor => {
|
|
|
68
68
|
return insertFragment(data);
|
|
69
69
|
};
|
|
70
70
|
newEditor.onHotKeyDown = e => {
|
|
71
|
-
|
|
72
|
-
selection
|
|
73
|
-
} = newEditor;
|
|
74
|
-
const isCollapsed = Range.isCollapsed(selection);
|
|
75
|
-
if (isHotkey('mod+k', e) && isCollapsed) {
|
|
71
|
+
if (isHotkey('mod+k', e)) {
|
|
76
72
|
// Prevent edge behavior
|
|
77
73
|
e.preventDefault();
|
|
74
|
+
const {
|
|
75
|
+
selection
|
|
76
|
+
} = newEditor;
|
|
77
|
+
const isCollapsed = Range.isCollapsed(selection);
|
|
78
78
|
const eventBus = EventBus.getInstance();
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
if (isCollapsed) {
|
|
80
|
+
eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
|
|
81
|
+
type: ELEMENT_TYPE.LINK,
|
|
82
|
+
editor
|
|
83
|
+
});
|
|
84
|
+
} else {
|
|
85
|
+
const [firstSelectedNode, ...restNodes] = getSelectedElems(newEditor);
|
|
86
|
+
if (!firstSelectedNode || restNodes) return; // If select more than one node or not select any node, return
|
|
87
|
+
const isSelectTextNodes = firstSelectedNode.children.some(node => Text.isText(node));
|
|
88
|
+
if (!isSelectTextNodes) return;
|
|
89
|
+
const selectContent = window.getSelection().toString();
|
|
90
|
+
const replaceLinkNode = () => Editor.deleteBackward(editor, selection);
|
|
91
|
+
eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
|
|
92
|
+
type: ELEMENT_TYPE.LINK,
|
|
93
|
+
editor: newEditor,
|
|
94
|
+
linkTitle: selectContent,
|
|
95
|
+
handleSubmit: replaceLinkNode
|
|
96
|
+
});
|
|
97
|
+
}
|
|
83
98
|
}
|
|
84
99
|
return onHotKeyDown && onHotKeyDown(e);
|
|
85
100
|
};
|
|
@@ -6,7 +6,7 @@ import classnames from 'classnames';
|
|
|
6
6
|
import { SDOC_LINK_TYPE_CONFIG, SDOC_LINK_TYPE, SDOC_LINK_TYPES } from '../constants';
|
|
7
7
|
import { ElementPopover } from '../../../commons';
|
|
8
8
|
import toaster from '../../../../../components/toast';
|
|
9
|
-
import {
|
|
9
|
+
import { onCopySdocLinkNode } from '../helpers';
|
|
10
10
|
import './index.css';
|
|
11
11
|
const SdocLinkHoverMenu = _ref => {
|
|
12
12
|
let {
|
|
@@ -15,7 +15,8 @@ const SdocLinkHoverMenu = _ref => {
|
|
|
15
15
|
element,
|
|
16
16
|
onUnwrapFileLinkNode,
|
|
17
17
|
onHideInsertHoverMenu,
|
|
18
|
-
t
|
|
18
|
+
t,
|
|
19
|
+
url
|
|
19
20
|
} = _ref;
|
|
20
21
|
const readOnly = useReadOnly();
|
|
21
22
|
const [isShowDisplayStylePopover, setIsShowDisplayStylePopover] = useState(false);
|
|
@@ -60,7 +61,7 @@ const SdocLinkHoverMenu = _ref => {
|
|
|
60
61
|
'ml-0': readOnly
|
|
61
62
|
})
|
|
62
63
|
}, /*#__PURE__*/React.createElement("a", {
|
|
63
|
-
href:
|
|
64
|
+
href: url,
|
|
64
65
|
target: "_blank",
|
|
65
66
|
rel: "noopener noreferrer",
|
|
66
67
|
className: "link-op-menu-link"
|
|
@@ -3,6 +3,7 @@ import { ReactEditor } from '@seafile/slate-react';
|
|
|
3
3
|
import { FILE_LINK_INSET_INPUT_TEMP, SDOC_LINK } from '../../constants';
|
|
4
4
|
import { getFileSearchInputEntry, insertTempInput, isTriggeredByShortcut } from './helpers';
|
|
5
5
|
import { getSelectedElems } from '../../core';
|
|
6
|
+
import { WIKI_LINK } from '../../constants/element-type';
|
|
6
7
|
const withSdocLink = editor => {
|
|
7
8
|
const {
|
|
8
9
|
isInline,
|
|
@@ -17,7 +18,7 @@ const withSdocLink = editor => {
|
|
|
17
18
|
const {
|
|
18
19
|
type
|
|
19
20
|
} = elem;
|
|
20
|
-
const isInlineElem = [SDOC_LINK, FILE_LINK_INSET_INPUT_TEMP].includes(type);
|
|
21
|
+
const isInlineElem = [WIKI_LINK, SDOC_LINK, FILE_LINK_INSET_INPUT_TEMP].includes(type);
|
|
21
22
|
if (isInlineElem) return true;
|
|
22
23
|
return isInline(elem);
|
|
23
24
|
};
|
|
@@ -43,7 +44,7 @@ const withSdocLink = editor => {
|
|
|
43
44
|
const beforePath = nodeEntry[1];
|
|
44
45
|
beforePath.splice(-1, 1, Math.max(nodeEntry[1].at(-1) - 1, 0));
|
|
45
46
|
const beforeNodeEntry = Editor.node(newEditor, beforePath);
|
|
46
|
-
if (beforeNodeEntry && [SDOC_LINK, FILE_LINK_INSET_INPUT_TEMP].includes(beforeNodeEntry[0].type)) {
|
|
47
|
+
if (beforeNodeEntry && [WIKI_LINK, SDOC_LINK, FILE_LINK_INSET_INPUT_TEMP].includes(beforeNodeEntry[0].type)) {
|
|
47
48
|
Transforms.delete(newEditor, {
|
|
48
49
|
at: beforeNodeEntry[1]
|
|
49
50
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
-
import React, { useCallback, useEffect, useState, useRef } from 'react';
|
|
2
|
+
import React, { useCallback, useEffect, useState, useRef, useMemo } from 'react';
|
|
3
3
|
import { Editor, Range } from '@seafile/slate';
|
|
4
4
|
import { ReactEditor, useReadOnly } from '@seafile/slate-react';
|
|
5
5
|
import { useScrollContext } from '../../../../hooks/use-scroll-context';
|
|
@@ -8,6 +8,8 @@ import HoverMenu from '../hover-menu';
|
|
|
8
8
|
import { DELETED_STYLE, ADDED_STYLE } from '../../../constants';
|
|
9
9
|
import { SDOC_LINK_TYPE } from '../constants';
|
|
10
10
|
import { focusEditor } from '../../../core';
|
|
11
|
+
import { WIKI_LINK } from '../../../constants/element-type';
|
|
12
|
+
import { getWikiUrl } from '../../wiki-link/helpers';
|
|
11
13
|
import './render-elem.css';
|
|
12
14
|
const SdocFileLink = _ref => {
|
|
13
15
|
let {
|
|
@@ -106,6 +108,9 @@ const SdocFileLink = _ref => {
|
|
|
106
108
|
if (style.computed_background_color) {
|
|
107
109
|
style['backgroundColor'] = style.computed_background_color;
|
|
108
110
|
}
|
|
111
|
+
const url = useMemo(() => {
|
|
112
|
+
return element.type === WIKI_LINK ? getWikiUrl(element.wiki_repo_id, element.page_id) : getUrl(element.doc_uuid);
|
|
113
|
+
}, [element.doc_uuid, element.page_id, element.type, element.wiki_repo_id]);
|
|
109
114
|
return /*#__PURE__*/React.createElement("span", Object.assign({}, attributes, {
|
|
110
115
|
"data-id": element.id,
|
|
111
116
|
contentEditable: false,
|
|
@@ -123,12 +128,13 @@ const SdocFileLink = _ref => {
|
|
|
123
128
|
className: 'sdoc-file-text-link',
|
|
124
129
|
style: style
|
|
125
130
|
}, /*#__PURE__*/React.createElement("a", {
|
|
126
|
-
href:
|
|
131
|
+
href: url,
|
|
127
132
|
onClick: e => {
|
|
128
133
|
e.preventDefault();
|
|
129
134
|
},
|
|
130
135
|
title: element.title
|
|
131
136
|
}, children))), isShowInsertHoverMenu && !readOnly && editor.selection && Range.isCollapsed(editor.selection) && /*#__PURE__*/React.createElement(HoverMenu, {
|
|
137
|
+
url: url,
|
|
132
138
|
editor: editor,
|
|
133
139
|
menuPosition: menuPosition,
|
|
134
140
|
element: element,
|
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
-
import { Editor, Transforms } from '@seafile/slate';
|
|
2
|
+
import { Editor, Transforms, Range } from '@seafile/slate';
|
|
3
3
|
import slugid from 'slugid';
|
|
4
4
|
import { BLOCKQUOTE, CHECK_LIST_ITEM, COLUMN, IMAGE, ORDERED_LIST, PARAGRAPH, TABLE_CELL, UNORDERED_LIST } from '../../constants/element-type';
|
|
5
5
|
import { focusEditor, getNodeType } from '../../core';
|
|
6
6
|
import Column from './model';
|
|
7
|
+
import * as CellType from './constants/cell-types';
|
|
7
8
|
export const isMenuDisabled = (editor, readonly) => {
|
|
8
9
|
if (readonly) return true;
|
|
9
|
-
|
|
10
|
+
const {
|
|
11
|
+
selection
|
|
12
|
+
} = editor;
|
|
13
|
+
if (selection == null) return true;
|
|
14
|
+
if (!Range.isCollapsed(selection)) return true;
|
|
10
15
|
const [nodeEntry] = Editor.nodes(editor, {
|
|
11
16
|
match: n => {
|
|
12
17
|
const type = getNodeType(n);
|
|
13
18
|
|
|
14
19
|
// Only available for p and blockquote
|
|
15
|
-
if (type ===
|
|
16
|
-
if (type ===
|
|
20
|
+
if (type === BLOCKQUOTE) return false;
|
|
21
|
+
if (type === PARAGRAPH) return false;
|
|
17
22
|
if (type === UNORDERED_LIST) return true;
|
|
18
23
|
if (type === ORDERED_LIST) return true;
|
|
19
24
|
if (type === CHECK_LIST_ITEM) return true;
|
|
20
25
|
if (type === IMAGE) return true;
|
|
21
26
|
if (type === TABLE_CELL) return true;
|
|
27
|
+
if (Editor.isVoid(editor, n)) return true;
|
|
22
28
|
return false;
|
|
23
29
|
},
|
|
24
30
|
universal: true,
|
|
@@ -27,9 +33,9 @@ export const isMenuDisabled = (editor, readonly) => {
|
|
|
27
33
|
|
|
28
34
|
// Match to p blockquote, do not disable
|
|
29
35
|
if (nodeEntry) {
|
|
30
|
-
return
|
|
36
|
+
return true;
|
|
31
37
|
}
|
|
32
|
-
return
|
|
38
|
+
return false;
|
|
33
39
|
};
|
|
34
40
|
export const getColumnType = editor => {
|
|
35
41
|
const [match] = Editor.nodes(editor, {
|
|
@@ -40,9 +46,9 @@ export const getColumnType = editor => {
|
|
|
40
46
|
const [n] = match;
|
|
41
47
|
return getNodeType(n);
|
|
42
48
|
};
|
|
43
|
-
export const insertSeaTableColumn = (editor, active) => {
|
|
49
|
+
export const insertSeaTableColumn = (editor, active, option) => {
|
|
44
50
|
if (!active) {
|
|
45
|
-
const column = new Column(
|
|
51
|
+
const column = new Column(option);
|
|
46
52
|
column.id = slugid.nice();
|
|
47
53
|
Transforms.insertNodes(editor, _objectSpread({}, column));
|
|
48
54
|
}
|
|
@@ -59,4 +65,49 @@ export const setSeaTableColumn = (editor, data) => {
|
|
|
59
65
|
export const getColumnByKey = (columns, key) => {
|
|
60
66
|
const column = columns.find(item => item.key === key);
|
|
61
67
|
return column || null;
|
|
68
|
+
};
|
|
69
|
+
export const getColumnWidth = column => {
|
|
70
|
+
let {
|
|
71
|
+
type,
|
|
72
|
+
data
|
|
73
|
+
} = column;
|
|
74
|
+
switch (type) {
|
|
75
|
+
case CellType.DATE:
|
|
76
|
+
{
|
|
77
|
+
let isShowHourAndMinute = data && data.format && data.format.indexOf('HH:mm') > -1;
|
|
78
|
+
return isShowHourAndMinute ? 160 : 100;
|
|
79
|
+
}
|
|
80
|
+
case CellType.CTIME:
|
|
81
|
+
case CellType.MTIME:
|
|
82
|
+
case CellType.LINK:
|
|
83
|
+
case CellType.GEOLOCATION:
|
|
84
|
+
{
|
|
85
|
+
return 160;
|
|
86
|
+
}
|
|
87
|
+
case CellType.COLLABORATOR:
|
|
88
|
+
{
|
|
89
|
+
return 100;
|
|
90
|
+
}
|
|
91
|
+
case CellType.CHECKBOX:
|
|
92
|
+
{
|
|
93
|
+
return 40;
|
|
94
|
+
}
|
|
95
|
+
case CellType.NUMBER:
|
|
96
|
+
case CellType.AUTO_NUMBER:
|
|
97
|
+
{
|
|
98
|
+
return 120;
|
|
99
|
+
}
|
|
100
|
+
case CellType.RATE:
|
|
101
|
+
{
|
|
102
|
+
const {
|
|
103
|
+
rate_max_number
|
|
104
|
+
} = data || {};
|
|
105
|
+
const rateMaxNumber = rate_max_number || 5;
|
|
106
|
+
return 16 * rateMaxNumber + 20;
|
|
107
|
+
}
|
|
108
|
+
default:
|
|
109
|
+
{
|
|
110
|
+
return 100;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
62
113
|
};
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { COLUMN } from '../../constants/element-type';
|
|
2
|
-
import ColumnMenu from './menu';
|
|
3
2
|
import withColumn from './plugin';
|
|
4
3
|
import renderColumn from './render-elem';
|
|
5
|
-
const
|
|
4
|
+
const SeaTableColumnPlugin = {
|
|
6
5
|
type: COLUMN,
|
|
7
6
|
nodeType: 'element',
|
|
8
|
-
editorMenus: [ColumnMenu],
|
|
9
7
|
editorPlugin: withColumn,
|
|
10
8
|
renderElements: [renderColumn]
|
|
11
9
|
};
|
|
12
|
-
export default
|
|
10
|
+
export default SeaTableColumnPlugin;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
.column-list-menu {
|
|
2
|
+
position: absolute;
|
|
3
|
+
left: -8px;
|
|
4
|
+
background-color: #fff;
|
|
5
|
+
min-width: 12rem;
|
|
6
|
+
width: 200px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.column-list-menu .column-list-menu-item-container {
|
|
10
|
+
padding: 3px 12px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.column-list-menu .column-list-menu-item-container .column-list-menu-item {
|
|
14
|
+
height: fit-content;
|
|
15
|
+
width: 100%;
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.column-list-menu .column-list-menu-item-container .column-list-menu-item .control-icon {
|
|
21
|
+
margin-right: 10px;
|
|
22
|
+
flex-shrink: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.column-list-menu .column-list-menu-item-container .column-list-menu-item .control-label {
|
|
26
|
+
white-space: nowrap;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
text-overflow: ellipsis;
|
|
29
|
+
flex-grow: 1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.column-list-menu .column-list-menu-item-container:hover {
|
|
33
|
+
background-color: #f5f5f5;
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React, { useMemo, useCallback } from 'react';
|
|
2
|
+
import { COLUMNS_ICON_CONFIG } from '../constants/column';
|
|
3
|
+
import { insertSeaTableColumn, getColumnType } from '../helpers';
|
|
4
|
+
import { COLUMN } from '../../../constants/element-type';
|
|
5
|
+
import './column-list-menu.css';
|
|
6
|
+
const NOT_SUPPORT_COLUMN_TYPES = ['button', 'file'];
|
|
7
|
+
export default function ColumnListMenu(_ref) {
|
|
8
|
+
let {
|
|
9
|
+
editor
|
|
10
|
+
} = _ref;
|
|
11
|
+
const columns = useMemo(() => {
|
|
12
|
+
if (!editor.columns) return [];
|
|
13
|
+
return editor.columns.filter(column => !NOT_SUPPORT_COLUMN_TYPES.includes(column.type));
|
|
14
|
+
}, [editor.columns]);
|
|
15
|
+
const options = useMemo(() => {
|
|
16
|
+
return columns.map(item => {
|
|
17
|
+
const iconClass = COLUMNS_ICON_CONFIG[item.type];
|
|
18
|
+
return {
|
|
19
|
+
value: item.key,
|
|
20
|
+
label: item.name,
|
|
21
|
+
iconClass
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
}, [columns]);
|
|
25
|
+
const isActive = editor => {
|
|
26
|
+
return getColumnType(editor) === COLUMN;
|
|
27
|
+
};
|
|
28
|
+
const onMousedown = useCallback(option => {
|
|
29
|
+
const active = isActive(editor);
|
|
30
|
+
insertSeaTableColumn(editor, active, option);
|
|
31
|
+
}, [editor]);
|
|
32
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
33
|
+
className: "column-list-menu"
|
|
34
|
+
}, options.map(option => {
|
|
35
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
36
|
+
key: option.value,
|
|
37
|
+
className: "column-list-menu-item-container",
|
|
38
|
+
onClick: () => onMousedown(option)
|
|
39
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
40
|
+
className: "column-list-menu-item"
|
|
41
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
42
|
+
className: "control-icon ".concat(option.iconClass)
|
|
43
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
44
|
+
className: "control-label"
|
|
45
|
+
}, option.label)));
|
|
46
|
+
}));
|
|
47
|
+
}
|