@seafile/sdoc-editor 0.2.27 → 0.2.29-beta

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.
Files changed (68) hide show
  1. package/dist/api/seafile-api.js +26 -0
  2. package/dist/assets/images/content-replaced.png +0 -0
  3. package/dist/basic-sdk/comment/hooks/use-comment-mount.js +7 -0
  4. package/dist/basic-sdk/editor/sdoc-editor.js +2 -3
  5. package/dist/basic-sdk/extension/constants/element-type.js +3 -2
  6. package/dist/basic-sdk/extension/constants/index.js +2 -2
  7. package/dist/basic-sdk/extension/plugins/html/helper.js +17 -16
  8. package/dist/basic-sdk/extension/plugins/html/rules/blockquote.js +0 -1
  9. package/dist/basic-sdk/extension/plugins/html/rules/check-list.js +0 -2
  10. package/dist/basic-sdk/extension/plugins/html/rules/code-block.js +0 -10
  11. package/dist/basic-sdk/extension/plugins/html/rules/header.js +0 -1
  12. package/dist/basic-sdk/extension/plugins/html/rules/image.js +0 -1
  13. package/dist/basic-sdk/extension/plugins/html/rules/link.js +0 -2
  14. package/dist/basic-sdk/extension/plugins/html/rules/list.js +3 -9
  15. package/dist/basic-sdk/extension/plugins/html/rules/paragraph.js +0 -1
  16. package/dist/basic-sdk/extension/plugins/html/rules/table.js +0 -3
  17. package/dist/basic-sdk/extension/plugins/html/rules/text.js +0 -7
  18. package/dist/basic-sdk/extension/plugins/list/helpers.js +0 -1
  19. package/dist/basic-sdk/extension/plugins/list/model.js +3 -3
  20. package/dist/basic-sdk/extension/plugins/list/plugin/insert-fragment-list.js +4 -4
  21. package/dist/basic-sdk/extension/plugins/list/plugin/normalize-list.js +2 -13
  22. package/dist/basic-sdk/extension/plugins/list/transforms/insert-list-item.js +13 -11
  23. package/dist/basic-sdk/extension/plugins/list/transforms/move-list-items.js +2 -2
  24. package/dist/basic-sdk/extension/plugins/list/transforms/normalize-list-item.js +7 -7
  25. package/dist/basic-sdk/extension/plugins/list/transforms/toggle-list.js +16 -19
  26. package/dist/basic-sdk/extension/plugins/list/transforms/unwrap-list.js +5 -13
  27. package/dist/basic-sdk/extension/plugins/table/helpers.js +0 -1
  28. package/dist/basic-sdk/extension/render/custom-element.js +14 -14
  29. package/dist/basic-sdk/socket/socket-client.js +7 -0
  30. package/dist/basic-sdk/socket/socket-manager.js +3 -0
  31. package/dist/components/doc-operations/index.js +2 -1
  32. package/dist/components/doc-operations/notifications-operation/index.css +14 -0
  33. package/dist/components/doc-operations/notifications-operation/index.js +170 -0
  34. package/dist/components/doc-operations/notifications-operation/notifications-dialog/index.css +97 -0
  35. package/dist/components/doc-operations/notifications-operation/notifications-dialog/index.js +107 -0
  36. package/dist/components/doc-operations/notifications-operation/notifications-dialog/notification.js +25 -0
  37. package/dist/components/doc-operations/notifications-operation/notifications-popover/index.css +173 -0
  38. package/dist/components/doc-operations/notifications-operation/notifications-popover/index.js +78 -0
  39. package/dist/components/doc-operations/notifications-operation/notifications-popover/notification.js +54 -0
  40. package/dist/components/doc-operations/revision-operations/more-revision-operations/index.js +1 -2
  41. package/dist/components/doc-operations/tag-operation/tag-popover/index.css +1 -0
  42. package/dist/components/tip-dialog/index.css +44 -0
  43. package/dist/components/tip-dialog/index.js +51 -18
  44. package/dist/constants/index.js +2 -3
  45. package/dist/context.js +26 -0
  46. package/dist/layout/index.js +2 -1
  47. package/dist/layout/other.js +8 -0
  48. package/dist/model/index.js +2 -1
  49. package/dist/model/notification.js +21 -0
  50. package/dist/pages/published-revision-viewer.js +2 -2
  51. package/dist/pages/simple-editor.js +6 -6
  52. package/dist/utils/index.js +3 -33
  53. package/dist/utils/notification-utils.js +46 -0
  54. package/package.json +1 -1
  55. package/public/locales/cs/sdoc-editor.json +1 -1
  56. package/public/locales/de/sdoc-editor.json +1 -1
  57. package/public/locales/en/sdoc-editor.json +13 -3
  58. package/public/locales/es/sdoc-editor.json +1 -1
  59. package/public/locales/fr/sdoc-editor.json +1 -1
  60. package/public/locales/it/sdoc-editor.json +1 -1
  61. package/public/locales/ru/sdoc-editor.json +1 -1
  62. package/public/locales/zh_CN/sdoc-editor.json +4 -2
  63. package/public/media/sdoc-editor-font/iconfont.eot +0 -0
  64. package/public/media/sdoc-editor-font/iconfont.svg +2 -0
  65. package/public/media/sdoc-editor-font/iconfont.ttf +0 -0
  66. package/public/media/sdoc-editor-font/iconfont.woff +0 -0
  67. package/public/media/sdoc-editor-font/iconfont.woff2 +0 -0
  68. package/public/media/sdoc-editor-font.css +4 -0
