@seafile/sdoc-editor 1.0.162 → 1.0.163-alpha.2

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.
@@ -121,6 +121,10 @@ class SeafileAPI {
121
121
  const url = 'api/v2.1/seadoc/dir/' + docUuid + '/?p=' + p + '&type=' + type + '&doc_uuid=' + docUuid;
122
122
  return this.req.get(url);
123
123
  }
124
+ getSearchByFilename(docUuid, query, page, per_page, search_type) {
125
+ const url = 'api/v2.1/seadoc/search-filename/' + docUuid + '/?query=' + query + '&page=' + page + '&per_page=' + per_page + '&search_type=' + search_type;
126
+ return this.req.get(url);
127
+ }
124
128
  getSdocFileId(docUuid, p) {
125
129
  const url = 'api/v2.1/seadoc/file-uuid/' + docUuid + '/?p=' + p;
126
130
  return this.req.get(url);
@@ -177,6 +181,7 @@ class SeafileAPI {
177
181
 
178
182
  // notification
179
183
  listUnseenNotifications(docUuid) {
184
+ console.log(11111);
180
185
  const url = `/api/v2.1/seadoc/notifications/${docUuid}/`;
181
186
  return this.req.get(url);
182
187
  }
@@ -18,3 +18,71 @@
18
18
  background-color: #FF8000;
19
19
  border-color: #FF8000;
20
20
  }
21
+
22
+ .modal-header-container {
23
+ display: flex;
24
+ position: relative;
25
+ justify-content: space-between;
26
+ align-items: center;
27
+ width: 100%;
28
+ height: 60px;
29
+ padding: 10px;
30
+ }
31
+
32
+ .modal-title-container {
33
+ flex: 1;
34
+ text-align: center;
35
+ }
36
+
37
+ .search-container {
38
+ display: flex;
39
+ align-items: center;
40
+ position: absolute;
41
+ right: 40px;
42
+ top: 55%;
43
+ transform: translateY(-50%);
44
+ gap: 8px;
45
+ }
46
+
47
+ .sdoc-files-search-popover{
48
+ font-size: 14px;
49
+ padding: 1.5px 5px;
50
+ }
51
+
52
+ .sdoc-files-search-popover:hover{
53
+ background-color: #F2F2F2;
54
+ border-radius: 2px;
55
+ }
56
+
57
+ .sdoc-files-search-popover-container {
58
+ display: flex;
59
+ justify-content: center;
60
+ align-items: center;
61
+ width: 200px;
62
+ margin-right: 10px;
63
+ }
64
+
65
+ .sdoc-search-wrapper{
66
+ position: relative;
67
+ display: flex;
68
+ align-items: center;
69
+ width: 100%;
70
+ height: 40px;
71
+ }
72
+
73
+ .sdoc-search-input{
74
+ flex: 1;
75
+ padding: 0 25px;
76
+ }
77
+
78
+ .sdoc-files-search-popover-container .sdoc-search{
79
+ position: absolute;
80
+ left: 6px;
81
+ font-size: 14px;
82
+ }
83
+
84
+ .sdoc-files-search-popover-container .sdoc-close{
85
+ position: absolute;
86
+ right: 10px;
87
+ font-size: 10px;
88
+ }
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "__esModule", {
8
8
  exports.default = void 0;
9
9
  var _react = _interopRequireWildcard(require("react"));
10
10
  var _reactstrap = require("reactstrap");
11
+ var _isHotkey = _interopRequireDefault(require("is-hotkey"));
11
12
  var _reactI18next = require("react-i18next");
12
13
  var _context = _interopRequireDefault(require("../../../../context"));
13
14
  var _localFiles = _interopRequireDefault(require("./local-files"));
@@ -27,6 +28,9 @@ const SelectSdocFileDialog = _ref => {
27
28
  t
28
29
  } = (0, _reactI18next.useTranslation)();
29
30
  const [currentSelectedFile, setCurrentSelectedFile] = (0, _react.useState)(null);
31
+ const [temSearchContent, setTemSearchContent] = (0, _react.useState)('');
32
+ const [searchContent, setSearchContent] = (0, _react.useState)('');
33
+ const [isOpenSearch, setIsOpenSearch] = (0, _react.useState)(false);
30
34
  const onSelectedFile = (0, _react.useCallback)(fileInfo => {
31
35
  setCurrentSelectedFile(fileInfo);
32
36
  }, []);
@@ -70,6 +74,30 @@ const SelectSdocFileDialog = _ref => {
70
74
  closeDialog();
71
75
  // eslint-disable-next-line react-hooks/exhaustive-deps
72
76
  }, [currentSelectedFile]);
77
+ const toggleSearch = (0, _react.useCallback)(() => {
78
+ setIsOpenSearch(prev => !prev);
79
+ }, []);
80
+ const handleSearchInputChange = (0, _react.useCallback)(e => {
81
+ const keyword = e.target.value.toLowerCase();
82
+ setTemSearchContent(keyword);
83
+ }, []);
84
+ const executeSearch = (0, _react.useCallback)(() => {
85
+ if (!temSearchContent.trim()) {
86
+ return;
87
+ }
88
+ setSearchContent(temSearchContent);
89
+ }, [temSearchContent]);
90
+ const handleInputKeyDown = (0, _react.useCallback)(e => {
91
+ if ((0, _isHotkey.default)('enter', e)) {
92
+ e.preventDefault();
93
+ executeSearch();
94
+ }
95
+ if ((0, _isHotkey.default)('escape', e)) {
96
+ e.preventDefault();
97
+ e.stopPropagation();
98
+ setIsOpenSearch(!isOpenSearch);
99
+ }
100
+ }, [executeSearch, isOpenSearch]);
73
101
  return /*#__PURE__*/_react.default.createElement(_reactstrap.Modal, {
74
102
  toggle: closeDialog,
75
103
  isOpen: true,
@@ -79,15 +107,41 @@ const SelectSdocFileDialog = _ref => {
79
107
  className: "sdoc-file-select-dialog",
80
108
  contentClassName: "sdoc-file-select-modal"
81
109
  }, /*#__PURE__*/_react.default.createElement(_reactstrap.ModalHeader, {
110
+ className: "modal-header-container",
82
111
  toggle: closeDialog
83
- }, t(modalTitle)), /*#__PURE__*/_react.default.createElement(_reactstrap.ModalBody, {
112
+ }, /*#__PURE__*/_react.default.createElement("div", {
113
+ className: "modal-title-container"
114
+ }, t(modalTitle)), /*#__PURE__*/_react.default.createElement("div", {
115
+ className: "search-container"
116
+ }, !isOpenSearch && /*#__PURE__*/_react.default.createElement("div", {
117
+ className: "sdocfont sdoc-find-replace sdoc-files-search-popover",
118
+ onClick: toggleSearch
119
+ }), isOpenSearch && /*#__PURE__*/_react.default.createElement("div", {
120
+ className: "sdoc-files-search-popover-container"
121
+ }, /*#__PURE__*/_react.default.createElement("div", {
122
+ className: "sdoc-search-wrapper"
123
+ }, /*#__PURE__*/_react.default.createElement("div", {
124
+ className: "sdocfont sdoc-find-replace sdoc-search",
125
+ onClick: executeSearch
126
+ }), /*#__PURE__*/_react.default.createElement(_reactstrap.Input, {
127
+ autoFocus: true,
128
+ className: "sdoc-search-input",
129
+ onKeyUp: handleInputKeyDown,
130
+ onChange: handleSearchInputChange,
131
+ id: "sdoc-search",
132
+ placeholder: t('Search')
133
+ }), /*#__PURE__*/_react.default.createElement("div", {
134
+ className: "sdocfont sdoc-sm-close sdoc-close",
135
+ onClick: toggleSearch
136
+ }))))), /*#__PURE__*/_react.default.createElement(_reactstrap.ModalBody, {
84
137
  className: "p-0"
85
138
  }, /*#__PURE__*/_react.default.createElement("div", {
86
139
  className: "sdoc-file-select-container"
87
140
  }, /*#__PURE__*/_react.default.createElement(_localFiles.default, {
88
141
  fileType: _constants.FILE_TYPE[dialogType],
89
142
  onSelectedFile: onSelectedFile,
90
- toggle: closeDialog
143
+ toggle: closeDialog,
144
+ searchContent: searchContent
91
145
  }), /*#__PURE__*/_react.default.createElement("div", {
92
146
  className: "sdoc-file-select-footer"
93
147
  }, /*#__PURE__*/_react.default.createElement(_reactstrap.Button, {
@@ -20,7 +20,8 @@ const LocalFiles = _ref => {
20
20
  onSelectedFile,
21
21
  toggle,
22
22
  fileType,
23
- t
23
+ t,
24
+ searchContent
24
25
  } = _ref;
25
26
  const folderRef = (0, _react.useRef)(null);
26
27
  const [expandedFolder, setExpandedFolder] = (0, _react.useState)(new Set([]));
@@ -41,11 +42,14 @@ const LocalFiles = _ref => {
41
42
  // eslint-disable-next-line react-hooks/exhaustive-deps
42
43
  }, []);
43
44
  const getTreeData = (0, _react.useCallback)((p, indexId, treeData) => {
44
- return _context.default.getSdocLocalFiles(p, fileType).then(res => {
45
+ console.log(p);
46
+ // return context.getSdocLocalFiles(p, fileType).then(res => {
47
+ return _context.default.getSearchFilesByFilename('10', '1', '10', 'sdoc').then(res => {
45
48
  res.data.forEach(item => {
46
49
  item.indexId = _slugid.default.nice();
47
50
  });
48
51
  // Open folder
52
+ // console.log(3, res.data);
49
53
  if (indexId && treeData.length > 0) {
50
54
  const newFileListData = (0, _helpers.addDataToTree)(treeData, indexId, res.data, p);
51
55
  setTreeData([...newFileListData]);
@@ -69,6 +73,7 @@ const LocalFiles = _ref => {
69
73
  // eslint-disable-next-line react-hooks/exhaustive-deps
70
74
  }, []);
71
75
  const onToggle = (0, _react.useCallback)(async (e, item, treeData) => {
76
+ // console.log(2, e, item, treeData);
72
77
  e.stopPropagation();
73
78
  if (expandedFolder.has(item.indexId)) {
74
79
  collapsedFolder(treeData, item.indexId);
@@ -88,7 +93,39 @@ const LocalFiles = _ref => {
88
93
  onSelectedFile(file);
89
94
  // eslint-disable-next-line react-hooks/exhaustive-deps
90
95
  }, []);
96
+ const [filteredTreeData, setFilteredTreeData] = (0, _react.useState)([]);
97
+ (0, _react.useEffect)(() => {
98
+ const filterFiles = async data => {
99
+ const results = [];
100
+ for (const item of data) {
101
+ if (item.type === 'file' && item.name.includes(searchContent)) {
102
+ results.push(item);
103
+ } else if (item.type === 'dir') {
104
+ console.log(33, item);
105
+ const children = item.children || (await getTreeData(item.path, item.indexId, treeData));
106
+ if (children && Array.isArray(children)) {
107
+ const childResults = await filterFiles(children);
108
+ results.push({
109
+ ...item,
110
+ children: childResults
111
+ });
112
+ }
113
+ }
114
+ }
115
+ return results;
116
+ };
117
+ const updateFilteredData = async () => {
118
+ if (!searchContent.trim()) {
119
+ setFilteredTreeData(treeData);
120
+ } else {
121
+ const filtered = await filterFiles(treeData);
122
+ setFilteredTreeData(filtered);
123
+ }
124
+ };
125
+ updateFilteredData();
126
+ }, [searchContent, treeData]);
91
127
  const renderFileTree = (0, _react.useCallback)(data => {
128
+ // console.log(2, data);
92
129
  if (!Array.isArray(data) || data.length === 0) return null;
93
130
  return data.map(item => {
94
131
  var _item$children, _item$children2;
@@ -98,6 +135,7 @@ const LocalFiles = _ref => {
98
135
  indexId,
99
136
  name
100
137
  } = item;
138
+ // console.log(12, data, type, indexId, name);
101
139
  const selected = (currentActiveItem === null || currentActiveItem === void 0 ? void 0 : currentActiveItem.indexId) === indexId;
102
140
  return /*#__PURE__*/_react.default.createElement("div", {
103
141
  key: indexId,
@@ -146,6 +184,6 @@ const LocalFiles = _ref => {
146
184
  }, [treeData, currentActiveItem, expandedFolder]);
147
185
  return /*#__PURE__*/_react.default.createElement("div", {
148
186
  className: "sdoc-files-tree"
149
- }, renderFileTree(treeData));
187
+ }, renderFileTree(filteredTreeData));
150
188
  };
151
189
  var _default = exports.default = (0, _reactI18next.withTranslation)('sdoc-editor')(LocalFiles);
@@ -113,7 +113,9 @@ class Link extends _react.default.Component {
113
113
  className: className
114
114
  }, attributes), /*#__PURE__*/_react.default.createElement("a", {
115
115
  href: element.href,
116
- title: element.title
116
+ title: element.title,
117
+ target: "_blank",
118
+ rel: "noreferrer"
117
119
  }, children));
118
120
  }
119
121
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("span", Object.assign({
package/dist/context.js CHANGED
@@ -14,6 +14,7 @@ class Context {
14
14
  constructor() {
15
15
  (0, _defineProperty2.default)(this, "initSettings", () => {
16
16
  this.settings = window.seafile ? window.seafile : window.seafileConfig;
17
+ console.log(1, this.settings);
17
18
  const {
18
19
  name,
19
20
  username,
@@ -26,6 +27,7 @@ class Context {
26
27
  };
27
28
  this.user = new _model.User(userInfo);
28
29
  if (this.settings['isSdocRevision']) {
30
+ console.log(2);
29
31
  const repoID = this.getSetting('repoID');
30
32
  const siteRoot = this.getSetting('siteRoot');
31
33
  const originFilePath = this.getSetting('originFilePath');
@@ -61,6 +63,7 @@ class Context {
61
63
  const server = this.getSetting('serviceUrl');
62
64
  const token = this.getSetting('accessToken');
63
65
  this.api = new _seafileApi.default(server, token);
66
+ console.log(2, server, token, this.api);
64
67
  const isOpenSocket = this.getSetting('isOpenSocket');
65
68
  if (isOpenSocket) {
66
69
  this.sdocServerApi = new _sdocServerApi.default(this.settings);
@@ -197,7 +200,41 @@ class Context {
197
200
  // local files
198
201
  getSdocLocalFiles(p, type) {
199
202
  const docUuid = this.getSetting('docUuid');
200
- return this.api.getSdocFiles(docUuid, p, type);
203
+ const repoID = this.getSetting('repoID');
204
+ return this.api.getSdocFiles(docUuid, p, type, this.server);
205
+ }
206
+ getSearchFilesByFilename(query, page, per_page) {
207
+ const docUuid = this.getSetting('docUuid');
208
+ return this.api.searchSdocFiles(docUuid, query, page, per_page);
209
+ // return this.api.getSearchByFilename(docUuid, query, page, per_page, search_type);
210
+ }
211
+ listRepos(options) {
212
+ /*
213
+ * options: `{type: 'shared'}`, `{type: ['mine', 'shared', ...]}`
214
+ */
215
+ let url = this.server + '/api/v2.1/repos/';
216
+ if (!options) {
217
+ // fetch all types of repos
218
+ return this.req.get(url);
219
+ }
220
+ return this.req.get(url, {
221
+ params: options,
222
+ paramsSerializer: {
223
+ serialize: function (params) {
224
+ let list = [];
225
+ for (let key in params) {
226
+ if (Array.isArray(params[key])) {
227
+ for (let i = 0, len = params[key].length; i < len; i++) {
228
+ list.push(key + '=' + encodeURIComponent(params[key][i]));
229
+ }
230
+ } else {
231
+ list.push(key + '=' + encodeURIComponent(params[key]));
232
+ }
233
+ }
234
+ return list.join('&');
235
+ }
236
+ }
237
+ });
201
238
  }
202
239
  getSdocLocalFileId(p) {
203
240
  const docUuid = this.getSetting('docUuid');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seafile/sdoc-editor",
3
- "version": "1.0.162",
3
+ "version": "1.0.163-alpha.2",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",