@seafile/sdoc-editor 0.4.16 → 0.4.18
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/comment/components/comment-input/helpers.js +15 -0
- package/dist/basic-sdk/comment/components/comment-input/index.js +11 -4
- package/dist/basic-sdk/editor/revision-editor.js +1 -0
- package/dist/basic-sdk/editor/sdoc-editor.js +1 -0
- package/dist/basic-sdk/extension/commons/history-files/index.css +65 -0
- package/dist/basic-sdk/extension/commons/history-files/index.js +156 -0
- package/dist/basic-sdk/extension/commons/insert-element-dialog/index.js +9 -1
- package/dist/basic-sdk/extension/commons/select-file-dialog/index.css +2 -37
- package/dist/basic-sdk/extension/commons/select-file-dialog/index.js +1 -9
- package/dist/basic-sdk/extension/commons/select-file-dialog/local-files/index.css +7 -13
- package/dist/basic-sdk/extension/plugins/sdoc-link/helpers.js +3 -5
- package/dist/basic-sdk/extension/plugins/sdoc-link/plugin.js +2 -1
- package/dist/basic-sdk/extension/toolbar/side-toolbar/helpers.js +3 -3
- package/dist/constants/index.js +2 -1
- package/package.json +1 -1
- package/public/locales/en/sdoc-editor.json +5 -1
- package/public/locales/zh_CN/sdoc-editor.json +5 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import context from '../../../../context';
|
|
2
|
+
|
|
3
|
+
// Sort collaborators by participants, move mentioned members to the top
|
|
4
|
+
export const sortCollaborators = function (collaborators) {
|
|
5
|
+
let participants = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
6
|
+
const loginEmail = context.getUserInfo().email;
|
|
7
|
+
const participantsMap = {};
|
|
8
|
+
participants.forEach(item => {
|
|
9
|
+
if (item.email === loginEmail) return;
|
|
10
|
+
participantsMap[item.email] = item;
|
|
11
|
+
});
|
|
12
|
+
const newCollaborators = collaborators.filter(item => !participantsMap[item.email] && item.email !== loginEmail);
|
|
13
|
+
const newParticipants = Object.values(participantsMap);
|
|
14
|
+
return [...newParticipants, ...newCollaborators];
|
|
15
|
+
};
|
|
@@ -9,6 +9,7 @@ import { DOWN, UP, POPOVER_ADDING_HEIGHT, FONT_SIZE_WIDTH, LINE_HEIGHT } from '.
|
|
|
9
9
|
import { eventStopPropagation } from '../../../utils/mouse-event';
|
|
10
10
|
import CommentParticipantItem from './comment-participant-item';
|
|
11
11
|
import { Hotkey, getSelectionCoords } from '../../../../utils';
|
|
12
|
+
import { sortCollaborators } from './helpers';
|
|
12
13
|
import './index.css';
|
|
13
14
|
const CommentInput = forwardRef((_ref, ref) => {
|
|
14
15
|
let {
|
|
@@ -27,11 +28,13 @@ const CommentInput = forwardRef((_ref, ref) => {
|
|
|
27
28
|
collaborators
|
|
28
29
|
} = useCollaborators();
|
|
29
30
|
const {
|
|
30
|
-
addParticipants
|
|
31
|
+
addParticipants,
|
|
32
|
+
participants
|
|
31
33
|
} = useParticipantsContext();
|
|
32
34
|
const [range, setRange] = useState();
|
|
33
35
|
const [searchedCollaborators, setSearchedCollaborators] = useState([]);
|
|
34
36
|
const [activeCollaboratorIndex, setActiveCollaboratorIndex] = useState(-1);
|
|
37
|
+
const [validCollaborators, setValidCollaborators] = useState([]);
|
|
35
38
|
const commentUtilities = new CommentUtilities();
|
|
36
39
|
|
|
37
40
|
// onMount: comment content
|
|
@@ -40,6 +43,10 @@ const CommentInput = forwardRef((_ref, ref) => {
|
|
|
40
43
|
commentRef.current.textContent = content;
|
|
41
44
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
42
45
|
}, []);
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const sortedCollaborators = sortCollaborators(collaborators, participants);
|
|
48
|
+
setValidCollaborators(sortedCollaborators);
|
|
49
|
+
}, [collaborators, participants]);
|
|
43
50
|
|
|
44
51
|
// onMount: set input focus
|
|
45
52
|
useEffect(() => {
|
|
@@ -147,11 +154,11 @@ const CommentInput = forwardRef((_ref, ref) => {
|
|
|
147
154
|
anchorOffset
|
|
148
155
|
} = _ref2;
|
|
149
156
|
if (atIndex !== 0 && text[atIndex - 1] !== ' ') return [];
|
|
150
|
-
if (atIndex === anchorOffset - 1) return
|
|
157
|
+
if (atIndex === anchorOffset - 1) return validCollaborators;
|
|
151
158
|
const searchingText = text.substring(atIndex + 1);
|
|
152
|
-
if (searchingText) return searchCollaborators(
|
|
159
|
+
if (searchingText) return searchCollaborators(validCollaborators, searchingText);
|
|
153
160
|
return [];
|
|
154
|
-
}, [
|
|
161
|
+
}, [validCollaborators]);
|
|
155
162
|
const handleInvolvedKeyUp = useCallback(event => {
|
|
156
163
|
// atIndex: Positional index of @
|
|
157
164
|
const {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
.sdoc-history-files-wrapper {
|
|
2
|
+
position: absolute;
|
|
3
|
+
z-index: 101;
|
|
4
|
+
width: 400px;
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.sdoc-history-files-wrapper .sdoc-history-files-search-input {
|
|
9
|
+
border: 0;
|
|
10
|
+
outline: none;
|
|
11
|
+
margin-top: -21px;
|
|
12
|
+
position: absolute;
|
|
13
|
+
background-color: transparent;
|
|
14
|
+
padding: 0px;
|
|
15
|
+
color: #212529;
|
|
16
|
+
font-size: 14px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files-header {
|
|
20
|
+
color: #999999;
|
|
21
|
+
font-size: 14px;
|
|
22
|
+
margin-top: 8px;
|
|
23
|
+
height: 32px;
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
padding: 0px 16px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files {
|
|
30
|
+
max-height: 306px;
|
|
31
|
+
overflow-y: scroll;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files .sdoc-history-files-item {
|
|
35
|
+
font-size: 14px;
|
|
36
|
+
line-height: 32px;
|
|
37
|
+
height: 32px;
|
|
38
|
+
padding: 0px 16px;
|
|
39
|
+
overflow:hidden;
|
|
40
|
+
text-overflow:ellipsis;
|
|
41
|
+
white-space:nowrap;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files .sdoc-history-files-item :first-child {
|
|
45
|
+
font-size: 12px;
|
|
46
|
+
margin-right: 5px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files .sdoc-history-files-item:hover {
|
|
50
|
+
background-color: #f5f5f5;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files-add {
|
|
54
|
+
height: 32px;
|
|
55
|
+
padding: 0px 16px;
|
|
56
|
+
border-top: 1px solid #e9ecef;
|
|
57
|
+
font-size: 14px;
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.sdoc-history-files-wrapper .sdoc-history-files-content .sdoc-history-files-add :first-child {
|
|
63
|
+
color: #444444;
|
|
64
|
+
margin-right: 10px;
|
|
65
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import React, { useCallback, useEffect, useState, useRef } from 'react';
|
|
3
|
+
import { Editor } from '@seafile/slate';
|
|
4
|
+
import { ReactEditor } from '@seafile/slate-react';
|
|
5
|
+
import { withTranslation } from 'react-i18next';
|
|
6
|
+
import EventBus from '../../../utils/event-bus';
|
|
7
|
+
import { insertSdocFileLink } from '../../plugins/sdoc-link/helpers';
|
|
8
|
+
import { LocalStorage } from '../../../../utils';
|
|
9
|
+
import { INTERNAL_EVENT } from '../../../constants';
|
|
10
|
+
import { EXTERNAL_EVENT } from '../../../../constants';
|
|
11
|
+
import { SDOC_LINK } from '../../constants';
|
|
12
|
+
import './index.css';
|
|
13
|
+
const HistoryFiles = _ref => {
|
|
14
|
+
let {
|
|
15
|
+
editor,
|
|
16
|
+
insertLinkCallback,
|
|
17
|
+
closeDialog,
|
|
18
|
+
t
|
|
19
|
+
} = _ref;
|
|
20
|
+
const historyFilesRef = useRef();
|
|
21
|
+
const historyFilesInputRef = useRef();
|
|
22
|
+
const [files, setFiles] = useState([]);
|
|
23
|
+
const [position, setPosition] = useState({});
|
|
24
|
+
const [header, setHeader] = useState(t('Recent_previews'));
|
|
25
|
+
const [newFileName, setNewFileName] = useState('');
|
|
26
|
+
const getPosition = useCallback(() => {
|
|
27
|
+
const {
|
|
28
|
+
selection
|
|
29
|
+
} = editor;
|
|
30
|
+
const nodeEntry = Editor.node(editor, selection);
|
|
31
|
+
const domNode = ReactEditor.toDOMNode(editor, nodeEntry[0]);
|
|
32
|
+
if (domNode) {
|
|
33
|
+
const {
|
|
34
|
+
top,
|
|
35
|
+
right
|
|
36
|
+
} = domNode.getBoundingClientRect();
|
|
37
|
+
setPosition({
|
|
38
|
+
left: right + 5,
|
|
39
|
+
top: top + 20
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
43
|
+
}, []);
|
|
44
|
+
const onClick = useCallback(e => {
|
|
45
|
+
if (historyFilesRef.current.contains(e.target)) return;
|
|
46
|
+
closeDialog();
|
|
47
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
48
|
+
}, []);
|
|
49
|
+
const onScroll = useCallback(e => {
|
|
50
|
+
getPosition();
|
|
51
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
|
+
}, []);
|
|
53
|
+
const getHistoryFiles = useCallback(e => {
|
|
54
|
+
const files = LocalStorage.getItem('sdoc-recent-files') || [];
|
|
55
|
+
setFiles(files);
|
|
56
|
+
}, []);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
getPosition();
|
|
59
|
+
getHistoryFiles();
|
|
60
|
+
setTimeout(() => {
|
|
61
|
+
historyFilesInputRef.current.focus();
|
|
62
|
+
}, 0);
|
|
63
|
+
const sdocScrollContainer = document.getElementById('sdoc-scroll-container');
|
|
64
|
+
sdocScrollContainer.addEventListener('scroll', onScroll);
|
|
65
|
+
document.addEventListener('click', onClick);
|
|
66
|
+
return () => {
|
|
67
|
+
sdocScrollContainer.removeEventListener('scroll', onScroll);
|
|
68
|
+
document.removeEventListener('click', onClick);
|
|
69
|
+
};
|
|
70
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
|
+
}, []);
|
|
72
|
+
const onSearch = useCallback(e => {
|
|
73
|
+
let newFiles = LocalStorage.getItem('sdoc-recent-files') || [];
|
|
74
|
+
if (e.target.value) {
|
|
75
|
+
newFiles = newFiles.filter(item => item.file_name.includes(e.target.value));
|
|
76
|
+
if (newFiles.length === 0) {
|
|
77
|
+
setHeader(t('The_document_does_not_exist'));
|
|
78
|
+
setNewFileName(e.target.value);
|
|
79
|
+
} else {
|
|
80
|
+
setHeader(t('Recent_previews'));
|
|
81
|
+
setNewFileName('');
|
|
82
|
+
}
|
|
83
|
+
setFiles(newFiles);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
setHeader(t('Recent_previews'));
|
|
87
|
+
setNewFileName('');
|
|
88
|
+
setFiles(newFiles);
|
|
89
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
90
|
+
}, []);
|
|
91
|
+
const onSelect = useCallback(fileInfo => {
|
|
92
|
+
const {
|
|
93
|
+
file_uuid,
|
|
94
|
+
file_name
|
|
95
|
+
} = fileInfo;
|
|
96
|
+
const {
|
|
97
|
+
insertSdocFileLinkCallback
|
|
98
|
+
} = insertLinkCallback;
|
|
99
|
+
insertSdocFileLinkCallback(editor, file_name, file_uuid);
|
|
100
|
+
closeDialog();
|
|
101
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
102
|
+
}, []);
|
|
103
|
+
const onShowMore = useCallback(() => {
|
|
104
|
+
const eventBus = EventBus.getInstance();
|
|
105
|
+
eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
|
|
106
|
+
type: SDOC_LINK,
|
|
107
|
+
insertSdocFileLinkCallback: insertSdocFileLink
|
|
108
|
+
});
|
|
109
|
+
}, []);
|
|
110
|
+
const onCreateFile = useCallback(() => {
|
|
111
|
+
const eventBus = EventBus.getInstance();
|
|
112
|
+
eventBus.dispatch(EXTERNAL_EVENT.CREATE_SDOC_FILE, {
|
|
113
|
+
newFileName: newFileName.trim()
|
|
114
|
+
});
|
|
115
|
+
closeDialog();
|
|
116
|
+
}, [closeDialog, newFileName]);
|
|
117
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
118
|
+
ref: historyFilesRef,
|
|
119
|
+
className: "sdoc-history-files-wrapper popover",
|
|
120
|
+
style: _objectSpread({}, position)
|
|
121
|
+
}, /*#__PURE__*/React.createElement("input", {
|
|
122
|
+
id: "sdoc-history-files-search-input",
|
|
123
|
+
className: "sdoc-history-files-search-input",
|
|
124
|
+
ref: historyFilesInputRef,
|
|
125
|
+
autoComplete: "off",
|
|
126
|
+
onChange: onSearch,
|
|
127
|
+
onCompositionStart: e => {
|
|
128
|
+
e.stopPropagation();
|
|
129
|
+
}
|
|
130
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
131
|
+
className: "sdoc-history-files-content"
|
|
132
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
133
|
+
className: "sdoc-history-files-header"
|
|
134
|
+
}, header), /*#__PURE__*/React.createElement("div", {
|
|
135
|
+
className: "sdoc-history-files"
|
|
136
|
+
}, files.map(item => {
|
|
137
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
138
|
+
key: item.file_uuid,
|
|
139
|
+
className: "sdoc-history-files-item",
|
|
140
|
+
onClick: () => {
|
|
141
|
+
onSelect(item);
|
|
142
|
+
}
|
|
143
|
+
}, /*#__PURE__*/React.createElement("i", {
|
|
144
|
+
className: "sdocfont sdoc-document"
|
|
145
|
+
}), /*#__PURE__*/React.createElement("span", null, item.file_name));
|
|
146
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
147
|
+
className: "sdoc-history-files-item",
|
|
148
|
+
onClick: onShowMore
|
|
149
|
+
}, "...", t('More'))), /*#__PURE__*/React.createElement("div", {
|
|
150
|
+
className: "sdoc-history-files-add",
|
|
151
|
+
onClick: onCreateFile
|
|
152
|
+
}, /*#__PURE__*/React.createElement("i", {
|
|
153
|
+
className: "sdocfont sdoc-append"
|
|
154
|
+
}), /*#__PURE__*/React.createElement("span", null, newFileName ? t("Create ".concat(newFileName, ".sdoc")) : t('Create_a_new_sdoc_file')))));
|
|
155
|
+
};
|
|
156
|
+
export default withTranslation('sdoc-editor')(HistoryFiles);
|
|
@@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useState, useRef } from 'react';
|
|
|
2
2
|
import { CustomTableSizeDialog, SplitCellSettingDialog } from '../../plugins/table/dialogs';
|
|
3
3
|
import AddLinkDialog from '../../plugins/link/dialog/add-link-dialog';
|
|
4
4
|
import SelectFileDialog from '../select-file-dialog/index.js';
|
|
5
|
+
import HistoryFiles from '../history-files';
|
|
5
6
|
import EventBus from '../../../utils/event-bus';
|
|
6
7
|
import { INTERNAL_EVENT } from '../../../constants';
|
|
7
8
|
import { ELEMENT_TYPE, INSERT_POSITION, LOCAL_IMAGE } from '../../constants';
|
|
@@ -16,6 +17,7 @@ const InsertElementDialog = _ref => {
|
|
|
16
17
|
const [insertPosition, setInsertPosition] = useState(INSERT_POSITION.CURRENT);
|
|
17
18
|
const [slateNode, setSlateNode] = useState(null);
|
|
18
19
|
const [insertLinkCallback, setInsertLinkCallback] = useState(null);
|
|
20
|
+
const [isShowHistoryFiles, setIsShowHistoryFiles] = useState(false);
|
|
19
21
|
const uploadLocalImageInputRef = useRef();
|
|
20
22
|
const onFileChanged = useCallback(event => {
|
|
21
23
|
const files = event.target.files;
|
|
@@ -42,7 +44,8 @@ const InsertElementDialog = _ref => {
|
|
|
42
44
|
insertPosition = INSERT_POSITION.CURRENT,
|
|
43
45
|
slateNode,
|
|
44
46
|
insertFileLinkCallback,
|
|
45
|
-
insertSdocFileLinkCallback
|
|
47
|
+
insertSdocFileLinkCallback,
|
|
48
|
+
isShowHistoryFiles
|
|
46
49
|
} = _ref2;
|
|
47
50
|
setInsertPosition(insertPosition);
|
|
48
51
|
setSlateNode(slateNode);
|
|
@@ -52,6 +55,7 @@ const InsertElementDialog = _ref => {
|
|
|
52
55
|
insertSdocFileLinkCallback,
|
|
53
56
|
insertFileLinkCallback
|
|
54
57
|
});
|
|
58
|
+
setIsShowHistoryFiles(isShowHistoryFiles);
|
|
55
59
|
if (type === LOCAL_IMAGE) {
|
|
56
60
|
setTimeout(() => {
|
|
57
61
|
uploadLocalImageInputRef.current && uploadLocalImageInputRef.current.click();
|
|
@@ -64,6 +68,7 @@ const InsertElementDialog = _ref => {
|
|
|
64
68
|
setElement('');
|
|
65
69
|
setDialogType('');
|
|
66
70
|
setInsertLinkCallback(null);
|
|
71
|
+
setIsShowHistoryFiles(false);
|
|
67
72
|
}, []);
|
|
68
73
|
const props = {
|
|
69
74
|
insertPosition,
|
|
@@ -93,6 +98,9 @@ const InsertElementDialog = _ref => {
|
|
|
93
98
|
insertLinkCallback,
|
|
94
99
|
closeDialog
|
|
95
100
|
};
|
|
101
|
+
if (isShowHistoryFiles) {
|
|
102
|
+
return /*#__PURE__*/React.createElement(HistoryFiles, sdocLinkProps);
|
|
103
|
+
}
|
|
96
104
|
return /*#__PURE__*/React.createElement(SelectFileDialog, sdocLinkProps);
|
|
97
105
|
}
|
|
98
106
|
case ELEMENT_TYPE.FILE_LINK:
|
|
@@ -1,44 +1,9 @@
|
|
|
1
1
|
.sdoc-file-select-dialog {
|
|
2
|
-
max-width:
|
|
2
|
+
max-width: 520px;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
.sdoc-file-select-dialog .sdoc-file-select-modal {
|
|
6
|
-
width:
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.sdoc-file-select-dialog .sdoc-file-select-container {
|
|
10
|
-
display: flex;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.sdoc-file-select-dialog .sdoc-file-select-left {
|
|
14
|
-
border-right: 1px solid #e9ecef;
|
|
15
|
-
width: 150px;
|
|
16
|
-
padding: 12px 8px;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.sdoc-file-select-dialog .sdoc-file-select-left .sdoc-file-select-nav-item {
|
|
20
|
-
padding: 5px 0 5px 8px;
|
|
21
|
-
border-radius: 3px;
|
|
22
|
-
display: inline-block;
|
|
23
|
-
cursor: pointer;
|
|
24
|
-
width: 100%;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.sdoc-file-select-dialog .sdoc-file-select-left .sdoc-file-select-nav-item:hover {
|
|
28
|
-
background-color: #f5f5f5;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.sdoc-file-select-dialog .sdoc-file-select-container .sdoc-file-select-left .selected-sdoc-file-select-nav-item {
|
|
32
|
-
background-color: #ff8000;
|
|
33
|
-
color: #fff;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.sdoc-file-select-dialog .sdoc-file-select-right {
|
|
37
|
-
height: 440px;
|
|
38
|
-
width: 468px;
|
|
39
|
-
display: flex;
|
|
40
|
-
padding: 0;
|
|
41
|
-
flex-direction: column;
|
|
6
|
+
width: 520px;
|
|
42
7
|
}
|
|
43
8
|
|
|
44
9
|
.sdoc-file-select-dialog .sdoc-file-select-footer {
|
|
@@ -73,14 +73,6 @@ const SelectSdocFileDialog = _ref => {
|
|
|
73
73
|
className: "p-0"
|
|
74
74
|
}, /*#__PURE__*/React.createElement("div", {
|
|
75
75
|
className: "sdoc-file-select-container"
|
|
76
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
77
|
-
className: "sdoc-file-select-left"
|
|
78
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
79
|
-
className: "sdoc-file-select-nav"
|
|
80
|
-
}, /*#__PURE__*/React.createElement("div", {
|
|
81
|
-
className: "sdoc-file-select-nav-item selected-sdoc-file-select-nav-item"
|
|
82
|
-
}, t('Local_file')))), /*#__PURE__*/React.createElement("div", {
|
|
83
|
-
className: "sdoc-file-select-right"
|
|
84
76
|
}, /*#__PURE__*/React.createElement(LocalFiles, {
|
|
85
77
|
fileType: FILE_TYPE[dialogType],
|
|
86
78
|
onSelectedFile: onSelectedFile,
|
|
@@ -96,6 +88,6 @@ const SelectSdocFileDialog = _ref => {
|
|
|
96
88
|
className: "highlight-bg-color",
|
|
97
89
|
disabled: !currentSelectedFile,
|
|
98
90
|
onClick: onSubmit
|
|
99
|
-
}, t('Confirm'))))))
|
|
91
|
+
}, t('Confirm'))))));
|
|
100
92
|
};
|
|
101
93
|
export default SelectSdocFileDialog;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
.sdoc-files-tree {
|
|
2
2
|
flex: 1;
|
|
3
|
-
padding: 16px;
|
|
4
|
-
overflow: auto;
|
|
3
|
+
padding: 8px 16px;
|
|
5
4
|
width: 100%;
|
|
5
|
+
height: 400px;
|
|
6
|
+
overflow-y: auto;
|
|
6
7
|
display: flex;
|
|
7
8
|
flex-direction: column;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
.sdoc-files-tree .sdoc-file-info {
|
|
11
12
|
border-radius: 2px;
|
|
12
|
-
height:
|
|
13
|
-
line-height:
|
|
13
|
+
height: 32px;
|
|
14
|
+
line-height: 32px;
|
|
14
15
|
overflow: hidden;
|
|
15
16
|
text-overflow: ellipsis;
|
|
16
17
|
white-space: nowrap;
|
|
@@ -20,8 +21,7 @@
|
|
|
20
21
|
|
|
21
22
|
.sdoc-files-tree .sdoc-file-info:hover {
|
|
22
23
|
cursor: pointer;
|
|
23
|
-
background: #
|
|
24
|
-
box-shadow: inset 0 0 1px #999;
|
|
24
|
+
background-color: #f5f5f5;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
.sdoc-files-tree .sdoc-file-info .sdoc-file-icon-container {
|
|
@@ -37,13 +37,7 @@
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
.sdoc-files-tree .sdoc-file-info.active {
|
|
40
|
-
background: #
|
|
41
|
-
box-shadow: inset 0 0 1px #999;
|
|
42
|
-
color: #fff;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
.sdoc-files-tree .sdoc-file-info.active .sdoc-file-icon {
|
|
46
|
-
color: #fff;
|
|
40
|
+
background-color: #f5f5f5;
|
|
47
41
|
}
|
|
48
42
|
|
|
49
43
|
.sdoc-files-tree .sdoc-file-icon-toggle {
|
|
@@ -4,8 +4,9 @@ import { Editor, Transforms, Range, Text } from '@seafile/slate';
|
|
|
4
4
|
import slugid from 'slugid';
|
|
5
5
|
import copy from 'copy-to-clipboard';
|
|
6
6
|
import context from '../../../../context';
|
|
7
|
-
import { SDOC_LINK, LINK, INSERT_FILE_DISPLAY_TYPE, CODE_BLOCK, CODE_LINE, PARAGRAPH } from '../../constants';
|
|
8
7
|
import { focusEditor, getNodeType, getSelectedElems } from '../../core';
|
|
8
|
+
import { LocalStorage } from '../../../../utils';
|
|
9
|
+
import { SDOC_LINK, LINK, INSERT_FILE_DISPLAY_TYPE, CODE_BLOCK, CODE_LINE, PARAGRAPH } from '../../constants';
|
|
9
10
|
export const isMenuDisabled = (editor, readonly) => {
|
|
10
11
|
if (readonly) return true;
|
|
11
12
|
if (editor.selection == null) return true;
|
|
@@ -55,12 +56,11 @@ export const insertSdocFileLink = (editor, text, uuid) => {
|
|
|
55
56
|
|
|
56
57
|
// Remove shortcut symbol,if trigger by shortcut
|
|
57
58
|
removeShortCutSymbol(editor);
|
|
59
|
+
const sdocFileNode = generateSdocFileNode(uuid, text);
|
|
58
60
|
if (isCollapsed) {
|
|
59
61
|
// Insert Spaces before and after sdoclinks for easy operation
|
|
60
62
|
editor.insertText(' ');
|
|
61
|
-
const sdocFileNode = generateSdocFileNode(uuid, text);
|
|
62
63
|
Transforms.insertNodes(editor, sdocFileNode);
|
|
63
|
-
|
|
64
64
|
// Not being able to use insertText directly causes the added Spaces to be added to the linked text, as in the issue above, replaced by insertFragment
|
|
65
65
|
editor.insertFragment([{
|
|
66
66
|
id: slugid.nice(),
|
|
@@ -71,11 +71,9 @@ export const insertSdocFileLink = (editor, text, uuid) => {
|
|
|
71
71
|
if (selectedText !== text) {
|
|
72
72
|
// If the selected text is different from the typed text, delete the text and insert the link
|
|
73
73
|
editor.deleteFragment();
|
|
74
|
-
const sdocFileNode = generateSdocFileNode(uuid, text);
|
|
75
74
|
Transforms.insertNodes(editor, sdocFileNode);
|
|
76
75
|
} else {
|
|
77
76
|
// If the selected text is the same as the entered text, only the link can be wrapped
|
|
78
|
-
const sdocFileNode = generateSdocFileNode(uuid, text);
|
|
79
77
|
Transforms.wrapNodes(editor, sdocFileNode, {
|
|
80
78
|
split: true
|
|
81
79
|
});
|
|
@@ -55,7 +55,8 @@ const withSdocLink = editor => {
|
|
|
55
55
|
if (isTriggeredByShortCut(newEditor)) {
|
|
56
56
|
eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
|
|
57
57
|
type: ELEMENT_TYPE.SDOC_LINK,
|
|
58
|
-
insertSdocFileLinkCallback: insertSdocFileLink
|
|
58
|
+
insertSdocFileLinkCallback: insertSdocFileLink,
|
|
59
|
+
isShowHistoryFiles: true
|
|
59
60
|
});
|
|
60
61
|
}
|
|
61
62
|
return onHotKeyDown && onHotKeyDown(event);
|
|
@@ -168,11 +168,11 @@ export const getListNode = (editor, path) => {
|
|
|
168
168
|
export const onWrapListItem = (editor, targetPath, sourcePath) => {
|
|
169
169
|
const nextPath = Path.next(targetPath);
|
|
170
170
|
const listNode = getListNode(editor, sourcePath);
|
|
171
|
-
Transforms.insertNodes(editor, listNode, {
|
|
172
|
-
at: nextPath
|
|
173
|
-
});
|
|
174
171
|
Transforms.removeNodes(editor, {
|
|
175
172
|
at: sourcePath
|
|
176
173
|
});
|
|
174
|
+
Transforms.insertNodes(editor, listNode, {
|
|
175
|
+
at: nextPath
|
|
176
|
+
});
|
|
177
177
|
return;
|
|
178
178
|
};
|
package/dist/constants/index.js
CHANGED
|
@@ -16,7 +16,8 @@ export const EXTERNAL_EVENT = {
|
|
|
16
16
|
REMOVE_DOCUMENT_ERROR: 'remove_document_error',
|
|
17
17
|
NEW_NOTIFICATION: 'new_notification',
|
|
18
18
|
PARTICIPANT_ADDED: 'participant-added',
|
|
19
|
-
PARTICIPANT_REMOVED: 'participant-removed'
|
|
19
|
+
PARTICIPANT_REMOVED: 'participant-removed',
|
|
20
|
+
CREATE_SDOC_FILE: 'create_sdoc_file'
|
|
20
21
|
};
|
|
21
22
|
export const TIP_TYPE = {
|
|
22
23
|
DELETE_NO_CHANGES_REVISION: 'delete_no_changes_revision',
|
package/package.json
CHANGED
|
@@ -440,5 +440,9 @@
|
|
|
440
440
|
"Replace_all": "Replace all",
|
|
441
441
|
"Are_you_sure_to_replace_all_number_xxx_in_this_document_with_yyy": "Are you sure to replace all {{number}} '{{originalWord}}' in this document with '{{replacedWord}}'?",
|
|
442
442
|
"Are_you_sure_to_clear_all_number_xxx_in_this_document": "Are you sure to clear all {{number}} '{{originalWord}}' in this document?",
|
|
443
|
-
"Search_not_found": "Not found"
|
|
443
|
+
"Search_not_found": "Not found",
|
|
444
|
+
"Recent_previews": "Recent previews",
|
|
445
|
+
"The_document_does_not_exist": "The document does not exist",
|
|
446
|
+
"Create_a_new_sdoc_file": "Create a new sdoc file",
|
|
447
|
+
"Create": "Create"
|
|
444
448
|
}
|
|
@@ -440,5 +440,9 @@
|
|
|
440
440
|
"Replace_all": "替换全部",
|
|
441
441
|
"Are_you_sure_to_replace_all_number_xxx_in_this_document_with_yyy": "确定要将此文档内的 {{number}} 处 \"{{originalWord}} \" 替换为 \"{{replacedWord}} \" 吗?",
|
|
442
442
|
"Are_you_sure_to_clear_all_number_xxx_in_this_document": "确定将此文档内的 {{number}} 处 \"{{originalWord}}\" 全部清除吗?",
|
|
443
|
-
"Search_not_found": "未找到"
|
|
443
|
+
"Search_not_found": "未找到",
|
|
444
|
+
"Recent_previews": "最近浏览",
|
|
445
|
+
"The_document_does_not_exist": "不存在该文档",
|
|
446
|
+
"Create_a_new_sdoc_file": "新建sdoc文件",
|
|
447
|
+
"Create": "新建"
|
|
444
448
|
}
|