@seafile/sdoc-editor 1.0.171 → 1.0.172

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.
@@ -19,7 +19,6 @@ var _constants2 = require("../../../constants");
19
19
  var _constants3 = require("../../constants");
20
20
  var _toast = _interopRequireDefault(require("../../../../components/toast"));
21
21
  var _helpers = require("../../plugins/sdoc-link/helpers");
22
- var _helpers2 = require("../../plugins/wiki-link/helpers");
23
22
  require("./style.css");
24
23
  const FileLinkInsertDialog = _ref => {
25
24
  let {
@@ -27,6 +26,11 @@ const FileLinkInsertDialog = _ref => {
27
26
  element,
28
27
  closeDialog
29
28
  } = _ref;
29
+ const {
30
+ t
31
+ } = (0, _reactI18next.useTranslation)();
32
+ const eventBus = _eventBus.default.getInstance();
33
+ const fileLinkInsertRef = (0, _react.useRef)(null);
30
34
  const historyFileWrapperRef = (0, _react.useRef)(document.querySelector('.sdoc-history-files-wrapper'));
31
35
  const [files, setFiles] = (0, _react.useState)([]);
32
36
  const [position, setPosition] = (0, _react.useState)({
@@ -34,18 +38,14 @@ const FileLinkInsertDialog = _ref => {
34
38
  left: 0
35
39
  });
36
40
  const [newFileName, setNewFileName] = (0, _react.useState)('');
37
- const {
38
- t
39
- } = (0, _reactI18next.useTranslation)();
40
41
  const [header, setHeader] = (0, _react.useState)(t('Recent_visited'));
41
- const eventBus = _eventBus.default.getInstance();
42
42
  const deleteInputAndInsertText = (0, _react.useCallback)(function () {
43
43
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
44
44
  args[_key] = arguments[_key];
45
45
  }
46
46
  return (0, _helpers.insertTextWhenRemoveFileNameCollector)(editor, element, ...args);
47
47
  }, [editor, element]);
48
- const getPosition = (0, _react.useCallback)(() => {
48
+ const getPosition = (0, _react.useCallback)(e => {
49
49
  const {
50
50
  selection
51
51
  } = editor;
@@ -60,6 +60,7 @@ const FileLinkInsertDialog = _ref => {
60
60
  } = domNode.getBoundingClientRect();
61
61
  let popoverTop = top + topGap;
62
62
  let popoverLeft = left + leftGap;
63
+
63
64
  // Insert gap between the popover and the selected node
64
65
  // file item height 32px, header height 32px, add button height 32px, margin-top 8px, max-height 306px
65
66
  const popoverHeight = Math.min(files.length * 32 + 32 * 3 + 8, 300);
@@ -71,17 +72,6 @@ const FileLinkInsertDialog = _ref => {
71
72
  const counterTopGap = 8;
72
73
  popoverTop = top - popoverHeight - counterTopGap;
73
74
  }
74
- if (editor.editorType === _constants2.WIKI_EDITOR) {
75
- const wikiEditorContainer = document.querySelector('.sdoc-editor-container');
76
- if (wikiEditorContainer) {
77
- const {
78
- left,
79
- top
80
- } = wikiEditorContainer.getBoundingClientRect();
81
- popoverLeft -= left;
82
- popoverTop -= top;
83
- }
84
- }
85
75
  setPosition({
86
76
  top: popoverTop,
87
77
  left: popoverLeft
@@ -93,20 +83,30 @@ const FileLinkInsertDialog = _ref => {
93
83
  var _historyFileWrapperRe, _historyFileWrapperRe2;
94
84
  const isClickInside = (_historyFileWrapperRe = historyFileWrapperRef.current) === null || _historyFileWrapperRe === void 0 ? void 0 : (_historyFileWrapperRe2 = _historyFileWrapperRe.contains) === null || _historyFileWrapperRe2 === void 0 ? void 0 : _historyFileWrapperRe2.call(_historyFileWrapperRe, e.target);
95
85
  if (isClickInside) return;
86
+
87
+ // Click on the insertion position without closing
88
+ const insertCollectorEl = document.querySelector('.sdoc-file-name-insert-collector');
89
+ if (insertCollectorEl && insertCollectorEl.className === e.target.className) return;
96
90
  deleteInputAndInsertText();
97
91
  closeDialog();
98
92
  }, [closeDialog, deleteInputAndInsertText]);
99
93
  const onScroll = (0, _react.useCallback)(e => {
100
- getPosition();
94
+ getPosition(e);
101
95
  }, [getPosition]);
102
- const getHistoryFiles = (0, _react.useCallback)(e => {
103
- const getItemKey = editor.editorType === _constants2.WIKI_EDITOR ? 'wiki-recent-files' : 'sdoc-recent-files';
104
- const files = _utils.LocalStorage.getItem(getItemKey) || [];
96
+ const getHistoryFiles = (0, _react.useCallback)(isCalculatedByFiles => {
97
+ const getItemKey = 'sdoc-recent-files';
98
+ let files = _utils.LocalStorage.getItem(getItemKey) || [];
99
+ if (isCalculatedByFiles) {
100
+ const newFiles = (0, _utils.getMaximumCapacity)(files);
101
+ files = newFiles;
102
+ }
105
103
  setFiles(files);
106
- }, [editor.editorType]);
104
+ }, []);
107
105
  (0, _react.useEffect)(() => {
106
+ fileLinkInsertRef.current['isFirstMount'] = true;
108
107
  getHistoryFiles();
109
- }, [getHistoryFiles]);
108
+ // eslint-disable-next-line react-hooks/exhaustive-deps
109
+ }, []);
110
110
  const onKeydown = (0, _react.useCallback)(e => {
111
111
  const {
112
112
  key
@@ -182,23 +182,22 @@ const FileLinkInsertDialog = _ref => {
182
182
  }, []);
183
183
  (0, _react.useEffect)(() => {
184
184
  if (!(element !== null && element !== void 0 && element.children)) return;
185
+ // No search on first load
186
+ if (fileLinkInsertRef.current['isFirstMount']) {
187
+ fileLinkInsertRef.current['isFirstMount'] = false;
188
+ return;
189
+ }
185
190
  const searchText = _slate.Node.string(element);
186
191
  onSearch(searchText);
187
192
  }, [element, onSearch]);
188
193
  const onSelect = (0, _react.useCallback)(fileInfo => {
189
194
  const {
190
195
  doc_uuid,
191
- name,
192
- wikiRepoId,
193
- pageId
196
+ name
194
197
  } = fileInfo;
195
198
  (0, _helpers.removeTempInput)(editor, element);
196
199
  closeDialog();
197
- if (editor.editorType === _constants2.WIKI_EDITOR) {
198
- (0, _helpers2.insertWikiPageLink)(editor, name, wikiRepoId, pageId);
199
- } else {
200
- (0, _helpers.insertSdocFileLink)(editor, name, doc_uuid);
201
- }
200
+ (0, _helpers.insertSdocFileLink)(editor, name, doc_uuid);
202
201
  }, [closeDialog, editor, element]);
203
202
  const onShowMore = (0, _react.useCallback)(() => {
204
203
  eventBus.dispatch(_constants2.INTERNAL_EVENT.INSERT_ELEMENT, {
@@ -211,26 +210,24 @@ const FileLinkInsertDialog = _ref => {
211
210
  e.stopPropagation();
212
211
  (0, _helpers.removeTempInput)(editor, element);
213
212
  const eventBus = _eventBus.default.getInstance();
214
- const dispatchEventKey = editor.editorType === _constants2.WIKI_EDITOR ? _constants.EXTERNAL_EVENT.CREATE_WIKI_PAGE : _constants.EXTERNAL_EVENT.CREATE_SDOC_FILE;
215
- let external_props = {};
216
- if (dispatchEventKey === _constants.EXTERNAL_EVENT.CREATE_SDOC_FILE) {
217
- external_props = {
218
- insertSdocFileLink: _helpers.insertSdocFileLink,
219
- editor
220
- };
221
- }
222
- eventBus.dispatch(dispatchEventKey, {
223
- newFileName: newFileName.trim(),
213
+ const createName = newFileName.trim();
214
+ const external_props = {
215
+ insertSdocFileLink: _helpers.insertSdocFileLink,
216
+ editor
217
+ };
218
+ eventBus.dispatch(_constants.EXTERNAL_EVENT.CREATE_SDOC_FILE, {
219
+ newFileName: createName,
224
220
  ...external_props
225
221
  });
226
222
  }, [editor, element, newFileName]);
227
223
  const createFileTipDefault = (0, _react.useMemo)(() => {
228
- return editor.editorType === _constants2.WIKI_EDITOR ? 'New_page' : 'Create_a_new_sdoc_file';
229
- }, [editor.editorType]);
224
+ return 'Create_a_new_sdoc_file';
225
+ }, []);
230
226
  const createFileName = (0, _react.useMemo)(() => {
231
- return editor.editorType === _constants2.WIKI_EDITOR ? newFileName : `${newFileName}.sdoc`;
232
- }, [editor.editorType, newFileName]);
227
+ return `${newFileName}.sdoc`;
228
+ }, [newFileName]);
233
229
  return /*#__PURE__*/_react.default.createElement("div", {
230
+ ref: fileLinkInsertRef,
234
231
  className: "sdoc-history-files-content popover",
235
232
  style: {
236
233
  ...position,
@@ -249,9 +246,11 @@ const FileLinkInsertDialog = _ref => {
249
246
  onClick: () => {
250
247
  onSelect(item);
251
248
  }
252
- }, /*#__PURE__*/_react.default.createElement("i", {
253
- className: "sdocfont sdoc-document"
254
- }), /*#__PURE__*/_react.default.createElement("span", null, item.name));
249
+ }, /*#__PURE__*/_react.default.createElement("span", {
250
+ className: "file-item-icon sdocfont sdoc-document"
251
+ }), /*#__PURE__*/_react.default.createElement("span", {
252
+ className: "file-item-name"
253
+ }, item.name));
255
254
  }), /*#__PURE__*/_react.default.createElement("div", {
256
255
  className: "sdoc-history-files-item",
257
256
  onClick: onShowMore
@@ -3,7 +3,8 @@
3
3
  flex-direction: column;
4
4
  position: absolute;
5
5
  width: 400px;
6
- max-height: 300px;
6
+ max-width: 400px;
7
+ max-height: 350px;
7
8
  /* The same as hierarchy of comment drawer */
8
9
  z-index: 103;
9
10
  box-shadow: 0 1px 3px rgba(0, 0, 0, .15), 0 4px 8px 3px rgba(0, 0, 0, .15);
@@ -35,17 +36,28 @@
35
36
  }
36
37
 
37
38
  .sdoc-history-files-content .sdoc-history-files .sdoc-history-files-item {
38
- padding: 0px 16px;
39
+ padding: 6px 16px;
39
40
  height: 32px;
40
- line-height: 32px;
41
- text-overflow: ellipsis;
42
41
  font-size: 14px;
43
- white-space: nowrap;
42
+ display: flex;
43
+ align-items: flex-start;
44
44
  }
45
45
 
46
- .sdoc-history-files-content .sdoc-history-files .sdoc-history-files-item :first-child {
47
- font-size: 12px;
48
- margin-right: 5px;
46
+ .sdoc-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-icon {
47
+ font-size: 16px;
48
+ margin-right: 8px;
49
+ color: #ff9800;
50
+ width: 20px;
51
+ height: 20px;
52
+ display: flex;
53
+ justify-content: center;
54
+ align-items: center;
55
+ }
56
+
57
+ .sdoc-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-name {
58
+ white-space: nowrap;
59
+ text-overflow: ellipsis;
60
+ overflow: hidden;
49
61
  }
50
62
 
51
63
  .sdoc-history-files-content .sdoc-history-files .sdoc-history-files-item:hover {
@@ -17,9 +17,11 @@ var _constants2 = require("../../constants");
17
17
  var _helpers = require("../../plugins/image/helpers");
18
18
  var _helpers2 = require("../../plugins/video/helpers");
19
19
  var _context = _interopRequireDefault(require("../../../../context.js"));
20
- var _index2 = _interopRequireDefault(require("../file-insert-dialog/index.js"));
21
- var _index3 = _interopRequireDefault(require("../../../../components/toast/index.js"));
22
- var _index4 = require("../../plugins/video/constants/index.js");
20
+ var _index2 = _interopRequireDefault(require("../wiki-file-insert-dialog/index.js"));
21
+ var _index3 = _interopRequireDefault(require("../file-insert-dialog/index.js"));
22
+ var _index4 = _interopRequireDefault(require("../../../../components/toast/index.js"));
23
+ var _index5 = require("../../plugins/video/constants/index.js");
24
+ var _constants3 = require("../../../../basic-sdk/constants");
23
25
  const InsertElementDialog = _ref => {
24
26
  let {
25
27
  editor
@@ -49,7 +51,7 @@ const InsertElementDialog = _ref => {
49
51
  }, [validEditor, uploadLocalImageInputRef, insertPosition, slateNode]);
50
52
  const handleDisplayAlert = (0, _react.useCallback)(() => {
51
53
  setTimeout(() => {
52
- _index3.default.warning(`${t('The_current_version_does_not_support_>5MB_video_file')}`, {
54
+ _index4.default.warning(`${t('The_current_version_does_not_support_>5MB_video_file')}`, {
53
55
  duration: 3
54
56
  });
55
57
  }, 0);
@@ -57,7 +59,7 @@ const InsertElementDialog = _ref => {
57
59
  const onVideoFileChanged = (0, _react.useCallback)(event => {
58
60
  const files = event.target.files;
59
61
  // Show warning for 3s and no further insertion if video file is more than 5MB
60
- if (files[0].size > _index4.VIDEO_MAX_SIZE_5MB) {
62
+ if (files[0].size > _index5.VIDEO_MAX_SIZE_5MB) {
61
63
  handleDisplayAlert();
62
64
  event.target.value = null;
63
65
  return;
@@ -194,7 +196,14 @@ const InsertElementDialog = _ref => {
194
196
  }
195
197
  case _constants2.ELEMENT_TYPE.FILE_LINK_INSET_INPUT_TEMP:
196
198
  {
197
- return /*#__PURE__*/_react.default.createElement(_index2.default, {
199
+ if (editor.editorType === _constants3.WIKI_EDITOR) {
200
+ return /*#__PURE__*/_react.default.createElement(_index2.default, {
201
+ element: slateNode,
202
+ editor: editor,
203
+ closeDialog: closeDialog
204
+ });
205
+ }
206
+ return /*#__PURE__*/_react.default.createElement(_index3.default, {
198
207
  element: slateNode,
199
208
  editor: editor,
200
209
  closeDialog: closeDialog
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+ var _react = _interopRequireWildcard(require("react"));
10
+ var _slateReact = require("@seafile/slate-react");
11
+ var _reactI18next = require("react-i18next");
12
+ var _slate = require("@seafile/slate");
13
+ var _lodash = _interopRequireDefault(require("lodash.throttle"));
14
+ var _classnames = _interopRequireDefault(require("classnames"));
15
+ var _utils = require("../../../../utils");
16
+ var _constants = require("../../../../constants");
17
+ var _eventBus = _interopRequireDefault(require("../../../utils/event-bus"));
18
+ var _constants2 = require("../../../constants");
19
+ var _helpers = require("../../plugins/sdoc-link/helpers");
20
+ var _helpers2 = require("../../plugins/wiki-link/helpers");
21
+ require("./style.css");
22
+ const WikiFileLinkInsertDialog = _ref => {
23
+ let {
24
+ editor,
25
+ element,
26
+ closeDialog
27
+ } = _ref;
28
+ const {
29
+ t
30
+ } = (0, _reactI18next.useTranslation)();
31
+ const eventBus = _eventBus.default.getInstance();
32
+ const fileLinkInsertRef = (0, _react.useRef)(null);
33
+ const historyFileWrapperRef = (0, _react.useRef)(document.querySelector('.sdoc-history-files-wrapper'));
34
+ const [files, setFiles] = (0, _react.useState)([]);
35
+ const [position, setPosition] = (0, _react.useState)({});
36
+ const [newFileName, setNewFileName] = (0, _react.useState)('');
37
+ const [header, setHeader] = (0, _react.useState)(t('Link_to_page'));
38
+ const [hiddenMoreMenu, setHiddenMoreMenu] = (0, _react.useState)(false);
39
+ const deleteInputAndInsertText = (0, _react.useCallback)(function () {
40
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
41
+ args[_key] = arguments[_key];
42
+ }
43
+ return (0, _helpers.insertTextWhenRemoveFileNameCollector)(editor, element, ...args);
44
+ }, [editor, element]);
45
+ const getPosition = (0, _react.useCallback)(() => {
46
+ queueMicrotask(() => {
47
+ const {
48
+ selection
49
+ } = editor;
50
+ const nodeEntry = _slate.Editor.node(editor, selection);
51
+ const domNode = _slateReact.ReactEditor.toDOMNode(editor, nodeEntry[0]);
52
+ if (domNode) {
53
+ const topGap = 20;
54
+ const leftGap = 16;
55
+ const outlineWidth = 300;
56
+ const {
57
+ top: domNodeTop,
58
+ left: domNodeLeft
59
+ } = domNode.getBoundingClientRect();
60
+ let popoverTop = domNodeTop - topGap;
61
+ let popoverLeft = domNodeLeft - leftGap - outlineWidth;
62
+ const {
63
+ height
64
+ } = fileLinkInsertRef.current.getBoundingClientRect();
65
+ const popoverBottomY = popoverTop + height;
66
+ const viewportHeight = window.innerHeight;
67
+ if (popoverBottomY > viewportHeight) {
68
+ // 8px for the gap between the popover and the bottom of the viewport
69
+ const counterTopGap = 8;
70
+ popoverTop = popoverTop - height - topGap - counterTopGap;
71
+ }
72
+ setPosition({
73
+ top: popoverTop,
74
+ left: popoverLeft
75
+ });
76
+ }
77
+ });
78
+ }, [editor]);
79
+ const onClick = (0, _react.useCallback)(e => {
80
+ var _historyFileWrapperRe, _historyFileWrapperRe2;
81
+ const isClickInside = (_historyFileWrapperRe = historyFileWrapperRef.current) === null || _historyFileWrapperRe === void 0 ? void 0 : (_historyFileWrapperRe2 = _historyFileWrapperRe.contains) === null || _historyFileWrapperRe2 === void 0 ? void 0 : _historyFileWrapperRe2.call(_historyFileWrapperRe, e.target);
82
+ if (isClickInside) return;
83
+
84
+ // Click on the insertion position without closing
85
+ const insertCollectorEl = document.querySelector('.sdoc-file-name-insert-collector');
86
+ if (insertCollectorEl && insertCollectorEl.className === e.target.className) return;
87
+ deleteInputAndInsertText();
88
+ closeDialog();
89
+ }, [closeDialog, deleteInputAndInsertText]);
90
+ const onScroll = (0, _lodash.default)(() => {
91
+ getPosition();
92
+ }, 100);
93
+ const getHistoryFiles = (0, _react.useCallback)(isCalculatedByFiles => {
94
+ let files = _utils.LocalStorage.getItem('wiki-recent-files') || [];
95
+ if (isCalculatedByFiles) {
96
+ const newFiles = (0, _utils.getMaximumCapacity)(files);
97
+ // Can accommodate all without showing more operations
98
+ if (files.length <= newFiles.length) {
99
+ setHiddenMoreMenu(true);
100
+ }
101
+ files = newFiles;
102
+ }
103
+ setFiles(files);
104
+ }, []);
105
+ (0, _react.useEffect)(() => {
106
+ fileLinkInsertRef.current['isFirstMount'] = true;
107
+ getHistoryFiles(true);
108
+ getPosition();
109
+ // eslint-disable-next-line react-hooks/exhaustive-deps
110
+ }, []);
111
+ const onKeydown = (0, _react.useCallback)(e => {
112
+ const {
113
+ key
114
+ } = e;
115
+ switch (key) {
116
+ case 'Escape':
117
+ deleteInputAndInsertText();
118
+ closeDialog();
119
+ break;
120
+ case 'ArrowRight':
121
+ case 'ArrowLeft':
122
+ deleteInputAndInsertText();
123
+ closeDialog();
124
+ break;
125
+ case 'ArrowUp':
126
+ case 'ArrowDown':
127
+ deleteInputAndInsertText();
128
+ closeDialog();
129
+ break;
130
+ default:
131
+ break;
132
+ }
133
+ }, [closeDialog, deleteInputAndInsertText]);
134
+ (0, _react.useEffect)(() => {
135
+ const sdocScrollContainer = document.getElementById('sdoc-scroll-container');
136
+ document.addEventListener('click', onClick);
137
+ document.addEventListener('keydown', onKeydown);
138
+ sdocScrollContainer.addEventListener('scroll', onScroll);
139
+ const unsubscribeCloseDialog = eventBus.subscribe(_constants2.INTERNAL_EVENT.CLOSE_FILE_INSET_DIALOG, closeDialog);
140
+ return () => {
141
+ sdocScrollContainer.removeEventListener('scroll', onScroll);
142
+ document.removeEventListener('click', onClick);
143
+ document.removeEventListener('keydown', onKeydown);
144
+ unsubscribeCloseDialog();
145
+ };
146
+ }, [closeDialog, editor, eventBus, files, getPosition, onClick, onKeydown, onScroll]);
147
+ const onSearch = (0, _react.useCallback)(searchText => {
148
+ if (searchText.trim().length === 0) {
149
+ getHistoryFiles();
150
+ setHiddenMoreMenu(true);
151
+ setHeader(t('Link_to_page'));
152
+ setNewFileName('');
153
+ getPosition();
154
+ return;
155
+ }
156
+ const {
157
+ navConfig
158
+ } = window.wiki.config;
159
+ const {
160
+ pages
161
+ } = navConfig;
162
+ const newFiles = [];
163
+ pages.forEach(page => {
164
+ if (page.name.includes(searchText.trim())) {
165
+ newFiles.push(page);
166
+ }
167
+ });
168
+ // No results found
169
+ if (newFiles.length === 0) {
170
+ setHeader(t('No_page_results'));
171
+ setNewFileName(searchText);
172
+ } else {
173
+ setHeader(t('Link_to_page'));
174
+ setNewFileName('');
175
+ }
176
+ setHiddenMoreMenu(true);
177
+ setFiles(newFiles);
178
+ getPosition();
179
+ // eslint-disable-next-line react-hooks/exhaustive-deps
180
+ }, []);
181
+ (0, _react.useEffect)(() => {
182
+ if (!(element !== null && element !== void 0 && element.children)) return;
183
+ // No search on first load
184
+ if (fileLinkInsertRef.current['isFirstMount']) {
185
+ fileLinkInsertRef.current['isFirstMount'] = false;
186
+ return;
187
+ }
188
+ const searchText = _slate.Node.string(element);
189
+ onSearch(searchText);
190
+ }, [element, onSearch]);
191
+ const onSelect = (0, _react.useCallback)(fileInfo => {
192
+ const {
193
+ name,
194
+ wikiRepoId,
195
+ pageId,
196
+ icon,
197
+ isDir
198
+ } = fileInfo;
199
+ (0, _helpers.removeTempInput)(editor, element);
200
+ closeDialog();
201
+ (0, _helpers2.insertWikiPageLink)(editor, name, wikiRepoId, pageId, icon, isDir);
202
+ }, [closeDialog, editor, element]);
203
+ const onShowMoreWiki = (0, _react.useCallback)(e => {
204
+ e.stopPropagation();
205
+ const recentFiles = _utils.LocalStorage.getItem('wiki-recent-files') || [];
206
+ setFiles(recentFiles);
207
+ setHiddenMoreMenu(true);
208
+ }, []);
209
+ const onCreateFile = (0, _react.useCallback)(e => {
210
+ e.stopPropagation();
211
+ (0, _helpers.removeTempInput)(editor, element);
212
+ const eventBus = _eventBus.default.getInstance();
213
+ const createName = newFileName.trim() || t('New_page');
214
+ eventBus.dispatch(_constants.EXTERNAL_EVENT.CREATE_WIKI_PAGE, {
215
+ newFileName: createName
216
+ });
217
+ }, [editor, element, newFileName, t]);
218
+ const createFileTipDefault = (0, _react.useMemo)(() => {
219
+ return 'New_page';
220
+ }, []);
221
+ const createFileName = (0, _react.useMemo)(() => {
222
+ return `"${newFileName}" ${t('Page')}`;
223
+ }, [newFileName, t]);
224
+ return /*#__PURE__*/_react.default.createElement("div", {
225
+ ref: fileLinkInsertRef,
226
+ className: (0, _classnames.default)('wiki-history-files-content popover'),
227
+ style: {
228
+ ...position,
229
+ position: 'absolute',
230
+ opacity: Object.keys(position).length ? 1 : 0
231
+ }
232
+ }, header.length !== 0 && /*#__PURE__*/_react.default.createElement("div", {
233
+ className: "wiki-history-files-header"
234
+ }, header), /*#__PURE__*/_react.default.createElement("div", {
235
+ className: (0, _classnames.default)('sdoc-history-files', {
236
+ 'no-header': header.length === 0
237
+ })
238
+ }, files.map(item => {
239
+ return /*#__PURE__*/_react.default.createElement("div", {
240
+ key: item.doc_uuid,
241
+ className: (0, _classnames.default)('sdoc-history-files-item', {
242
+ 'files-item-has-dir': item === null || item === void 0 ? void 0 : item.path
243
+ }),
244
+ onClick: () => {
245
+ onSelect(item);
246
+ }
247
+ }, (item === null || item === void 0 ? void 0 : item.icon) && /*#__PURE__*/_react.default.createElement("span", {
248
+ className: "file-item-emoticons"
249
+ }, item.icon), !(item !== null && item !== void 0 && item.icon) && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, item !== null && item !== void 0 && item.isDir ? /*#__PURE__*/_react.default.createElement("span", {
250
+ className: "file-item-icon sf3-font sf3-font-files2"
251
+ }) : /*#__PURE__*/_react.default.createElement("span", {
252
+ className: "file-item-icon sf3-font sf3-font-file"
253
+ })), /*#__PURE__*/_react.default.createElement("span", {
254
+ className: "file-item-name-wrapper"
255
+ }, /*#__PURE__*/_react.default.createElement("span", {
256
+ className: "file-item-name"
257
+ }, item.name), (item === null || item === void 0 ? void 0 : item.path) && /*#__PURE__*/_react.default.createElement("span", {
258
+ className: "name-dir"
259
+ }, item.path)));
260
+ }), !hiddenMoreMenu && /*#__PURE__*/_react.default.createElement("div", {
261
+ className: "sdoc-history-files-item",
262
+ onClick: onShowMoreWiki
263
+ }, "...", t('More'))), /*#__PURE__*/_react.default.createElement("div", {
264
+ className: "sdoc-history-files-add",
265
+ onClick: onCreateFile
266
+ }, /*#__PURE__*/_react.default.createElement("i", {
267
+ className: "sdocfont sdoc-append"
268
+ }), /*#__PURE__*/_react.default.createElement("span", {
269
+ className: "new-file-name"
270
+ }, newFileName ? t('Create_file_name_sdoc', {
271
+ file_name_sdoc: createFileName
272
+ }) : t(createFileTipDefault))));
273
+ };
274
+ var _default = exports.default = WikiFileLinkInsertDialog;
@@ -0,0 +1,116 @@
1
+ .wiki-history-files-content {
2
+ display: flex;
3
+ flex-direction: column;
4
+ position: absolute;
5
+ width: 400px;
6
+ max-width: 400px;
7
+ max-height: 350px;
8
+ /* The same as hierarchy of comment drawer */
9
+ z-index: 103;
10
+ box-shadow: 0 1px 3px rgba(0, 0, 0, .15), 0 4px 8px 3px rgba(0, 0, 0, .15);
11
+ }
12
+
13
+ .wiki-history-files-content .wiki-history-files-header {
14
+ display: flex;
15
+ flex-shrink: 0;
16
+ align-items: center;
17
+ margin-top: 8px;
18
+ padding: 0px 16px;
19
+ height: 32px;
20
+ width: 100%;
21
+ color: #999999;
22
+ font-size: 14px;
23
+ user-select: none;
24
+ cursor: default;
25
+ }
26
+
27
+ .wiki-history-files-content .sdoc-history-files {
28
+ flex-grow: 1;
29
+ overflow-y: auto;
30
+ cursor: pointer;
31
+ }
32
+
33
+ .wiki-history-files-content .no-header {
34
+ margin-top: 8px;
35
+ width: 100%;
36
+ }
37
+
38
+ .wiki-history-files-content .sdoc-history-files .sdoc-history-files-item {
39
+ padding: 6px 16px;
40
+ height: 32px;
41
+ font-size: 14px;
42
+ display: flex;
43
+ align-items: flex-start;
44
+ }
45
+
46
+ .wiki-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-icon {
47
+ font-size: 16px;
48
+ margin-right: 8px;
49
+ color: #666666;
50
+ width: 20px;
51
+ height: 20px;
52
+ display: flex;
53
+ justify-content: center;
54
+ align-items: center;
55
+ }
56
+
57
+ .wiki-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-name {
58
+ white-space: nowrap;
59
+ text-overflow: ellipsis;
60
+ overflow: hidden;
61
+ }
62
+
63
+ .wiki-history-files-content .sdoc-history-files .sdoc-history-files-item:hover {
64
+ background-color: #f5f5f5;
65
+ }
66
+
67
+ .wiki-history-files-content .sdoc-history-files-add {
68
+ display: flex;
69
+ flex-shrink: 0;
70
+ align-items: center;
71
+ padding: 0px 16px;
72
+ height: 32px;
73
+ width: 100%;
74
+ border-top: 1px solid #e9ecef;
75
+ font-size: 14px;
76
+ cursor: pointer;
77
+ }
78
+
79
+ .wiki-history-files-content .sdoc-history-files-add :first-child {
80
+ color: #444444;
81
+ margin-right: 10px;
82
+ }
83
+
84
+ .wiki-history-files-content .sdoc-history-files-add .new-file-name {
85
+ text-wrap: nowrap;
86
+ text-overflow: ellipsis;
87
+ overflow: hidden;
88
+ }
89
+
90
+ .wiki-history-files-content .sdoc-history-files .sdoc-history-files-item.files-item-has-dir {
91
+ height: 51px;
92
+ }
93
+
94
+ .wiki-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-emoticons {
95
+ font-size: 14px;
96
+ margin-right: 8px;
97
+ width: 20px;
98
+ height: 20px;
99
+ display: flex;
100
+ justify-content: center;
101
+ align-items: center;
102
+ }
103
+
104
+ .wiki-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-name-wrapper {
105
+ display: flex;
106
+ flex-direction: column;
107
+ overflow: hidden;
108
+ }
109
+
110
+ .wiki-history-files-content .sdoc-history-files .sdoc-history-files-item .file-item-name-wrapper .name-dir {
111
+ color: #666;
112
+ font-size: 12px;
113
+ white-space: nowrap;
114
+ text-overflow: ellipsis;
115
+ overflow: hidden;
116
+ }
@@ -69,6 +69,27 @@ const insertSdocFileLink = (editor, text, uuid) => {
69
69
  removeShortCutSymbol(editor);
70
70
  const sdocFileNode = generateSdocFileNode(uuid, text);
71
71
  if (isCollapsed) {
72
+ const {
73
+ anchor,
74
+ focus
75
+ } = editor.selection;
76
+ const [targetNode] = _slate.Editor.node(editor, editor.selection, {
77
+ depth: 2
78
+ }) || [];
79
+
80
+ // When the current cursor position is on a link, change the position to after the link
81
+ if (targetNode && targetNode.type === _constants.SDOC_LINK && anchor.path.length === 3) {
82
+ editor.selection = {
83
+ anchor: {
84
+ offset: anchor.offset,
85
+ path: [anchor.path[0], anchor.path[1] + 1]
86
+ },
87
+ focus: {
88
+ offset: focus.offset,
89
+ path: [focus.path[0], focus.path[1] + 1]
90
+ }
91
+ };
92
+ }
72
93
  _slate.Transforms.insertNodes(editor, sdocFileNode);
73
94
  } else {
74
95
  const selectedText = _slate.Editor.string(editor, selection); // Selected text
@@ -25,6 +25,10 @@ const SdocFileLink = _ref => {
25
25
  children,
26
26
  attributes
27
27
  } = _ref;
28
+ const {
29
+ icon,
30
+ isDir
31
+ } = element;
28
32
  const sdocFileRef = (0, _react.useRef)(null);
29
33
  const scrollRef = (0, _useScrollContext.useScrollContext)();
30
34
  const [isShowInsertHoverMenu, setIsShowInsertHoverMenu] = (0, _react.useState)(false);
@@ -134,9 +138,13 @@ const SdocFileLink = _ref => {
134
138
  }, [_constants2.SDOC_LINK_TYPE.ICON_LINK, _constants2.SDOC_LINK_TYPE.CARD_LINK].includes(element.display_type) && /*#__PURE__*/_react.default.createElement("span", {
135
139
  className: "sdoc-file-link-icon",
136
140
  style: style
137
- }, /*#__PURE__*/_react.default.createElement("i", {
141
+ }, element.type !== _elementType.WIKI_LINK && /*#__PURE__*/_react.default.createElement("i", {
138
142
  className: "sdocfont sdoc-document"
139
- })), /*#__PURE__*/_react.default.createElement("span", {
143
+ }), element.type === _elementType.WIKI_LINK && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, icon && /*#__PURE__*/_react.default.createElement("span", null, icon), !icon && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isDir ? /*#__PURE__*/_react.default.createElement("span", {
144
+ className: "sf3-font sf3-font-files2"
145
+ }) : /*#__PURE__*/_react.default.createElement("span", {
146
+ className: "sf3-font sf3-font-file"
147
+ })))), /*#__PURE__*/_react.default.createElement("span", {
140
148
  className: 'sdoc-file-text-link',
141
149
  style: style
142
150
  }, /*#__PURE__*/_react.default.createElement("a", {
@@ -4,13 +4,13 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.insertWikiPageLink = exports.getWikiUrl = exports.generateSdocFileNode = void 0;
7
+ exports.insertWikiPageLink = exports.getWikiUrl = exports.generateWikiFileNode = void 0;
8
8
  var _slate = require("@seafile/slate");
9
9
  var _slugid = _interopRequireDefault(require("slugid"));
10
10
  var _constants = require("../../constants");
11
11
  var _helpers = require("../sdoc-link/helpers");
12
12
  var _elementType = require("../../constants/element-type");
13
- const insertWikiPageLink = (editor, text, wikiRepoId, pageId) => {
13
+ const insertWikiPageLink = (editor, text, wikiRepoId, pageId, icon, isDir) => {
14
14
  if ((0, _helpers.isMenuDisabled)(editor)) return;
15
15
  // Selection folded or not
16
16
  const {
@@ -21,7 +21,7 @@ const insertWikiPageLink = (editor, text, wikiRepoId, pageId) => {
21
21
 
22
22
  // Remove shortcut symbol,if trigger by shortcut
23
23
  (0, _helpers.removeShortCutSymbol)(editor);
24
- const wikiLinkNode = generateSdocFileNode(wikiRepoId, pageId, text);
24
+ const wikiLinkNode = generateWikiFileNode(wikiRepoId, pageId, text, icon, isDir);
25
25
  if (isCollapsed) {
26
26
  _slate.Transforms.insertNodes(editor, wikiLinkNode);
27
27
  } else {
@@ -42,14 +42,18 @@ const insertWikiPageLink = (editor, text, wikiRepoId, pageId) => {
42
42
  }
43
43
  };
44
44
  exports.insertWikiPageLink = insertWikiPageLink;
45
- const generateSdocFileNode = function (wikiRepoId, pageId) {
45
+ const generateWikiFileNode = function (wikiRepoId, pageId) {
46
46
  let title = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
47
+ let icon = arguments.length > 3 ? arguments[3] : undefined;
48
+ let isDir = arguments.length > 4 ? arguments[4] : undefined;
47
49
  const wikiPageLinkNode = {
48
50
  id: _slugid.default.nice(),
49
51
  type: _elementType.WIKI_LINK,
50
52
  wiki_repo_id: wikiRepoId,
51
53
  page_id: pageId,
52
54
  title: title,
55
+ icon,
56
+ isDir,
53
57
  display_type: _constants.INSERT_FILE_DISPLAY_TYPE[1],
54
58
  children: [{
55
59
  id: _slugid.default.nice(),
@@ -58,13 +62,11 @@ const generateSdocFileNode = function (wikiRepoId, pageId) {
58
62
  };
59
63
  return wikiPageLinkNode;
60
64
  };
61
- exports.generateSdocFileNode = generateSdocFileNode;
65
+ exports.generateWikiFileNode = generateWikiFileNode;
62
66
  const getWikiUrl = (wikiRepoId, pageId) => {
63
67
  const {
64
- origin,
65
- pathname
68
+ origin
66
69
  } = window.location;
67
- const pathName = pathname.replace(/\d+\/$/, `${wikiRepoId}/`);
68
- return `${origin}${pathName}?page_id=${pageId}`;
70
+ return `${origin}/wikis/${wikiRepoId}/?page_id=${pageId}`;
69
71
  };
70
72
  exports.getWikiUrl = getWikiUrl;
@@ -25,7 +25,7 @@ Object.defineProperty(exports, "getEventTransfer", {
25
25
  return _getEventTransfer.default;
26
26
  }
27
27
  });
28
- exports.resetWebTitle = exports.isMobile = exports.isMac = exports.isEnglish = exports.getSelectionCoords = exports.getImageFileNameWithTimestamp = void 0;
28
+ exports.resetWebTitle = exports.isMobile = exports.isMac = exports.isEnglish = exports.getSelectionCoords = exports.getMaximumCapacity = exports.getImageFileNameWithTimestamp = void 0;
29
29
  var _dateUtils = _interopRequireDefault(require("./date-utils"));
30
30
  var _localStorageUtils = _interopRequireDefault(require("./local-storage-utils"));
31
31
  var _context = _interopRequireDefault(require("../context"));
@@ -152,4 +152,22 @@ const isEnglish = str => {
152
152
  }
153
153
  return false;
154
154
  };
155
- exports.isEnglish = isEnglish;
155
+ exports.isEnglish = isEnglish;
156
+ const getMaximumCapacity = files => {
157
+ const containerMaxHeight = 350;
158
+ const containerTop = 40;
159
+ const containerBottom = 32;
160
+ const containerMore = 32;
161
+ const availableHeight = containerMaxHeight - containerTop - containerBottom - containerMore;
162
+ let allHeight = 0;
163
+ const newFiles = [];
164
+ files.forEach(file => {
165
+ const itemHeight = file !== null && file !== void 0 && file.path ? 51 : 32;
166
+ allHeight = allHeight + itemHeight;
167
+ if (allHeight <= availableHeight) {
168
+ newFiles.push(file);
169
+ }
170
+ });
171
+ return newFiles;
172
+ };
173
+ exports.getMaximumCapacity = getMaximumCapacity;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "1.0.171",
3
+ "version": "1.0.172",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -575,5 +575,8 @@
575
575
  "Video": "Video",
576
576
  "Upload_local_video": "Upload_local_video",
577
577
  "The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
578
- "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page."
578
+ "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
579
+ "Link_to_page": "Link to page",
580
+ "No_page_results": "No page results",
581
+ "Page": "Page"
579
582
  }
@@ -575,5 +575,8 @@
575
575
  "Video": "Video",
576
576
  "Upload_local_video": "Upload_local_video",
577
577
  "The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
578
- "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page."
578
+ "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
579
+ "Link_to_page": "Link to page",
580
+ "No_page_results": "No page results",
581
+ "Page": "Page"
579
582
  }
@@ -575,5 +575,8 @@
575
575
  "Video": "Video",
576
576
  "Upload_local_video": "Upload_local_video",
577
577
  "The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
578
- "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page."
578
+ "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
579
+ "Link_to_page": "Link to page",
580
+ "No_page_results": "No page results",
581
+ "Page": "Page"
579
582
  }
@@ -575,5 +575,8 @@
575
575
  "Video": "Video",
576
576
  "Upload_local_video": "Upload_local_video",
577
577
  "The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
578
- "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page."
578
+ "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
579
+ "Link_to_page": "Link to page",
580
+ "No_page_results": "No page results",
581
+ "Page": "Page"
579
582
  }
@@ -575,5 +575,8 @@
575
575
  "Video": "Video",
576
576
  "Upload_local_video": "Upload_local_video",
577
577
  "The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
578
- "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page."
578
+ "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
579
+ "Link_to_page": "Link to page",
580
+ "No_page_results": "No page results",
581
+ "Page": "Page"
579
582
  }
@@ -575,5 +575,8 @@
575
575
  "Video": "Video",
576
576
  "Upload_local_video": "Upload_local_video",
577
577
  "The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
578
- "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page."
578
+ "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
579
+ "Link_to_page": "Link to page",
580
+ "No_page_results": "No page results",
581
+ "Page": "Page"
579
582
  }
@@ -575,5 +575,8 @@
575
575
  "Video": "Vidéo",
576
576
  "Upload_local_video": "Upload_local_video",
577
577
  "The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
578
- "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page."
578
+ "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
579
+ "Link_to_page": "Link to page",
580
+ "No_page_results": "No page results",
581
+ "Page": "Page"
579
582
  }
@@ -575,5 +575,8 @@
575
575
  "Video": "Video",
576
576
  "Upload_local_video": "Upload_local_video",
577
577
  "The_current_version_does_not_support_>5MB_video_file": "The_current_version_does_not_support_>5MB_video_file",
578
- "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page."
578
+ "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page.",
579
+ "Link_to_page": "Link to page",
580
+ "No_page_results": "No page results",
581
+ "Page": "Page"
579
582
  }
@@ -575,5 +575,8 @@
575
575
  "Video": "Видео",
576
576
  "Upload_local_video": "Загрузка_локального_видео",
577
577
  "The_current_version_does_not_support_>5MB_video_file": "Текущая_версия_не_поддерживает_видео_файл_>5_МБ",
578
- "Token_expired_Please_refresh_the_page": "Token expired. Please refresh the page."
578
+ "Token_expired_Please_refresh_the_page": "Срок действия токена истек. Обновите страницу.",
579
+ "Link_to_page": "Ссылка на страницу",
580
+ "No_page_results": "No page results",
581
+ "Page": "Page"
579
582
  }
@@ -247,7 +247,7 @@
247
247
  "Server_is_disconnected_Reconnecting": "服务器断开连接。正在重新连接...",
248
248
  "Server_is_reconnected": "服务器已重新连接。",
249
249
  "Outline": "目录",
250
- "Headings_you_add_to_the_document_will_appear_here": "您添加到文档中的标题将显示在此处",
250
+ "Headings_you_add_to_the_document_will_appear_here": "你添加到文档中的标题将显示在此处",
251
251
  "Open_parent_folder": "打开父目录",
252
252
  "Redo": "重做",
253
253
  "Undo": "撤销",
@@ -575,5 +575,8 @@
575
575
  "Video": "视频",
576
576
  "Upload_local_video": "上传本地视频",
577
577
  "The_current_version_does_not_support_>5MB_video_file": "当前版本不支持大于 5MB 的视频文件",
578
- "Token_expired_Please_refresh_the_page": "Token已过期。请刷新页面。"
578
+ "Token_expired_Please_refresh_the_page": "Token已过期。请刷新页面。",
579
+ "Link_to_page": "链接到页面",
580
+ "No_page_results": "没有页面结果",
581
+ "Page": "页面"
579
582
  }