@@ -2,15 +2,15 @@ import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIt
2
2
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
3
  import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
4
4
  import { Transforms, Editor, Path, Element } from '@seafile/slate';
5
- import { LIST_LIC } from '../../../constants';
5
+ import { PARAGRAPH } from '../../../constants';
6
6
  import { getChildren, getDeepInlineChildren, match } from '../../../core';
7
7
  import { getListTypes } from '../queries';
8
8
  import { movedListItemUp } from './move-list-item-up';
9
- import { generateEmptyListLic } from '../model';
9
+ import { generateEmptyListContent } from '../model';
10
10
  export var normalizeListItem = function normalizeListItem(editor, _ref) {
11
11
  var listItem = _ref.listItem;
12
12
  var changed = false;
13
- var validLiChildrenTypes = [].concat(_toConsumableArray(getListTypes()), [LIST_LIC]);
13
+ var validLiChildrenTypes = [].concat(_toConsumableArray(getListTypes()), [PARAGRAPH]);
14
14
  var _listItem = _slicedToArray(listItem, 2),
15
15
  liPath = _listItem[1];
16
16
  var liChildren = getChildren(listItem);
@@ -29,14 +29,14 @@ export var normalizeListItem = function normalizeListItem(editor, _ref) {
29
29
  firstLiChildNode = _ref7[0],
30
30
  firstLiChildPath = _ref7[1];
31
31
  if (!firstLiChild || !Editor.isBlock(editor, firstLiChildNode)) {
32
- var emptyLic = generateEmptyListLic();
33
- Transforms.insertNodes(editor, emptyLic, {
32
+ var itemContent = generateEmptyListContent();
33
+ Transforms.insertNodes(editor, itemContent, {
34
34
  at: liPath.concat([0])
35
35
  });
36
36
  return true;
37
37
  }
38
38
  if (Editor.isBlock(editor, firstLiChildNode) && !match(firstLiChildNode, [], {
39
- type: [LIST_LIC]
39
+ type: [PARAGRAPH]
40
40
  })) {
41
41
  if (match(firstLiChildNode, [], {
42
42
  type: getListTypes()
@@ -59,7 +59,7 @@ export var normalizeListItem = function normalizeListItem(editor, _ref) {
59
59
  return true;
60
60
  }
61
61
  Transforms.setNodes(editor, {
62
- type: LIST_LIC
62
+ type: PARAGRAPH
63
63
  }, {
64
64
  at: firstLiChildPath
65
65
  });
@@ -1,25 +1,23 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
3
  import { Node, Range, Transforms, Element, Editor } from '@seafile/slate';
4
- import { LIST_ITEM, LIST_LIC, PARAGRAPH, INSERT_POSITION } from '../../../constants';
5
- import { findNode, getNodeEntries, getNodeType, getSelectedNodeEntryByType, isRangeAcrossBlocks, generateEmptyElement } from '../../../core';
4
+ import { LIST_ITEM, PARAGRAPH, INSERT_POSITION } from '../../../constants';
5
+ import { findNode, getNodeEntries, getNodeType, getSelectedNodeEntryByType, isRangeAcrossBlocks } from '../../../core';
6
6
  import { getListItemEntry, getListTypes } from '../queries';
7
7
  import { unwrapList } from './unwrap-list';
8
- import { generateEmptyList, generateEmptyListItem } from '../model';
8
+ import { generateEmptyList, generateEmptyListContent, generateEmptyListItem } from '../model';
9
9
  var wrapLineList = function wrapLineList(editor, type) {
10
10
  var list = generateEmptyList(type);
11
11
  Transforms.wrapNodes(editor, list);
12
12
  var nodeEntry = getSelectedNodeEntryByType(editor, PARAGRAPH);
13
13
  if (!nodeEntry) return;
14
+
15
+ // select is paragraph
16
+ // 1 handle paragraph
17
+
18
+ // 2 wrap list_item
14
19
  var _nodeEntry = _slicedToArray(nodeEntry, 2),
15
- node = _nodeEntry[0],
16
20
  path = _nodeEntry[1];
17
- if (node.type !== LIST_LIC) {
18
- // paragraph to list-lic
19
- Transforms.setNodes(editor, {
20
- type: LIST_LIC
21
- });
22
- }
23
21
  var listItem = generateEmptyListItem();
24
22
  Transforms.wrapNodes(editor, listItem, {
25
23
  at: path
@@ -91,17 +89,16 @@ var wrapRangeList = function wrapRangeList(editor, type) {
91
89
  mode: 'all'
92
90
  });
93
91
  } else {
94
- if (![LIST_LIC].includes(n[0].type)) {
95
- Transforms.setNodes(editor, {
96
- type: LIST_LIC
97
- }, {
98
- at: n[1]
99
- });
100
- }
92
+ // select content is paragraph
93
+ // 1 handle content
94
+
95
+ // 2. wrap list_item
101
96
  var listItem = generateEmptyListItem();
102
97
  Transforms.wrapNodes(editor, listItem, {
103
98
  at: n[1]
104
99
  });
100
+
101
+ // 3. wrap list
105
102
  var list = generateEmptyList(type);
106
103
  Transforms.wrapNodes(editor, list, {
107
104
  at: n[1]
@@ -113,9 +110,9 @@ var wrapRangeList = function wrapRangeList(editor, type) {
113
110
  var toggleList = function toggleList(editor, type, insertPosition) {
114
111
  if (insertPosition === INSERT_POSITION.AFTER) {
115
112
  var list = generateEmptyList(type);
116
- var p = generateEmptyElement(PARAGRAPH);
113
+ var listContent = generateEmptyListContent();
117
114
  var path = Editor.path(editor, editor.selection);
118
- Transforms.insertNodes(editor, p, {
115
+ Transforms.insertNodes(editor, listContent, {
119
116
  at: [path[0] + 1]
120
117
  });
121
118
  Transforms.select(editor, [path[0] + 1]);
@@ -1,6 +1,6 @@
1
1
  import { Editor, Transforms, Element, Node } from '@seafile/slate';
2
- import { LIST_ITEM, LIST_LIC, PARAGRAPH } from '../../../constants';
3
- import { getAboveBlockNode, getAboveNode, getNodeType } from '../../../core';
2
+ import { LIST_ITEM } from '../../../constants';
3
+ import { getAboveNode, getNodeType } from '../../../core';
4
4
  import { getListTypes } from '../queries';
5
5
  export var unwrapList = function unwrapList(editor) {
6
6
  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
@@ -25,17 +25,7 @@ export var unwrapList = function unwrapList(editor) {
25
25
  };
26
26
  Editor.withoutNormalizing(editor, function () {
27
27
  do {
28
- var licEntry = getAboveBlockNode(editor, {
29
- at: at,
30
- match: {
31
- type: LIST_LIC
32
- }
33
- });
34
- if (licEntry) {
35
- Transforms.setNodes(editor, {
36
- type: PARAGRAPH
37
- });
38
- }
28
+ // unwrap list_item
39
29
  Transforms.unwrapNodes(editor, {
40
30
  at: at,
41
31
  match: function match(n) {
@@ -43,6 +33,8 @@ export var unwrapList = function unwrapList(editor) {
43
33
  },
44
34
  split: true
45
35
  });
36
+
37
+ // unwrap list
46
38
  Transforms.unwrapNodes(editor, {
47
39
  at: at,
48
40
  match: function match(n) {
@@ -31,7 +31,6 @@ export var isTableMenuDisabled = function isTableMenuDisabled(editor, readonly)
31
31
  if (type === ELEMENT_TYPE.UNORDERED_LIST) return true;
32
32
  if (type === ELEMENT_TYPE.BLOCKQUOTE) return true;
33
33
  if (type === ELEMENT_TYPE.LIST_ITEM) return true;
34
- if (type === ELEMENT_TYPE.LIST_LIC) return true;
35
34
  if (type === ELEMENT_TYPE.TABLE) return true;
36
35
  if (type === ELEMENT_TYPE.TABLE_CELL) return true;
37
36
  if (type === ELEMENT_TYPE.TABLE_ROW) return true;
@@ -2,7 +2,7 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
3
  import { useCallback } from 'react';
4
4
  import { useSlateStatic } from '@seafile/slate-react';
5
- import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, LIST_LIC, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, ELEMENT_TYPE, SDOC_LINK, FILE_LINK, TITLE, SUBTITLE } from '../constants';
5
+ import { BLOCKQUOTE, LINK, CHECK_LIST_ITEM, HEADER1, HEADER2, HEADER3, HEADER4, HEADER5, HEADER6, LIST_ITEM, ORDERED_LIST, PARAGRAPH, UNORDERED_LIST, CODE_BLOCK, CODE_LINE, IMAGE, ELEMENT_TYPE, SDOC_LINK, FILE_LINK, TITLE, SUBTITLE } from '../constants';
6
6
  import { BlockquotePlugin, LinkPlugin, CheckListPlugin, HeaderPlugin, ListPlugin, CodeBlockPlugin, ImagePlugin, TablePlugin, SdocLinkPlugin, ParagraphPlugin, FileLinkPlugin } from '../plugins';
7
7
  import EventBus from '../../utils/event-bus';
8
8
  import { INTERNAL_EVENT } from '../../constants';
@@ -19,9 +19,15 @@ var CustomRenderElement = function CustomRenderElement(props) {
19
19
  switch (element.type) {
20
20
  case PARAGRAPH:
21
21
  {
22
+ var parentNode = getParentNode(editor.children, element.id);
23
+ if (parentNode && parentNode.type === LIST_ITEM) {
24
+ var _ParagraphPlugin$rend = _slicedToArray(ParagraphPlugin.renderElements, 1),
25
+ _renderParagraph = _ParagraphPlugin$rend[0];
26
+ return _renderParagraph(props);
27
+ }
22
28
  attributes['onMouseEnter'] = onMouseEnter;
23
- var _ParagraphPlugin$rend = _slicedToArray(ParagraphPlugin.renderElements, 1),
24
- renderParagraph = _ParagraphPlugin$rend[0];
29
+ var _ParagraphPlugin$rend2 = _slicedToArray(ParagraphPlugin.renderElements, 1),
30
+ renderParagraph = _ParagraphPlugin$rend2[0];
25
31
  return renderParagraph(props);
26
32
  }
27
33
  case TITLE:
@@ -76,12 +82,6 @@ var CustomRenderElement = function CustomRenderElement(props) {
76
82
  renderListItem = _ListPlugin$renderEle2[1];
77
83
  return renderListItem(props, editor);
78
84
  }
79
- case LIST_LIC:
80
- {
81
- var _ListPlugin$renderEle3 = _slicedToArray(ListPlugin.renderElements, 3),
82
- renderListLic = _ListPlugin$renderEle3[2];
83
- return renderListLic(props, editor);
84
- }
85
85
  case CHECK_LIST_ITEM:
86
86
  {
87
87
  attributes['onMouseEnter'] = onMouseEnter;
@@ -105,8 +105,8 @@ var CustomRenderElement = function CustomRenderElement(props) {
105
105
  case IMAGE:
106
106
  {
107
107
  var _editor$element_comme;
108
- var parentNode = getParentNode(editor.children, element.id);
109
- var comments = ((_editor$element_comme = editor.element_comments_map) === null || _editor$element_comme === void 0 ? void 0 : _editor$element_comme[parentNode.id]) || [];
108
+ var _parentNode = getParentNode(editor.children, element.id);
109
+ var comments = ((_editor$element_comme = editor.element_comments_map) === null || _editor$element_comme === void 0 ? void 0 : _editor$element_comme[_parentNode.id]) || [];
110
110
  var unresolvedComments = comments && comments.filter(function (item) {
111
111
  return !item.resolved;
112
112
  });
@@ -153,9 +153,9 @@ var CustomRenderElement = function CustomRenderElement(props) {
153
153
  }
154
154
  default:
155
155
  {
156
- var _ParagraphPlugin$rend2 = _slicedToArray(ParagraphPlugin.renderElements, 1),
157
- _renderParagraph = _ParagraphPlugin$rend2[0];
158
- return _renderParagraph(props);
156
+ var _ParagraphPlugin$rend3 = _slicedToArray(ParagraphPlugin.renderElements, 1),
157
+ _renderParagraph2 = _ParagraphPlugin$rend3[0];
158
+ return _renderParagraph2(props);
159
159
  }
160
160
  }
161
161
  };
@@ -143,6 +143,10 @@ var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
143
143
  var socketManager = SocketManager.getInstance();
144
144
  socketManager.receiveRemoveDocumentError();
145
145
  };
146
+ this.receiveNewNotification = function (notification) {
147
+ var socketManager = SocketManager.getInstance();
148
+ socketManager.receiveNewNotification(notification);
149
+ };
146
150
  this.config = config;
147
151
  this.isReconnect = false;
148
152
  this.socket = io(config.sdocServer, {
@@ -170,6 +174,9 @@ var SocketClient = /*#__PURE__*/_createClass(function SocketClient(config) {
170
174
  this.socket.on('doc-removed', this.receiveRemoveDocument);
171
175
  this.socket.on('doc-removed-error', this.receiveRemoveDocumentError);
172
176
  this.socket.on('update-cursor', this.receiveCursorLocation);
177
+
178
+ // notification
179
+ this.socket.on('new-notification', this.receiveNewNotification);
173
180
  this.socket.io.on('reconnect', this.onReconnect);
174
181
  this.socket.io.on('reconnect_attempt', this.onReconnectAttempt);
175
182
  this.socket.io.on('reconnect_error', this.onReconnectError);
@@ -48,6 +48,9 @@ var SocketManager = /*#__PURE__*/_createClass(function SocketManager(editor, _do
48
48
  this.receiveDocumentReplacedError = function () {
49
49
  _this.eventBus.dispatch(EXTERNAL_EVENT.DOCUMENT_REPLACED_ERROR);
50
50
  };
51
+ this.receiveNewNotification = function (notification) {
52
+ _this.eventBus.dispatch(EXTERNAL_EVENT.NEW_NOTIFICATION, notification);
53
+ };
51
54
  this.onReceiveLocalOperations = function (operations) {
52
55
  _this.pendingOperationList.push(operations);
53
56
  var lastOpBeginTime = new Date().getTime();
@@ -9,6 +9,7 @@ import CommentsOperation from './comments-operation';
9
9
  import ShareOperation from './share-operation';
10
10
  import TagOperation from './tag-operation';
11
11
  import { isMobile } from '../../utils';
12
+ import NotificationOperation from './notifications-operation';
12
13
  import './style.css';
13
14
  var DocOperations = function DocOperations(_ref) {
14
15
  var isShowChanges = _ref.isShowChanges,
@@ -33,6 +34,6 @@ var DocOperations = function DocOperations(_ref) {
33
34
  handleViewChangesToggle: handleViewChangesToggle,
34
35
  handleRevisionMerged: handleRevisionMerged,
35
36
  handleRevisionPublished: handleRevisionPublished
36
- }), !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));
37
+ }), !isPublished && /*#__PURE__*/React.createElement(TagOperation, null), !isPublished && /*#__PURE__*/React.createElement(NotificationOperation, 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));
37
38
  };
38
39
  export default withTranslation('sdoc-editor')(DocOperations);
@@ -0,0 +1,14 @@
1
+ .sdoc-notification-icon-container .sdoc-notification-count {
2
+ position: absolute;
3
+ color: #fff;
4
+ font-size: 12px;
5
+ top: -7px;
6
+ right: -6px;
7
+ padding: 2px;
8
+ background: #fc6440;
9
+ border-radius: 50%;
10
+ min-width: 20px;
11
+ min-height: 20px;
12
+ transform: scale(.7);
13
+ text-align: center;
14
+ }
@@ -0,0 +1,170 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import React, { useCallback, useEffect, useState } from 'react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { EventBus } from '../../../basic-sdk';
5
+ import { EXTERNAL_EVENT } from '../../../constants';
6
+ import { createNotify, getErrorMsg } from '../../../utils';
7
+ import { useCollaborators } from '../../../hooks';
8
+ import context from '../../../context';
9
+ import { Notification } from '../../../model';
10
+ import NotificationPopover from './notifications-popover';
11
+ import AllNotificationsDialog from './notifications-dialog';
12
+ import toaster from '../../toast';
13
+ import './index.css';
14
+ var PER_PAGE = 25;
15
+ var NotificationOperation = function NotificationOperation() {
16
+ var _useState = useState([]),
17
+ _useState2 = _slicedToArray(_useState, 2),
18
+ notifications = _useState2[0],
19
+ setNotifications = _useState2[1];
20
+ var _useState3 = useState(true),
21
+ _useState4 = _slicedToArray(_useState3, 2),
22
+ hasMore = _useState4[0],
23
+ setHasMore = _useState4[1];
24
+ var _useState5 = useState(1),
25
+ _useState6 = _slicedToArray(_useState5, 2),
26
+ page = _useState6[0],
27
+ setPage = _useState6[1];
28
+ var _useState7 = useState(false),
29
+ _useState8 = _slicedToArray(_useState7, 2),
30
+ showNotificationsDialog = _useState8[0],
31
+ setShowNotificationsDialog = _useState8[1];
32
+ var _useTranslation = useTranslation(),
33
+ t = _useTranslation.t;
34
+ var _useCollaborators = useCollaborators(),
35
+ collaborators = _useCollaborators.collaborators;
36
+ var id = 'sdoc-notification';
37
+ var popupBrowserCommentNotification = useCallback(function (notification) {
38
+ if (!notification) return;
39
+ var author = notification.author,
40
+ msgType = notification.msg_type,
41
+ reply = notification.reply,
42
+ comment = notification.comment;
43
+ var authorInfo = collaborators.find(function (collaborator) {
44
+ return collaborator.email === author;
45
+ });
46
+ var notificationContent = comment || reply;
47
+ var titleKey = msgType === 'comment' ? 'xxx_added_a_new_comment' : 'xxx_added_a_reply';
48
+ var title = t(titleKey, {
49
+ author: authorInfo ? authorInfo.name : t('Unknown')
50
+ });
51
+ var options = {
52
+ body: "".concat(notificationContent)
53
+ };
54
+ createNotify(title, options);
55
+ }, [collaborators, t]);
56
+ var _listNotifications = useCallback(function (page) {
57
+ var perPage = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : PER_PAGE;
58
+ var forceAcquisition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
59
+ if (!forceAcquisition && !hasMore) return;
60
+ var newNotifications = page === 1 ? [] : notifications.slice(0);
61
+ context.listNotifications(page, perPage).then(function (res) {
62
+ var _res$data = res.data,
63
+ loadedNotifications = _res$data.notifications,
64
+ total_count = _res$data.total_count;
65
+ var hasMore = total_count > notifications.length + newNotifications.length;
66
+ loadedNotifications.forEach(function (n) {
67
+ var notification = new Notification(n);
68
+ newNotifications.push(notification);
69
+ });
70
+ setHasMore(hasMore);
71
+ setPage(page + 1);
72
+ setNotifications(newNotifications);
73
+ }).catch(function (error) {
74
+ var errMsg = getErrorMsg(error, true);
75
+ if (!error.response || error.response.status !== 403) {
76
+ toaster.danger(t(errMsg));
77
+ }
78
+ });
79
+ }, [notifications, hasMore, t]);
80
+ var onNewNotification = useCallback(function (notification) {
81
+ popupBrowserCommentNotification(notification);
82
+ _listNotifications(1, PER_PAGE, true);
83
+ }, [popupBrowserCommentNotification, _listNotifications]);
84
+ useEffect(function () {
85
+ _listNotifications(1, PER_PAGE);
86
+ // eslint-disable-next-line react-hooks/exhaustive-deps
87
+ }, []);
88
+ useEffect(function () {
89
+ var eventBus = EventBus.getInstance();
90
+ var unsubscribeNewNotification = eventBus.subscribe(EXTERNAL_EVENT.NEW_NOTIFICATION, onNewNotification);
91
+ return function () {
92
+ unsubscribeNewNotification();
93
+ };
94
+ }, [onNewNotification]);
95
+ var markAllNotificationsRead = useCallback(function () {
96
+ context.markAllNotificationsRead().then(function (res) {
97
+ var newNotifications = notifications.slice(0).map(function (n) {
98
+ n.seen = true;
99
+ return n;
100
+ });
101
+ setNotifications(newNotifications);
102
+ }).catch(function (error) {
103
+ var errMsg = getErrorMsg(error, true);
104
+ if (!error.response || error.response.status !== 403) {
105
+ toaster.danger(t(errMsg));
106
+ }
107
+ });
108
+ }, [notifications, t]);
109
+ var markNotificationRead = useCallback(function (notificationId) {
110
+ context.markNotificationRead(notificationId).then(function (res) {
111
+ var newNotifications = notifications.slice(0).map(function (n) {
112
+ if (n.id === notificationId) {
113
+ n.seen = true;
114
+ }
115
+ return n;
116
+ });
117
+ setNotifications(newNotifications);
118
+ }).catch(function (error) {
119
+ var errMsg = getErrorMsg(error, true);
120
+ if (!error.response || error.response.status !== 403) {
121
+ toaster.danger(t(errMsg));
122
+ }
123
+ });
124
+ }, [notifications, t]);
125
+ var deleteAllNotifications = useCallback(function () {
126
+ context.deleteAllNotifications().then(function (res) {
127
+ setNotifications([]);
128
+ setPage(1);
129
+ setHasMore(true);
130
+ }).catch(function (error) {
131
+ var errMsg = getErrorMsg(error);
132
+ if (!error.response || error.response.status !== 403) {
133
+ toaster.danger(t(errMsg));
134
+ }
135
+ });
136
+ }, [t]);
137
+ var toggleNotificationsDialog = useCallback(function () {
138
+ setShowNotificationsDialog(!showNotificationsDialog);
139
+ }, [showNotificationsDialog]);
140
+ var unreadNotificationsCount = notifications.filter(function (n) {
141
+ return !n.seen;
142
+ }).length;
143
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
144
+ className: "op-item sdoc-notification-icon-container",
145
+ id: id
146
+ }, /*#__PURE__*/React.createElement("i", {
147
+ className: "sdocfont sdoc-notification"
148
+ }), unreadNotificationsCount > 0 && /*#__PURE__*/React.createElement("span", {
149
+ className: "sdoc-notification-count"
150
+ }, unreadNotificationsCount)), /*#__PURE__*/React.createElement(NotificationPopover, {
151
+ target: id,
152
+ notifications: notifications,
153
+ listNotifications: function listNotifications() {
154
+ return _listNotifications(page, PER_PAGE);
155
+ },
156
+ markAllNotificationsRead: markAllNotificationsRead,
157
+ markNotificationRead: markNotificationRead,
158
+ onToggleNotificationsDialog: toggleNotificationsDialog
159
+ }), showNotificationsDialog && /*#__PURE__*/React.createElement(AllNotificationsDialog, {
160
+ notifications: notifications,
161
+ listNotifications: function listNotifications() {
162
+ return _listNotifications(page, PER_PAGE);
163
+ },
164
+ markNotificationRead: markNotificationRead,
165
+ markAllNotificationsRead: markAllNotificationsRead,
166
+ deleteAllNotifications: deleteAllNotifications,
167
+ toggle: toggleNotificationsDialog
168
+ }));
169
+ };
170
+ export default NotificationOperation;
@@ -0,0 +1,97 @@
1
+ .sdoc-all-notifications-dialog {
2
+ width: 720px;
3
+ max-width: 720px;
4
+ height: calc(100% - 56px);
5
+ }
6
+
7
+ .sdoc-all-notifications-dialog .modal-content {
8
+ height: 100%;
9
+ }
10
+
11
+ .sdoc-all-notifications-dialog .sdoc-notification-header-close {
12
+ display: flex;
13
+ }
14
+
15
+ .sdoc-all-notifications-dialog .sdoc-notification-dropdown-toggle {
16
+ display: flex;
17
+ justify-content: center;
18
+ align-items: center;
19
+ height: 24px;
20
+ width: 24px;
21
+ }
22
+
23
+ .sdoc-all-notifications-dialog .sdoc-notification-operation-btn {
24
+ height: 24px;
25
+ width: 24px;
26
+ display: flex;
27
+ align-items: center;
28
+ justify-content: center;
29
+ color: #000;
30
+ opacity: .5;
31
+ }
32
+
33
+ .sdoc-all-notifications-dialog .sdoc-notification-operation-btn:hover {
34
+ opacity: .75;
35
+ cursor: pointer;
36
+ }
37
+
38
+ .sdoc-all-notifications-dialog .sdoc-all-notifications-body {
39
+ height: 100%;
40
+ overflow: hidden;
41
+ padding: 0;
42
+ }
43
+
44
+ .sdoc-all-notifications-dialog .sdoc-all-notifications-container {
45
+ overflow: auto;
46
+ padding: 2rem 1rem;
47
+ height: 100%;
48
+ }
49
+
50
+ .sdoc-all-notifications-dialog .sdoc-all-notifications-container table {
51
+ width: 100%;
52
+ table-layout: fixed;
53
+ }
54
+
55
+ .sdoc-all-notifications-dialog .sdoc-all-notifications-container .sdoc-notifications-table-header-sm {
56
+ font-size: 13px;
57
+ }
58
+
59
+ .sdoc-all-notifications-dialog .sdoc-all-notifications-container table thead tr {
60
+ height: 2.1875rem;
61
+ }
62
+
63
+ .sdoc-all-notifications-dialog .sdoc-all-notifications-container table th {
64
+ padding: 0.3125rem 0.1875rem;
65
+ border-bottom: 1px solid #eee;
66
+ text-align: left;
67
+ font-weight: 400;
68
+ line-height: 1.6;
69
+ color: #9c9c9c;
70
+ }
71
+
72
+ .sdoc-all-notifications-dialog .sdoc-all-notifications-container table td {
73
+ padding: 0.5rem 0.1875rem;
74
+ border-bottom: 1px solid #eee;
75
+ color: #333;
76
+ font-size: 14px;
77
+ word-break: break-all;
78
+ }
79
+
80
+ .sdoc-all-notifications-dialog .sdoc-all-notifications-container table tbody tr:hover {
81
+ background: #f5f5f5;
82
+ cursor: pointer;
83
+ }
84
+
85
+ .sdoc-all-notifications-dialog .sdoc-empty-notifications-tip {
86
+ height: 100%;
87
+ width: 100%;
88
+ padding: 5.5em 1em;
89
+ border-radius: 3px;
90
+ background-color: #fff;
91
+ text-align: center;
92
+ }
93
+
94
+ .sdoc-all-notifications-dialog .sdoc-empty-notifications-tip .sdoc-empty-notifications-img-tip {
95
+ width: 100px;
96
+ height: 100px;
97
+ }
@@ -0,0 +1,107 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
+ import React, { useCallback, useState, useRef } from 'react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { Modal, ModalHeader, ModalBody, Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
5
+ import context from '../../../../context';
6
+ import Notification from './notification';
7
+ import './index.css';
8
+ var AllNotificationsDialog = function AllNotificationsDialog(_ref) {
9
+ var notifications = _ref.notifications,
10
+ toggle = _ref.toggle,
11
+ markAllNotificationsRead = _ref.markAllNotificationsRead,
12
+ deleteAllNotifications = _ref.deleteAllNotifications,
13
+ markNotificationRead = _ref.markNotificationRead,
14
+ listNotifications = _ref.listNotifications;
15
+ var _useTranslation = useTranslation(),
16
+ t = _useTranslation.t;
17
+ var _useState = useState(false),
18
+ _useState2 = _slicedToArray(_useState, 2),
19
+ isMenuShow = _useState2[0],
20
+ setMenuShow = _useState2[1];
21
+ var containerRef = useRef(null);
22
+ var tableRef = useRef(null);
23
+ var toggleMenu = useCallback(function () {
24
+ setMenuShow(!isMenuShow);
25
+ }, [isMenuShow]);
26
+ var onScroll = useCallback(function () {
27
+ if (containerRef.current.offsetHeight + containerRef.current.scrollTop + 1 >= tableRef.current.offsetHeight + 64) {
28
+ // 64 is padding height
29
+ listNotifications();
30
+ }
31
+ }, [listNotifications, containerRef, tableRef]);
32
+ var renderHeaderRowBtn = useCallback(function () {
33
+ return /*#__PURE__*/React.createElement("div", {
34
+ className: "sdoc-notification-header-close"
35
+ }, /*#__PURE__*/React.createElement(Dropdown, {
36
+ isOpen: isMenuShow,
37
+ toggle: toggleMenu
38
+ }, /*#__PURE__*/React.createElement(DropdownToggle, {
39
+ tag: "span",
40
+ "data-toggle": "dropdown",
41
+ "aria-expanded": isMenuShow,
42
+ className: "sdoc-notification-dropdown-toggle"
43
+ }, /*#__PURE__*/React.createElement("div", {
44
+ className: "sdoc-notification-operation-btn"
45
+ }, /*#__PURE__*/React.createElement("i", {
46
+ className: "sdocfont sdoc-more"
47
+ }))), /*#__PURE__*/React.createElement(DropdownMenu, {
48
+ right: true,
49
+ className: "sdoc-dropdown-menu large"
50
+ }, /*#__PURE__*/React.createElement(DropdownItem, {
51
+ className: "sdoc-dropdown-menu-item",
52
+ onClick: markAllNotificationsRead
53
+ }, t('Mark_all_as_read')), /*#__PURE__*/React.createElement(DropdownItem, {
54
+ className: "sdoc-dropdown-menu-item",
55
+ onClick: deleteAllNotifications
56
+ }, t('Delete_all_notifications')))), /*#__PURE__*/React.createElement("div", {
57
+ className: "sdoc-notification-operation-btn",
58
+ onClick: toggle
59
+ }, /*#__PURE__*/React.createElement("i", {
60
+ className: "sdocfont sdoc-sm-close"
61
+ })));
62
+ }, [deleteAllNotifications, isMenuShow, markAllNotificationsRead, t, toggle, toggleMenu]);
63
+ var renderNotifications = useCallback(function () {
64
+ if (!Array.isArray(notifications) || notifications.length === 0) {
65
+ var mediaUrl = context.getSetting('mediaUrl');
66
+ return /*#__PURE__*/React.createElement("div", {
67
+ className: "sdoc-empty-notifications-tip"
68
+ }, /*#__PURE__*/React.createElement("img", {
69
+ src: mediaUrl + 'img/no-items-tip.png',
70
+ className: "sdoc-empty-notifications-img-tip",
71
+ alt: ""
72
+ }), /*#__PURE__*/React.createElement("p", null, t('No_notification')));
73
+ }
74
+ return /*#__PURE__*/React.createElement("table", {
75
+ ref: tableRef
76
+ }, /*#__PURE__*/React.createElement("thead", {
77
+ className: "sdoc-notifications-table-header-sm"
78
+ }, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", {
79
+ width: "10%"
80
+ }), /*#__PURE__*/React.createElement("th", {
81
+ width: "70%"
82
+ }, t('News')), /*#__PURE__*/React.createElement("th", {
83
+ width: "20%"
84
+ }, t('Update_date')))), /*#__PURE__*/React.createElement("tbody", null, notifications.map(function (item) {
85
+ return /*#__PURE__*/React.createElement(Notification, {
86
+ key: item.id,
87
+ notification: item,
88
+ markNotificationRead: markNotificationRead
89
+ });
90
+ })));
91
+ }, [notifications, t, markNotificationRead]);
92
+ return /*#__PURE__*/React.createElement(Modal, {
93
+ isOpen: true,
94
+ toggle: toggle,
95
+ className: "sdoc-all-notifications-dialog"
96
+ }, /*#__PURE__*/React.createElement(ModalHeader, {
97
+ close: renderHeaderRowBtn(),
98
+ toggle: toggle
99
+ }, t('All_notifications')), /*#__PURE__*/React.createElement(ModalBody, {
100
+ className: "sdoc-all-notifications-body"
101
+ }, /*#__PURE__*/React.createElement("div", {
102
+ className: "sdoc-all-notifications-container",
103
+ ref: containerRef,
104
+ onScroll: onScroll
105
+ }, renderNotifications())));
106
+ };
107
+ export default AllNotificationsDialog;