@seafile/sdoc-editor 0.2.20 → 0.2.23
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/api/seafile-api.js +55 -0
- package/dist/basic-sdk/assets/css/sdoc-editor-plugins.css +2 -2
- package/dist/basic-sdk/extension/plugins/image/render-elem.js +14 -32
- package/dist/basic-sdk/extension/toolbar/side-toolbar/side-menu.js +23 -0
- package/dist/basic-sdk/outline/index.js +1 -1
- package/dist/basic-sdk/outline/outline-item.js +1 -1
- package/dist/components/doc-operations/index.js +2 -1
- package/dist/components/doc-operations/tag-operation/constans.js +2 -0
- package/dist/components/doc-operations/tag-operation/index.js +11 -0
- package/dist/components/doc-operations/tag-operation/tag-popover/index.css +70 -0
- package/dist/components/doc-operations/tag-operation/tag-popover/index.js +251 -0
- package/dist/components/doc-operations/tag-operation/utils.js +8 -0
- package/dist/context.js +54 -0
- package/dist/layout/layout.js +11 -1
- package/package.json +1 -1
- package/public/locales/cs/sdoc-editor.json +29 -15
- package/public/locales/de/sdoc-editor.json +29 -15
- package/public/locales/en/sdoc-editor.json +30 -15
- package/public/locales/es/sdoc-editor.json +29 -15
- package/public/locales/fr/sdoc-editor.json +29 -15
- package/public/locales/it/sdoc-editor.json +29 -15
- package/public/locales/ru/sdoc-editor.json +29 -15
- package/public/locales/zh_CN/sdoc-editor.json +30 -15
- package/public/media/sdoc-editor-font/iconfont.svg +0 -4
- package/public/media/sdoc-editor-font.css +0 -8
package/dist/api/seafile-api.js
CHANGED
|
@@ -187,6 +187,61 @@ var SeafileAPI = /*#__PURE__*/function () {
|
|
|
187
187
|
var url = 'api/v2.1/seadoc/related-users/' + docUuid + '/';
|
|
188
188
|
return this.req.get(url);
|
|
189
189
|
}
|
|
190
|
+
|
|
191
|
+
// Operate file tags
|
|
192
|
+
}, {
|
|
193
|
+
key: "getFileTagList",
|
|
194
|
+
value: function getFileTagList(docUuid) {
|
|
195
|
+
var url = "/api/v2.1/seadoc/file-tags/".concat(docUuid, "/");
|
|
196
|
+
return this.req.get(url);
|
|
197
|
+
}
|
|
198
|
+
}, {
|
|
199
|
+
key: "addFileTag",
|
|
200
|
+
value: function addFileTag(docUuid, repoTagID) {
|
|
201
|
+
var form = new FormData();
|
|
202
|
+
form.append('repo_tag_id', repoTagID);
|
|
203
|
+
var url = "/api/v2.1/seadoc/file-tags/".concat(docUuid, "/");
|
|
204
|
+
return this._sendPostRequest(url, form);
|
|
205
|
+
}
|
|
206
|
+
}, {
|
|
207
|
+
key: "removeFileTag",
|
|
208
|
+
value: function removeFileTag(docUuid, fileTagID) {
|
|
209
|
+
var url = "/api/v2.1/seadoc/file-tags/".concat(docUuid, "/").concat(fileTagID, "/");
|
|
210
|
+
return this.req.delete(url);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Operate repository tags
|
|
214
|
+
}, {
|
|
215
|
+
key: "getRepoTagList",
|
|
216
|
+
value: function getRepoTagList(docUuid) {
|
|
217
|
+
var url = "/api/v2.1/seadoc/repo-tags/".concat(docUuid, "/");
|
|
218
|
+
return this.req.get(url);
|
|
219
|
+
}
|
|
220
|
+
}, {
|
|
221
|
+
key: "createRepoTag",
|
|
222
|
+
value: function createRepoTag(docUuid, repoTagName, color) {
|
|
223
|
+
var url = "/api/v2.1/seadoc/repo-tags/".concat(docUuid, "/");
|
|
224
|
+
var form = new FormData();
|
|
225
|
+
form.append('name', repoTagName);
|
|
226
|
+
form.append('color', color);
|
|
227
|
+
return this._sendPostRequest(url, form);
|
|
228
|
+
}
|
|
229
|
+
}, {
|
|
230
|
+
key: "removeRepoTag",
|
|
231
|
+
value: function removeRepoTag(docUuid, repoTagId) {
|
|
232
|
+
var url = "/api/v2.1/seadoc/repo-tags/".concat(docUuid, "/").concat(repoTagId, "/");
|
|
233
|
+
return this.req.delete(url);
|
|
234
|
+
}
|
|
235
|
+
}, {
|
|
236
|
+
key: "updateRepoTag",
|
|
237
|
+
value: function updateRepoTag(docUuid, repoTagId, repoTagName, color) {
|
|
238
|
+
var url = "/api/v2.1/seadoc/repo-tags/".concat(docUuid, "/").concat(repoTagId, "/");
|
|
239
|
+
var params = {
|
|
240
|
+
name: repoTagName,
|
|
241
|
+
color: color
|
|
242
|
+
};
|
|
243
|
+
return this.req.put(url, params);
|
|
244
|
+
}
|
|
190
245
|
}]);
|
|
191
246
|
return SeafileAPI;
|
|
192
247
|
}();
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
.sdoc-editor-container .article .sdoc-image-wrapper {
|
|
41
41
|
position: relative;
|
|
42
42
|
display: inline-block;
|
|
43
|
-
|
|
43
|
+
padding: 6px 6px 6px 0;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
.sdoc-editor-container .article .sdoc-image-inner {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
.sdoc-editor-container .article .sdoc-image-content {
|
|
52
52
|
display: flex;
|
|
53
53
|
flex-direction: column;
|
|
54
|
-
align-items: start;
|
|
54
|
+
align-items: flex-start;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
.sdoc-editor-container .article .sdoc-image-content :first-child {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
1
|
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
2
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
3
3
|
import React, { useState, useCallback, useRef, useEffect } from 'react';
|
|
4
4
|
import { ReactEditor, useSelected, useReadOnly } from '@seafile/slate-react';
|
|
5
5
|
import { Transforms } from '@seafile/slate';
|
|
@@ -16,6 +16,7 @@ import imagePlaceholder from '../../../assets/images/image-placeholder.png';
|
|
|
16
16
|
var Image = function Image(_ref) {
|
|
17
17
|
var element = _ref.element,
|
|
18
18
|
editor = _ref.editor,
|
|
19
|
+
style = _ref.style,
|
|
19
20
|
className = _ref.className,
|
|
20
21
|
attributes = _ref.attributes,
|
|
21
22
|
children = _ref.children,
|
|
@@ -26,11 +27,11 @@ var Image = function Image(_ref) {
|
|
|
26
27
|
align = element.align,
|
|
27
28
|
_element$border_type = element.border_type,
|
|
28
29
|
border_type = _element$border_type === void 0 ? IMAGE_BORDER_TYPE[0].type : _element$border_type;
|
|
29
|
-
var imageWrapStyle = {
|
|
30
|
+
var imageWrapStyle = _objectSpread(_objectSpread({}, style), {}, {
|
|
30
31
|
display: display_type === 'Block' ? 'block' : 'inline-block',
|
|
31
32
|
paddingTop: display_type === 'Block' ? '8px' : '',
|
|
32
33
|
textAlign: display_type === 'Block' ? align : ''
|
|
33
|
-
};
|
|
34
|
+
});
|
|
34
35
|
var imageStyle = {
|
|
35
36
|
border: IMAGE_BORDER_TYPE.find(function (item) {
|
|
36
37
|
return item.type === border_type;
|
|
@@ -213,7 +214,9 @@ var Image = function Image(_ref) {
|
|
|
213
214
|
}, [data, editor, element]);
|
|
214
215
|
return /*#__PURE__*/React.createElement(React.Fragment, null, isShowImagePlaceholder && /*#__PURE__*/React.createElement("span", Object.assign({
|
|
215
216
|
className: classNames('sdoc-image-wrapper', className)
|
|
216
|
-
}, attributes
|
|
217
|
+
}, attributes, {
|
|
218
|
+
style: imageWrapStyle
|
|
219
|
+
}), /*#__PURE__*/React.createElement("img", {
|
|
217
220
|
ref: imageRef,
|
|
218
221
|
src: imagePlaceholder,
|
|
219
222
|
style: getImageStyle(),
|
|
@@ -250,7 +253,7 @@ var Image = function Image(_ref) {
|
|
|
250
253
|
}, /*#__PURE__*/React.createElement("span", null, t('Width'), ':', parseInt(movingWidth || imageRef.current.clientWidth)), /*#__PURE__*/React.createElement("span", null, "\xA0\xA0"), /*#__PURE__*/React.createElement("span", null, t('Height'), ':', imageRef.current.clientHeight))), display_type === 'Block' && (isShowCaption || (data === null || data === void 0 ? void 0 : data.caption)) && /*#__PURE__*/React.createElement("input", {
|
|
251
254
|
className: "sdoc-image-caption-input-wrapper",
|
|
252
255
|
style: {
|
|
253
|
-
width: (data === null || data === void 0 ? void 0 : data.width) ||
|
|
256
|
+
width: (data === null || data === void 0 ? void 0 : data.width) || imageRef.current.clientWidth
|
|
254
257
|
},
|
|
255
258
|
placeholder: t('Insert_caption'),
|
|
256
259
|
value: caption,
|
|
@@ -281,36 +284,15 @@ function renderImage(props, editor) {
|
|
|
281
284
|
// decorate diff-viewer
|
|
282
285
|
var element = props.element,
|
|
283
286
|
leaf = props.leaf;
|
|
284
|
-
|
|
285
|
-
var style = element.ADD ? ADDED_STYLE : DELETED_STYLE;
|
|
286
|
-
return /*#__PURE__*/React.createElement("span", {
|
|
287
|
-
className: "d-inline-block p-1",
|
|
288
|
-
style: {
|
|
289
|
-
backgroundColor: style.computed_background_color,
|
|
290
|
-
width: 'fit-content',
|
|
291
|
-
height: 'fit-content'
|
|
292
|
-
}
|
|
293
|
-
}, /*#__PURE__*/React.createElement(SdocImage, Object.assign({}, props, {
|
|
294
|
-
className: classNames(props.className || '', 'm-0'),
|
|
295
|
-
editor: editor,
|
|
296
|
-
isSelected: isSelected
|
|
297
|
-
})));
|
|
298
|
-
}
|
|
287
|
+
var style = _objectSpread({}, props.style);
|
|
299
288
|
if (leaf && leaf.computed_background_color) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
width: 'fit-content',
|
|
305
|
-
height: 'fit-content'
|
|
306
|
-
}
|
|
307
|
-
}, /*#__PURE__*/React.createElement(SdocImage, Object.assign({}, props, {
|
|
308
|
-
className: classNames(props.className || '', 'm-0'),
|
|
309
|
-
editor: editor,
|
|
310
|
-
isSelected: isSelected
|
|
311
|
-
})));
|
|
289
|
+
style['backgroundColor'] = leaf.computed_background_color;
|
|
290
|
+
}
|
|
291
|
+
if (element.ADD || element.DELETE) {
|
|
292
|
+
style = Object.assign({}, style, element.ADD ? ADDED_STYLE : DELETED_STYLE);
|
|
312
293
|
}
|
|
313
294
|
return /*#__PURE__*/React.createElement(SdocImage, Object.assign({}, props, {
|
|
295
|
+
style: style,
|
|
314
296
|
editor: editor,
|
|
315
297
|
isSelected: isSelected
|
|
316
298
|
}));
|
|
@@ -2,6 +2,8 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
|
2
2
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
3
|
import { withTranslation } from 'react-i18next';
|
|
4
4
|
import { useSlateStatic } from '@seafile/slate-react';
|
|
5
|
+
import copy from 'copy-to-clipboard';
|
|
6
|
+
import context from '../../../../context';
|
|
5
7
|
import EventBus from '../../../utils/event-bus';
|
|
6
8
|
import { ElementPopover } from '../../commons';
|
|
7
9
|
import InsertBelowMenu from './insert-below-menu';
|
|
@@ -9,6 +11,8 @@ import InsertBlockMenu from './insert-block-menu';
|
|
|
9
11
|
import { onCopyNode, onDeleteNode, isNotSupportTransform } from './helpers';
|
|
10
12
|
import TransformMenus from './transform-menus';
|
|
11
13
|
import DropdownMenuItem from '../../commons/dropdown-menu-item';
|
|
14
|
+
import toaster from '../../../../components/toast';
|
|
15
|
+
import { HEADER1, HEADER2, HEADER3 } from '../../constants';
|
|
12
16
|
import './side-menu.css';
|
|
13
17
|
var SideMenu = function SideMenu(_ref) {
|
|
14
18
|
var slateNode = _ref.slateNode,
|
|
@@ -41,6 +45,17 @@ var SideMenu = function SideMenu(_ref) {
|
|
|
41
45
|
onDeleteNode(editor, slateNode);
|
|
42
46
|
onReset();
|
|
43
47
|
}, [editor, onReset, slateNode]);
|
|
48
|
+
var onCopyHeaderLink = useCallback(function () {
|
|
49
|
+
var serviceUrl = context.getSetting('serviceUrl');
|
|
50
|
+
var sdocUuid = context.getSetting('docUuid');
|
|
51
|
+
var href = serviceUrl + "/smart-link/".concat(sdocUuid, "/#").concat(slateNode.id);
|
|
52
|
+
copy(href);
|
|
53
|
+
toaster.success(t('Copied'), {
|
|
54
|
+
hasCloseButton: false,
|
|
55
|
+
duration: 2
|
|
56
|
+
});
|
|
57
|
+
onReset();
|
|
58
|
+
}, [onReset, slateNode.id, t]);
|
|
44
59
|
useEffect(function () {
|
|
45
60
|
var top = menuPosition.top;
|
|
46
61
|
if (sideMenuRef.current) {
|
|
@@ -87,6 +102,14 @@ var SideMenu = function SideMenu(_ref) {
|
|
|
87
102
|
slateNode: slateNode
|
|
88
103
|
})), /*#__PURE__*/React.createElement("div", {
|
|
89
104
|
className: "sdoc-dropdown-menu-divider"
|
|
105
|
+
}), [HEADER1, HEADER2, HEADER3].includes(slateNode === null || slateNode === void 0 ? void 0 : slateNode.type) && /*#__PURE__*/React.createElement(DropdownMenuItem, {
|
|
106
|
+
menuConfig: {
|
|
107
|
+
text: 'Copy_link_of_section',
|
|
108
|
+
iconClass: 'sdocfont sdoc-link'
|
|
109
|
+
},
|
|
110
|
+
onClick: onCopyHeaderLink
|
|
111
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
112
|
+
className: "sdoc-dropdown-menu-divider"
|
|
90
113
|
}), /*#__PURE__*/React.createElement(DropdownMenuItem, {
|
|
91
114
|
menuConfig: {
|
|
92
115
|
text: 'Copy',
|
|
@@ -61,7 +61,7 @@ var SDocOutline = function SDocOutline(_ref) {
|
|
|
61
61
|
onClick: toggleShow
|
|
62
62
|
})), list.length === 0 && /*#__PURE__*/React.createElement("p", {
|
|
63
63
|
className: "mt-4 text-secondary"
|
|
64
|
-
}, t('Headings_you_add_to_the_document_will_appear_here')), list.length > 0 && /*#__PURE__*/React.createElement("
|
|
64
|
+
}, t('Headings_you_add_to_the_document_will_appear_here')), list.length > 0 && /*#__PURE__*/React.createElement("div", {
|
|
65
65
|
className: "sdoc-outline-list-container"
|
|
66
66
|
}, list.map(function (item, index) {
|
|
67
67
|
return /*#__PURE__*/React.createElement(OutlineItem, {
|
|
@@ -43,7 +43,7 @@ var OutlineItem = /*#__PURE__*/function (_React$PureComponent) {
|
|
|
43
43
|
'pl-7': type === 'header3',
|
|
44
44
|
'active': isHighlighted
|
|
45
45
|
});
|
|
46
|
-
return /*#__PURE__*/React.createElement("
|
|
46
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
47
47
|
className: outlineItemClass,
|
|
48
48
|
onClick: this.onItemClick,
|
|
49
49
|
onMouseOver: this.onMouseOver,
|
|
@@ -7,6 +7,7 @@ import CollaboratorsOperation from './collaborators-operation';
|
|
|
7
7
|
import MoreOperations from './more-operations';
|
|
8
8
|
import CommentsOperation from './comments-operation';
|
|
9
9
|
import ShareOperation from './share-operation';
|
|
10
|
+
import TagOperation from './tag-operation';
|
|
10
11
|
import { isMobile } from '../../utils';
|
|
11
12
|
import './style.css';
|
|
12
13
|
var DocOperations = function DocOperations(_ref) {
|
|
@@ -28,6 +29,6 @@ var DocOperations = function DocOperations(_ref) {
|
|
|
28
29
|
changes: changes,
|
|
29
30
|
handleViewChangesToggle: handleViewChangesToggle,
|
|
30
31
|
handleRevisionPublished: handleRevisionPublished
|
|
31
|
-
}), !isPublished && /*#__PURE__*/React.createElement(CommentsOperation, null), !isSdocRevision && /*#__PURE__*/React.createElement(ShareOperation, null), /*#__PURE__*/React.createElement(HistoryOperation, null), !isPublished && /*#__PURE__*/React.createElement(CollaboratorsOperation, null), !isSdocRevision && /*#__PURE__*/React.createElement(MoreOperations, null));
|
|
32
|
+
}), !isPublished && /*#__PURE__*/React.createElement(TagOperation, null), !isPublished && /*#__PURE__*/React.createElement(CommentsOperation, null), !isSdocRevision && /*#__PURE__*/React.createElement(ShareOperation, null), /*#__PURE__*/React.createElement(HistoryOperation, null), !isPublished && /*#__PURE__*/React.createElement(CollaboratorsOperation, null), !isSdocRevision && /*#__PURE__*/React.createElement(MoreOperations, null));
|
|
32
33
|
};
|
|
33
34
|
export default withTranslation('sdoc-editor')(DocOperations);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import TagPopover from './tag-popover';
|
|
3
|
+
var TagOperation = function TagOperation() {
|
|
4
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
|
|
5
|
+
className: "op-item tag-operation-icon",
|
|
6
|
+
id: "tag-operation-icon-container"
|
|
7
|
+
}, /*#__PURE__*/React.createElement("i", {
|
|
8
|
+
className: "sdocfont sdoc-tag"
|
|
9
|
+
})), /*#__PURE__*/React.createElement(TagPopover, null));
|
|
10
|
+
};
|
|
11
|
+
export default TagOperation;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
.sdoc-tag-popover {
|
|
2
|
+
padding-bottom: 0;
|
|
3
|
+
width: 230px;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.sdoc-popover-container .sdoc-tag-search-input {
|
|
7
|
+
margin-bottom: 10px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.sdoc-popover-container .sdoc-tag-list-container {
|
|
11
|
+
max-height: 180px;
|
|
12
|
+
overflow-y: auto;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.sdoc-tag-item {
|
|
16
|
+
display: flex;
|
|
17
|
+
justify-content: space-between;
|
|
18
|
+
align-items: center;
|
|
19
|
+
padding: 3px 10px;
|
|
20
|
+
width: 100%;
|
|
21
|
+
height: 30px;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.sdoc-tag-item:hover {
|
|
26
|
+
background-color: #eee;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.sdoc-tag-item .sdoc-tag-badge-container {
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
width: 100%;
|
|
33
|
+
height: 100%;
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
text-overflow: ellipsis;
|
|
36
|
+
white-space: nowrap;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.sdoc-tag-item .sdoc-tag-badge {
|
|
40
|
+
margin-right: 10px;
|
|
41
|
+
text-overflow: ellipsis;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
font-size: 13px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.sdoc-tag-item .sdoc-tag-added-mark {
|
|
47
|
+
width: 18px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.sdoc-create-tag {
|
|
51
|
+
padding: 8px 10px;
|
|
52
|
+
border-top: 1px solid #eee;
|
|
53
|
+
border-bottom: none;
|
|
54
|
+
overflow: hidden;
|
|
55
|
+
text-overflow: ellipsis;
|
|
56
|
+
white-space: nowrap;
|
|
57
|
+
background-color: #fff;
|
|
58
|
+
font-weight: normal;
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.sdoc-create-tag:hover {
|
|
63
|
+
background-color: #f5f5f5;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.sdoc-create-tag .add-icon {
|
|
67
|
+
margin-right: 6px;
|
|
68
|
+
font-size: 13px;
|
|
69
|
+
font-weight: 600;
|
|
70
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
3
|
+
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(typeof e + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
4
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
|
+
import { Badge, Input, PopoverBody, PopoverHeader, UncontrolledPopover } from 'reactstrap';
|
|
6
|
+
import { useTranslation } from 'react-i18next';
|
|
7
|
+
import context from '../../../../context';
|
|
8
|
+
import { getErrorMsg } from '../../../../utils';
|
|
9
|
+
import toaster from '../../../toast';
|
|
10
|
+
import { generateTagColor, removeForwardSpace } from '../utils';
|
|
11
|
+
import './index.css';
|
|
12
|
+
var TagPopover = function TagPopover() {
|
|
13
|
+
var _useState = useState(''),
|
|
14
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
15
|
+
searchContent = _useState2[0],
|
|
16
|
+
setSearchContent = _useState2[1];
|
|
17
|
+
var _useState3 = useState([]),
|
|
18
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
19
|
+
tagList = _useState4[0],
|
|
20
|
+
setTagList = _useState4[1];
|
|
21
|
+
var tagListRef = useRef([]);
|
|
22
|
+
var _useTranslation = useTranslation(),
|
|
23
|
+
t = _useTranslation.t;
|
|
24
|
+
var isShowCreateTag = useMemo(function () {
|
|
25
|
+
var isInputTag = !!searchContent.length;
|
|
26
|
+
var isMathExistTag = tagList.some(function (item) {
|
|
27
|
+
return item.tag_name === searchContent;
|
|
28
|
+
});
|
|
29
|
+
return isInputTag && !isMathExistTag;
|
|
30
|
+
}, [searchContent, tagList]);
|
|
31
|
+
useEffect(function () {
|
|
32
|
+
getTagList();
|
|
33
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34
|
+
}, []);
|
|
35
|
+
var getFileTagList = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
36
|
+
var _yield$context$getFil, file_tags, errorMessage;
|
|
37
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
38
|
+
while (1) switch (_context.prev = _context.next) {
|
|
39
|
+
case 0:
|
|
40
|
+
_context.prev = 0;
|
|
41
|
+
_context.next = 3;
|
|
42
|
+
return context.getFileTagList();
|
|
43
|
+
case 3:
|
|
44
|
+
_yield$context$getFil = _context.sent;
|
|
45
|
+
file_tags = _yield$context$getFil.data.file_tags;
|
|
46
|
+
return _context.abrupt("return", file_tags);
|
|
47
|
+
case 8:
|
|
48
|
+
_context.prev = 8;
|
|
49
|
+
_context.t0 = _context["catch"](0);
|
|
50
|
+
errorMessage = getErrorMsg(_context.t0);
|
|
51
|
+
toaster.danger(t(errorMessage));
|
|
52
|
+
case 12:
|
|
53
|
+
case "end":
|
|
54
|
+
return _context.stop();
|
|
55
|
+
}
|
|
56
|
+
}, _callee, null, [[0, 8]]);
|
|
57
|
+
})), [t]);
|
|
58
|
+
|
|
59
|
+
// Get tag list and set fil_tag_id property when tag is attached on file
|
|
60
|
+
var getTagList = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
|
|
61
|
+
var _yield$context$getRep, repo_tags, fileTagList, errorMessage;
|
|
62
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
63
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
64
|
+
case 0:
|
|
65
|
+
_context2.prev = 0;
|
|
66
|
+
_context2.next = 3;
|
|
67
|
+
return context.getRepoTagList();
|
|
68
|
+
case 3:
|
|
69
|
+
_yield$context$getRep = _context2.sent;
|
|
70
|
+
repo_tags = _yield$context$getRep.data.repo_tags;
|
|
71
|
+
_context2.next = 7;
|
|
72
|
+
return getFileTagList();
|
|
73
|
+
case 7:
|
|
74
|
+
fileTagList = _context2.sent;
|
|
75
|
+
// Add file_tag_id property to tag,to mark which tag is added on file
|
|
76
|
+
repo_tags.forEach(function (item) {
|
|
77
|
+
var _matchFileTag$file_ta;
|
|
78
|
+
var matchFileTag = fileTagList.find(function (fileTag) {
|
|
79
|
+
return fileTag.repo_tag_id === item.repo_tag_id;
|
|
80
|
+
});
|
|
81
|
+
item.file_tag_id = (_matchFileTag$file_ta = matchFileTag === null || matchFileTag === void 0 ? void 0 : matchFileTag.file_tag_id) !== null && _matchFileTag$file_ta !== void 0 ? _matchFileTag$file_ta : null;
|
|
82
|
+
});
|
|
83
|
+
setTagList(repo_tags);
|
|
84
|
+
tagListRef.current = repo_tags;
|
|
85
|
+
_context2.next = 17;
|
|
86
|
+
break;
|
|
87
|
+
case 13:
|
|
88
|
+
_context2.prev = 13;
|
|
89
|
+
_context2.t0 = _context2["catch"](0);
|
|
90
|
+
errorMessage = getErrorMsg(_context2.t0);
|
|
91
|
+
toaster.danger(t(errorMessage));
|
|
92
|
+
case 17:
|
|
93
|
+
case "end":
|
|
94
|
+
return _context2.stop();
|
|
95
|
+
}
|
|
96
|
+
}, _callee2, null, [[0, 13]]);
|
|
97
|
+
})), [getFileTagList, t]);
|
|
98
|
+
|
|
99
|
+
// Create tag and add tag on file,then update tag list and clean search content
|
|
100
|
+
// Note: Here we remove the spaces at the beginning and end of the string
|
|
101
|
+
var handleCreateTag = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
|
|
102
|
+
var tagColor, _yield$context$create, repo_tag, errorMessage;
|
|
103
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
104
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
105
|
+
case 0:
|
|
106
|
+
_context3.prev = 0;
|
|
107
|
+
tagColor = generateTagColor();
|
|
108
|
+
_context3.next = 4;
|
|
109
|
+
return context.createRepoTag(searchContent.trim(), tagColor);
|
|
110
|
+
case 4:
|
|
111
|
+
_yield$context$create = _context3.sent;
|
|
112
|
+
repo_tag = _yield$context$create.data.repo_tag;
|
|
113
|
+
_context3.next = 8;
|
|
114
|
+
return context.addFileTag(repo_tag.repo_tag_id);
|
|
115
|
+
case 8:
|
|
116
|
+
getTagList();
|
|
117
|
+
setSearchContent('');
|
|
118
|
+
_context3.next = 16;
|
|
119
|
+
break;
|
|
120
|
+
case 12:
|
|
121
|
+
_context3.prev = 12;
|
|
122
|
+
_context3.t0 = _context3["catch"](0);
|
|
123
|
+
errorMessage = getErrorMsg(_context3.t0);
|
|
124
|
+
toaster.danger(t(errorMessage));
|
|
125
|
+
case 16:
|
|
126
|
+
case "end":
|
|
127
|
+
return _context3.stop();
|
|
128
|
+
}
|
|
129
|
+
}, _callee3, null, [[0, 12]]);
|
|
130
|
+
})), [getTagList, searchContent, t]);
|
|
131
|
+
var matchTag = useCallback(function (matchText) {
|
|
132
|
+
if (matchText.length) {
|
|
133
|
+
var filterTagList = tagListRef.current.filter(function (_ref4) {
|
|
134
|
+
var tag_name = _ref4.tag_name;
|
|
135
|
+
return tag_name.indexOf(matchText) !== -1;
|
|
136
|
+
});
|
|
137
|
+
setTagList(filterTagList);
|
|
138
|
+
} else {
|
|
139
|
+
setTagList(tagListRef.current);
|
|
140
|
+
}
|
|
141
|
+
}, []);
|
|
142
|
+
|
|
143
|
+
// Handle input change and match tag showing in popover
|
|
144
|
+
// Note: The input value is not allowed to start with a space,but it can contain spaces in the middle or at the end
|
|
145
|
+
var handleInputChange = useCallback(function (e) {
|
|
146
|
+
var text = e.target.value ??= '';
|
|
147
|
+
var inputText = removeForwardSpace(text).slice(0, 100);
|
|
148
|
+
matchTag(inputText);
|
|
149
|
+
setSearchContent(inputText);
|
|
150
|
+
}, [matchTag]);
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @param {string} repoTagID
|
|
154
|
+
* @param {number | null} file_tag_id
|
|
155
|
+
*/
|
|
156
|
+
var handleClickTag = useCallback( /*#__PURE__*/function () {
|
|
157
|
+
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(repoTagID, file_tag_id) {
|
|
158
|
+
var errorMessage;
|
|
159
|
+
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
160
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
161
|
+
case 0:
|
|
162
|
+
_context4.prev = 0;
|
|
163
|
+
if (!(file_tag_id !== null)) {
|
|
164
|
+
_context4.next = 6;
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
_context4.next = 4;
|
|
168
|
+
return context.removeFileTag(file_tag_id);
|
|
169
|
+
case 4:
|
|
170
|
+
_context4.next = 8;
|
|
171
|
+
break;
|
|
172
|
+
case 6:
|
|
173
|
+
_context4.next = 8;
|
|
174
|
+
return context.addFileTag(repoTagID);
|
|
175
|
+
case 8:
|
|
176
|
+
getTagList();
|
|
177
|
+
_context4.next = 15;
|
|
178
|
+
break;
|
|
179
|
+
case 11:
|
|
180
|
+
_context4.prev = 11;
|
|
181
|
+
_context4.t0 = _context4["catch"](0);
|
|
182
|
+
errorMessage = getErrorMsg(_context4.t0);
|
|
183
|
+
toaster.danger(t(errorMessage));
|
|
184
|
+
case 15:
|
|
185
|
+
case "end":
|
|
186
|
+
return _context4.stop();
|
|
187
|
+
}
|
|
188
|
+
}, _callee4, null, [[0, 11]]);
|
|
189
|
+
}));
|
|
190
|
+
return function (_x, _x2) {
|
|
191
|
+
return _ref5.apply(this, arguments);
|
|
192
|
+
};
|
|
193
|
+
}(), [getTagList, t]);
|
|
194
|
+
return /*#__PURE__*/React.createElement(UncontrolledPopover, {
|
|
195
|
+
target: "tag-operation-icon-container",
|
|
196
|
+
placement: "bottom-end",
|
|
197
|
+
popperClassName: "sdoc-menu-popover sdoc-dropdown-menu sdoc-tag-popover",
|
|
198
|
+
trigger: "legacy",
|
|
199
|
+
hideArrow: true,
|
|
200
|
+
fade: false,
|
|
201
|
+
security: "fixed"
|
|
202
|
+
}, /*#__PURE__*/React.createElement(PopoverBody, {
|
|
203
|
+
className: "sdoc-popover-container"
|
|
204
|
+
}, /*#__PURE__*/React.createElement(Input, {
|
|
205
|
+
value: searchContent,
|
|
206
|
+
onChange: handleInputChange,
|
|
207
|
+
placeholder: t('Find_an_option'),
|
|
208
|
+
maxLength: 100,
|
|
209
|
+
className: "sdoc-tag-search-input",
|
|
210
|
+
bsSize: "sm",
|
|
211
|
+
autoFocus: true
|
|
212
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
213
|
+
className: "sdoc-tag-list-container"
|
|
214
|
+
}, tagList.length ? tagList.map(function (item) {
|
|
215
|
+
return /*#__PURE__*/React.createElement(TagItem, Object.assign({
|
|
216
|
+
key: item.repo_tag_id,
|
|
217
|
+
handleClickTag: handleClickTag
|
|
218
|
+
}, item));
|
|
219
|
+
}) : /*#__PURE__*/React.createElement("span", null, t('No_options_available')))), isShowCreateTag && /*#__PURE__*/React.createElement(PopoverHeader, {
|
|
220
|
+
className: "sdoc-create-tag",
|
|
221
|
+
onClick: handleCreateTag
|
|
222
|
+
}, /*#__PURE__*/React.createElement("i", {
|
|
223
|
+
className: "sdocfont sdoc-append add-icon"
|
|
224
|
+
}), "".concat(t('Add_option'), " '").concat(searchContent, "'")));
|
|
225
|
+
};
|
|
226
|
+
export default TagPopover;
|
|
227
|
+
var TagItem = function TagItem(_ref6) {
|
|
228
|
+
var repo_tag_id = _ref6.repo_tag_id,
|
|
229
|
+
tag_color = _ref6.tag_color,
|
|
230
|
+
tag_name = _ref6.tag_name,
|
|
231
|
+
handleClickTag = _ref6.handleClickTag,
|
|
232
|
+
file_tag_id = _ref6.file_tag_id;
|
|
233
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
234
|
+
className: "sdoc-tag-item",
|
|
235
|
+
onClick: function onClick() {
|
|
236
|
+
return handleClickTag(repo_tag_id, file_tag_id);
|
|
237
|
+
}
|
|
238
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
239
|
+
className: "sdoc-tag-badge-container"
|
|
240
|
+
}, /*#__PURE__*/React.createElement(Badge, {
|
|
241
|
+
style: {
|
|
242
|
+
backgroundColor: tag_color
|
|
243
|
+
},
|
|
244
|
+
className: "sdoc-tag-badge",
|
|
245
|
+
pill: true
|
|
246
|
+
}, tag_name)), /*#__PURE__*/React.createElement("div", {
|
|
247
|
+
className: "sdoc-tag-added-mark"
|
|
248
|
+
}, file_tag_id !== null && /*#__PURE__*/React.createElement("i", {
|
|
249
|
+
className: "sdocfont sdoc-check-mark"
|
|
250
|
+
})));
|
|
251
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TAG_COLORS } from './constans';
|
|
2
|
+
var generateTagColor = function generateTagColor() {
|
|
3
|
+
return TAG_COLORS[Math.floor(Math.random() * TAG_COLORS.length)];
|
|
4
|
+
};
|
|
5
|
+
var removeForwardSpace = function removeForwardSpace(str) {
|
|
6
|
+
return str.replace(/^\s+/, '');
|
|
7
|
+
};
|
|
8
|
+
export { generateTagColor, removeForwardSpace };
|