@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.
@@ -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
- margin: 0 3px;
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), /*#__PURE__*/React.createElement("img", {
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) || '120px'
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
- if (element.ADD || element.DELETE) {
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
- return /*#__PURE__*/React.createElement("span", {
301
- className: "d-inline-block p-1",
302
- style: {
303
- backgroundColor: leaf.computed_background_color,
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("ol", {
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("li", {
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,2 @@
1
+ var TAG_COLORS = ['#FBD44A', '#EAA775', '#F4667C', '#DC82D2', '#9860E5', '#9F8CF1', '#59CB74', '#ADDF84', '#89D2EA', '#4ECCCB', '#46A1FD', '#C2C2C2'];
2
+ export { TAG_COLORS };
@@ -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 };