box-ui-elements 16.0.0 → 16.0.1-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/explorer.js +2 -2
  2. package/dist/openwith.js +1 -1
  3. package/dist/picker.js +9 -9
  4. package/dist/preview.js +2 -2
  5. package/dist/sharing.js +15 -15
  6. package/dist/sidebar.js +2 -2
  7. package/dist/uploader.js +9 -9
  8. package/es/api/Feed.js +67 -22
  9. package/es/api/Feed.js.flow +52 -6
  10. package/es/api/Feed.js.map +1 -1
  11. package/es/elements/content-sidebar/withSidebarAnnotations.js +6 -10
  12. package/es/elements/content-sidebar/withSidebarAnnotations.js.flow +5 -5
  13. package/es/elements/content-sidebar/withSidebarAnnotations.js.map +1 -1
  14. package/es/features/content-explorer/content-explorer-modal-container/ContentExplorerModalContainer.js +12 -52
  15. package/es/features/content-explorer/content-explorer-modal-container/ContentExplorerModalContainer.js.flow +3 -49
  16. package/es/features/content-explorer/content-explorer-modal-container/ContentExplorerModalContainer.js.map +1 -1
  17. package/i18n/fi-FI.js +3 -3
  18. package/i18n/fi-FI.properties +3 -3
  19. package/i18n/hi-IN.js +3 -3
  20. package/i18n/hi-IN.properties +3 -3
  21. package/i18n/it-IT.js +3 -3
  22. package/i18n/it-IT.properties +3 -3
  23. package/i18n/ja-JP.js +3 -3
  24. package/i18n/ja-JP.properties +3 -3
  25. package/i18n/nb-NO.js +3 -3
  26. package/i18n/nb-NO.properties +3 -3
  27. package/i18n/nl-NL.js +3 -3
  28. package/i18n/nl-NL.properties +3 -3
  29. package/i18n/sv-SE.js +3 -3
  30. package/i18n/sv-SE.properties +3 -3
  31. package/i18n/zh-CN.js +3 -3
  32. package/i18n/zh-CN.properties +3 -3
  33. package/i18n/zh-TW.js +3 -3
  34. package/i18n/zh-TW.properties +3 -3
  35. package/package.json +1 -1
  36. package/src/api/Feed.js +52 -6
  37. package/src/api/__tests__/Feed.test.js +130 -5
  38. package/src/elements/content-sidebar/__tests__/withSidebarAnnotations.test.js +4 -2
  39. package/src/elements/content-sidebar/withSidebarAnnotations.js +5 -5
  40. package/src/features/content-explorer/content-explorer-modal-container/ContentExplorerModalContainer.js +3 -49
package/i18n/nl-NL.js CHANGED
@@ -97,9 +97,9 @@ export default {
97
97
  "be.contentSidebar.activityFeed.commentForm.commentWrite": "Een opmerking schrijven",
98
98
  "be.contentSidebar.activityFeed.commmon.showOriginalMessage": "Origineel tonen",
99
99
  "be.contentSidebar.activityFeed.common.activityStatusResolved": "Opgelost",
100
- "be.contentSidebar.activityFeed.common.editedMessage": "(edited)",
101
- "be.contentSidebar.activityFeed.common.seeLessMessage": "See less",
102
- "be.contentSidebar.activityFeed.common.seeMoreMessage": "See more",
100
+ "be.contentSidebar.activityFeed.common.editedMessage": "(bewerkt)",
101
+ "be.contentSidebar.activityFeed.common.seeLessMessage": "Minder weergeven",
102
+ "be.contentSidebar.activityFeed.common.seeMoreMessage": "Meer weergeven",
103
103
  "be.contentSidebar.activityFeed.common.translateMessage": "Vertalen",
104
104
  "be.contentSidebar.activityFeed.task.taskAnyAffordanceTooltip": "Er is slechts één toegewezen gebruiker nodig om deze taak te voltooien",
105
105
  "be.contentSidebar.activityFeed.task.taskDeleteMenuItem": "Taak verwijderen",
@@ -195,11 +195,11 @@ be.contentSidebar.activityFeed.commmon.showOriginalMessage = Origineel tonen
195
195
  # Indicator of resolved status of Comment or Annotation, visible in Feed Item (in upper-case in supported language)
196
196
  be.contentSidebar.activityFeed.common.activityStatusResolved = Opgelost
197
197
  # Label indicating that message was edited, should be lowercase
198
- be.contentSidebar.activityFeed.common.editedMessage = (edited)
198
+ be.contentSidebar.activityFeed.common.editedMessage = (bewerkt)
199
199
  # See less button for hiding part of long message
200
- be.contentSidebar.activityFeed.common.seeLessMessage = See less
200
+ be.contentSidebar.activityFeed.common.seeLessMessage = Minder weergeven
201
201
  # See more button for showing whole long message
202
- be.contentSidebar.activityFeed.common.seeMoreMessage = See more
202
+ be.contentSidebar.activityFeed.common.seeMoreMessage = Meer weergeven
203
203
  # Translate button for translating comment
204
204
  be.contentSidebar.activityFeed.common.translateMessage = Vertalen
205
205
  # Tooltip text for any task icon, explaining that the task only needs one assignee to complete.
package/i18n/sv-SE.js CHANGED
@@ -97,9 +97,9 @@ export default {
97
97
  "be.contentSidebar.activityFeed.commentForm.commentWrite": "Skriv en kommentar",
98
98
  "be.contentSidebar.activityFeed.commmon.showOriginalMessage": "Visa original",
99
99
  "be.contentSidebar.activityFeed.common.activityStatusResolved": "Löst",
100
- "be.contentSidebar.activityFeed.common.editedMessage": "(edited)",
101
- "be.contentSidebar.activityFeed.common.seeLessMessage": "See less",
102
- "be.contentSidebar.activityFeed.common.seeMoreMessage": "See more",
100
+ "be.contentSidebar.activityFeed.common.editedMessage": "(redigerad)",
101
+ "be.contentSidebar.activityFeed.common.seeLessMessage": "Se mindre",
102
+ "be.contentSidebar.activityFeed.common.seeMoreMessage": "Se mer",
103
103
  "be.contentSidebar.activityFeed.common.translateMessage": "Översätt",
104
104
  "be.contentSidebar.activityFeed.task.taskAnyAffordanceTooltip": "Endast en tilldelad behöver slutföra uppgiften",
105
105
  "be.contentSidebar.activityFeed.task.taskDeleteMenuItem": "Radera uppgift",
@@ -195,11 +195,11 @@ be.contentSidebar.activityFeed.commmon.showOriginalMessage = Visa original
195
195
  # Indicator of resolved status of Comment or Annotation, visible in Feed Item (in upper-case in supported language)
196
196
  be.contentSidebar.activityFeed.common.activityStatusResolved = Löst
197
197
  # Label indicating that message was edited, should be lowercase
198
- be.contentSidebar.activityFeed.common.editedMessage = (edited)
198
+ be.contentSidebar.activityFeed.common.editedMessage = (redigerad)
199
199
  # See less button for hiding part of long message
200
- be.contentSidebar.activityFeed.common.seeLessMessage = See less
200
+ be.contentSidebar.activityFeed.common.seeLessMessage = Se mindre
201
201
  # See more button for showing whole long message
202
- be.contentSidebar.activityFeed.common.seeMoreMessage = See more
202
+ be.contentSidebar.activityFeed.common.seeMoreMessage = Se mer
203
203
  # Translate button for translating comment
204
204
  be.contentSidebar.activityFeed.common.translateMessage = Översätt
205
205
  # Tooltip text for any task icon, explaining that the task only needs one assignee to complete.
package/i18n/zh-CN.js CHANGED
@@ -97,9 +97,9 @@ export default {
97
97
  "be.contentSidebar.activityFeed.commentForm.commentWrite": "留下评论",
98
98
  "be.contentSidebar.activityFeed.commmon.showOriginalMessage": "显示原始评论",
99
99
  "be.contentSidebar.activityFeed.common.activityStatusResolved": "Resolved",
100
- "be.contentSidebar.activityFeed.common.editedMessage": "(edited)",
101
- "be.contentSidebar.activityFeed.common.seeLessMessage": "See less",
102
- "be.contentSidebar.activityFeed.common.seeMoreMessage": "See more",
100
+ "be.contentSidebar.activityFeed.common.editedMessage": "(编辑)",
101
+ "be.contentSidebar.activityFeed.common.seeLessMessage": "查看更少",
102
+ "be.contentSidebar.activityFeed.common.seeMoreMessage": "查看更多",
103
103
  "be.contentSidebar.activityFeed.common.translateMessage": "翻译",
104
104
  "be.contentSidebar.activityFeed.task.taskAnyAffordanceTooltip": "只需要一个受理人来完成此任务",
105
105
  "be.contentSidebar.activityFeed.task.taskDeleteMenuItem": "删除任务",
@@ -195,11 +195,11 @@ be.contentSidebar.activityFeed.commmon.showOriginalMessage = 显示原始评论
195
195
  # Indicator of resolved status of Comment or Annotation, visible in Feed Item (in upper-case in supported language)
196
196
  be.contentSidebar.activityFeed.common.activityStatusResolved = Resolved
197
197
  # Label indicating that message was edited, should be lowercase
198
- be.contentSidebar.activityFeed.common.editedMessage = (edited)
198
+ be.contentSidebar.activityFeed.common.editedMessage = (编辑)
199
199
  # See less button for hiding part of long message
200
- be.contentSidebar.activityFeed.common.seeLessMessage = See less
200
+ be.contentSidebar.activityFeed.common.seeLessMessage = 查看更少
201
201
  # See more button for showing whole long message
202
- be.contentSidebar.activityFeed.common.seeMoreMessage = See more
202
+ be.contentSidebar.activityFeed.common.seeMoreMessage = 查看更多
203
203
  # Translate button for translating comment
204
204
  be.contentSidebar.activityFeed.common.translateMessage = 翻译
205
205
  # Tooltip text for any task icon, explaining that the task only needs one assignee to complete.
package/i18n/zh-TW.js CHANGED
@@ -97,9 +97,9 @@ export default {
97
97
  "be.contentSidebar.activityFeed.commentForm.commentWrite": "撰寫留言",
98
98
  "be.contentSidebar.activityFeed.commmon.showOriginalMessage": "顯示原始留言",
99
99
  "be.contentSidebar.activityFeed.common.activityStatusResolved": "已解決",
100
- "be.contentSidebar.activityFeed.common.editedMessage": "(edited)",
101
- "be.contentSidebar.activityFeed.common.seeLessMessage": "See less",
102
- "be.contentSidebar.activityFeed.common.seeMoreMessage": "See more",
100
+ "be.contentSidebar.activityFeed.common.editedMessage": "(已編輯)",
101
+ "be.contentSidebar.activityFeed.common.seeLessMessage": "查看更少",
102
+ "be.contentSidebar.activityFeed.common.seeMoreMessage": "查看更多",
103
103
  "be.contentSidebar.activityFeed.common.translateMessage": "翻譯",
104
104
  "be.contentSidebar.activityFeed.task.taskAnyAffordanceTooltip": "只要求一位被指定者完成此工作",
105
105
  "be.contentSidebar.activityFeed.task.taskDeleteMenuItem": "刪除工作",
@@ -195,11 +195,11 @@ be.contentSidebar.activityFeed.commmon.showOriginalMessage = 顯示原始留言
195
195
  # Indicator of resolved status of Comment or Annotation, visible in Feed Item (in upper-case in supported language)
196
196
  be.contentSidebar.activityFeed.common.activityStatusResolved = 已解決
197
197
  # Label indicating that message was edited, should be lowercase
198
- be.contentSidebar.activityFeed.common.editedMessage = (edited)
198
+ be.contentSidebar.activityFeed.common.editedMessage = (已編輯)
199
199
  # See less button for hiding part of long message
200
- be.contentSidebar.activityFeed.common.seeLessMessage = See less
200
+ be.contentSidebar.activityFeed.common.seeLessMessage = 查看更少
201
201
  # See more button for showing whole long message
202
- be.contentSidebar.activityFeed.common.seeMoreMessage = See more
202
+ be.contentSidebar.activityFeed.common.seeMoreMessage = 查看更多
203
203
  # Translate button for translating comment
204
204
  be.contentSidebar.activityFeed.common.translateMessage = 翻譯
205
205
  # Tooltip text for any task icon, explaining that the task only needs one assignee to complete.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "box-ui-elements",
3
- "version": "16.0.0",
3
+ "version": "16.0.1-beta.2",
4
4
  "description": "Box UI Elements",
5
5
  "author": "Box (https://www.box.com/)",
6
6
  "license": "SEE LICENSE IN LICENSE",
package/src/api/Feed.js CHANGED
@@ -221,9 +221,11 @@ class Feed extends Base {
221
221
  permissions,
222
222
  feedItemChanges,
223
223
  (annotation: Annotation) => {
224
+ const { replies, total_reply_count, ...annotationBase } = annotation;
224
225
  this.updateFeedItem(
225
226
  {
226
- ...annotation,
227
+ // Do not update replies and total_reply_count props as their current values are not included in the response
228
+ ...annotationBase,
227
229
  isPending: false,
228
230
  },
229
231
  annotationId,
@@ -505,9 +507,12 @@ class Feed extends Base {
505
507
 
506
508
  this.updateFeedItem({ isRepliesLoading: true }, commentFeedItemId);
507
509
 
508
- const successCallbackFn = (comments: ThreadedCommentsType) => {
509
- this.updateFeedItem({ isRepliesLoading: false, replies: comments.entries }, commentFeedItemId);
510
- successCallback(comments.entries);
510
+ const successCallbackFn = ({ entries }: ThreadedCommentsType) => {
511
+ this.updateFeedItem(
512
+ { isRepliesLoading: false, replies: entries, total_reply_count: entries.length },
513
+ commentFeedItemId,
514
+ );
515
+ successCallback(entries);
511
516
  };
512
517
  const errorCallbackFn = (error: ErrorResponseData, code: string) => {
513
518
  this.fetchRepliesErrorCallback(error, code, commentFeedItemId);
@@ -898,13 +903,26 @@ class Feed extends Base {
898
903
  fileId: file.id,
899
904
  commentId: id,
900
905
  permissions,
901
- successCallback: this.deleteReplyItem.bind(this, id, parentId, successCallback),
906
+ successCallback: this.deleteReplySuccessCallback.bind(this, id, parentId, successCallback),
902
907
  errorCallback: (e: ElementsXhrError, code: string) => {
903
908
  this.deleteReplyErrorCallback(e, code, id, parentId);
904
909
  },
905
910
  });
906
911
  };
907
912
 
913
+ /**
914
+ * Callback for successful deletion of a reply.
915
+ *
916
+ * @param {string} id - ID of the reply
917
+ * @param {string} parentId - ID of the parent feed item
918
+ * @param {Function} successCallback - success callback
919
+ * @return {void}
920
+ */
921
+ deleteReplySuccessCallback = (id: string, parentId: string, successCallback: Function): void => {
922
+ this.deleteReplyItem(id, parentId, successCallback);
923
+ this.modifyFeedItemRepliesCountBy(parentId, -1);
924
+ };
925
+
908
926
  /**
909
927
  * Error callback for deleting a comment
910
928
  *
@@ -1727,6 +1745,7 @@ class Feed extends Base {
1727
1745
  this.file = file;
1728
1746
  this.errorCallback = errorCallback;
1729
1747
  this.addPendingReply(parentId, currentUser, commentData);
1748
+ this.modifyFeedItemRepliesCountBy(parentId, 1);
1730
1749
 
1731
1750
  const successCallbackFn = (comment: Comment) => {
1732
1751
  this.createReplySuccessCallback(comment, parentId, uuid, successCallback);
@@ -1877,9 +1896,11 @@ class Feed extends Base {
1877
1896
  message: text,
1878
1897
  status,
1879
1898
  successCallback: (comment: Comment) => {
1899
+ const { replies, total_reply_count, ...commentBase } = comment;
1880
1900
  this.updateFeedItem(
1881
1901
  {
1882
- ...comment,
1902
+ // Do not update replies and total_reply_count props as their current values are not included in the response
1903
+ ...commentBase,
1883
1904
  isPending: false,
1884
1905
  },
1885
1906
  commentId,
@@ -1950,6 +1971,31 @@ class Feed extends Base {
1950
1971
  });
1951
1972
  };
1952
1973
 
1974
+ /**
1975
+ * Modify feed item replies count
1976
+ *
1977
+ * @param {string} id - id of the item
1978
+ * @param {number} n - number to modify the count by
1979
+ * @return {void}
1980
+ */
1981
+ modifyFeedItemRepliesCountBy = (id: string, n: number) => {
1982
+ if (!this.file.id) {
1983
+ throw getBadItemError();
1984
+ }
1985
+
1986
+ const { items: feedItems = [] } = this.getCachedItems(this.file.id) || {};
1987
+ const feedItem = feedItems.find(({ id: itemId }) => itemId === id);
1988
+
1989
+ if (!feedItem || (feedItem.type !== 'annotation' && feedItem.type !== 'comment')) {
1990
+ return;
1991
+ }
1992
+
1993
+ const newReplyCount = (feedItem.total_reply_count || 0) + n;
1994
+ if (newReplyCount >= 0) {
1995
+ this.updateFeedItem({ total_reply_count: newReplyCount }, id);
1996
+ }
1997
+ };
1998
+
1953
1999
  destroyTaskCollaborators() {
1954
2000
  if (Array.isArray(this.taskCollaboratorsAPI)) {
1955
2001
  this.taskCollaboratorsAPI.forEach(api => api.destroy());
@@ -12,7 +12,9 @@ import {
12
12
  IS_ERROR_DISPLAYED,
13
13
  TASK_MAX_GROUP_ASSIGNEES,
14
14
  } from '../../constants';
15
+ import AnnotationsAPI from '../Annotations';
15
16
  import Feed from '../Feed';
17
+ import ThreadedCommentsAPI from '../ThreadedComments';
16
18
  import { annotation as mockAnnotation } from '../../__mocks__/annotations';
17
19
  import { task as mockTask, threadedComments as mockThreadedComments, threadedCommentsFormatted } from '../fixtures';
18
20
 
@@ -66,6 +68,8 @@ const threadedComments = {
66
68
  next_marker: null,
67
69
  };
68
70
 
71
+ const mockReplies = mockThreadedComments[0].replies;
72
+
69
73
  jest.mock('lodash/uniqueId', () => () => 'uniqueId');
70
74
 
71
75
  const mockCreateTaskWithDeps = jest.fn().mockImplementation(({ successCallback }) => {
@@ -206,7 +210,7 @@ jest.mock('../ThreadedComments', () =>
206
210
  }),
207
211
  getCommentReplies: jest.fn().mockImplementation(({ successCallback }) => {
208
212
  successCallback({
209
- entries: mockThreadedComments,
213
+ entries: mockReplies,
210
214
  limit: 1000,
211
215
  next_marker: null,
212
216
  });
@@ -215,7 +219,7 @@ jest.mock('../ThreadedComments', () =>
215
219
  successCallback();
216
220
  }),
217
221
  updateComment: jest.fn().mockImplementation(({ successCallback }) => {
218
- successCallback();
222
+ successCallback({});
219
223
  }),
220
224
  createComment: jest.fn().mockImplementation(({ successCallback }) => {
221
225
  successCallback();
@@ -239,12 +243,12 @@ jest.mock('../Annotations', () =>
239
243
  successCallback();
240
244
  }),
241
245
  updateAnnotation: jest.fn().mockImplementation((file, id, payload, permissions, successCallback) => {
242
- successCallback();
246
+ successCallback({});
243
247
  }),
244
248
  getAnnotations: jest.fn(),
245
249
  getAnnotationReplies: jest.fn().mockImplementation((fileId, annotationId, permissions, successCallback) => {
246
250
  successCallback({
247
- entries: mockThreadedComments,
251
+ entries: mockReplies,
248
252
  limit: 1000,
249
253
  next_marker: null,
250
254
  });
@@ -676,8 +680,8 @@ describe('api/Feed', () => {
676
680
  const annotationId = '1234';
677
681
  const successCallback = jest.fn();
678
682
  const errorCallback = jest.fn();
683
+
679
684
  feed.fetchReplies(file, annotationId, FEED_ITEM_TYPE_ANNOTATION, successCallback, errorCallback);
680
- expect(feed.updateFeedItem).toBeCalledWith({ isRepliesLoading: true }, annotationId);
681
685
  expect(feed.annotationsAPI.getAnnotationReplies).toBeCalledWith(
682
686
  feed.file.id,
683
687
  annotationId,
@@ -685,6 +689,16 @@ describe('api/Feed', () => {
685
689
  expect.any(Function),
686
690
  expect.any(Function),
687
691
  );
692
+ expect(feed.updateFeedItem).toHaveBeenNthCalledWith(1, { isRepliesLoading: true }, annotationId);
693
+ expect(feed.updateFeedItem).toHaveBeenNthCalledWith(
694
+ 2,
695
+ {
696
+ isRepliesLoading: false,
697
+ replies: mockReplies,
698
+ total_reply_count: mockReplies.length,
699
+ },
700
+ annotationId,
701
+ );
688
702
  expect(successCallback).toBeCalled();
689
703
  });
690
704
  });
@@ -1094,6 +1108,39 @@ describe('api/Feed', () => {
1094
1108
  expect(successCallback).toBeCalled();
1095
1109
  });
1096
1110
  });
1111
+
1112
+ test('should call updateFeedItem without the replies and total_reply_count properties', () => {
1113
+ const commentId = '1';
1114
+ const text = 'abc';
1115
+ const permissions = { can_edit: true };
1116
+ const updatedCommentResult = {
1117
+ id: commentId,
1118
+ permissions,
1119
+ replies: [],
1120
+ tagged_message: text,
1121
+ total_reply_count: 0,
1122
+ };
1123
+ ThreadedCommentsAPI.mockReturnValueOnce({
1124
+ updateComment: jest.fn().mockImplementation(({ successCallback }) => {
1125
+ successCallback(updatedCommentResult);
1126
+ }),
1127
+ });
1128
+
1129
+ feed.updateThreadedComment(file, commentId, text, undefined, permissions, jest.fn(), jest.fn());
1130
+
1131
+ const expectedUpdateFeedItemCommentData = {
1132
+ id: commentId,
1133
+ isPending: false,
1134
+ permissions,
1135
+ tagged_message: text,
1136
+ };
1137
+ expect(feed.updateFeedItem).toHaveBeenNthCalledWith(
1138
+ 1,
1139
+ { tagged_message: text, isPending: true },
1140
+ commentId,
1141
+ );
1142
+ expect(feed.updateFeedItem).toHaveBeenNthCalledWith(2, expectedUpdateFeedItemCommentData, commentId);
1143
+ });
1097
1144
  });
1098
1145
 
1099
1146
  describe('updateReply()', () => {
@@ -1218,6 +1265,19 @@ describe('api/Feed', () => {
1218
1265
  });
1219
1266
  });
1220
1267
 
1268
+ describe('deleteReplySuccessCallback()', () => {
1269
+ test('should remove the reply from feed and update parent item', () => {
1270
+ feed.deleteReplyItem = jest.fn();
1271
+ feed.modifyFeedItemRepliesCountBy = jest.fn();
1272
+ const id = '123';
1273
+ const parentId = '456';
1274
+ const successCallback = jest.fn();
1275
+ feed.deleteReplySuccessCallback(id, parentId, successCallback);
1276
+ expect(feed.deleteReplyItem).toBeCalledWith(id, parentId, successCallback);
1277
+ expect(feed.modifyFeedItemRepliesCountBy).toBeCalledWith(parentId, -1);
1278
+ });
1279
+ });
1280
+
1221
1281
  describe('deleteCommentErrorCallback()', () => {
1222
1282
  const e = new Error('foo');
1223
1283
 
@@ -1695,6 +1755,22 @@ describe('api/Feed', () => {
1695
1755
  });
1696
1756
  });
1697
1757
 
1758
+ test('should increment the number of replies of parent item', () => {
1759
+ feed.modifyFeedItemRepliesCountBy = jest.fn();
1760
+ const successCb = jest.fn();
1761
+ const errorCb = jest.fn();
1762
+ const parentId = '123';
1763
+ const parentType = FEED_ITEM_TYPE_COMMENT;
1764
+ const text = 'abc';
1765
+ const currentUser = {
1766
+ id: '123',
1767
+ };
1768
+
1769
+ feed.createReply(file, currentUser, parentId, parentType, text, successCb, errorCb);
1770
+
1771
+ expect(feed.modifyFeedItemRepliesCountBy).toBeCalledWith(parentId, 1);
1772
+ });
1773
+
1698
1774
  test('given parentType=annotation, should create the reply using annotationsAPI and invoke the success callback', done => {
1699
1775
  feed.createReplySuccessCallback = jest.fn();
1700
1776
  feed.createReplyErrorCallback = jest.fn();
@@ -1975,6 +2051,34 @@ describe('api/Feed', () => {
1975
2051
  expect(successCallback).toBeCalled();
1976
2052
  });
1977
2053
  });
2054
+
2055
+ test('should call updateFeedItem without the replies and total_reply_count properties', () => {
2056
+ const status = 'open';
2057
+ const updatedAnnotationResult = {
2058
+ id: annotationId,
2059
+ permissions,
2060
+ replies: [],
2061
+ status,
2062
+ total_reply_count: 0,
2063
+ };
2064
+ AnnotationsAPI.mockReturnValueOnce({
2065
+ updateAnnotation: jest.fn().mockImplementation((f, id, payload, p, callback) => {
2066
+ callback(updatedAnnotationResult);
2067
+ }),
2068
+ });
2069
+ feed.updateFeedItem = jest.fn();
2070
+
2071
+ feed.updateAnnotation(file, annotationId, undefined, status, permissions, jest.fn(), jest.fn());
2072
+
2073
+ const expectedUpdateFeedItemCommentData = {
2074
+ id: annotationId,
2075
+ isPending: false,
2076
+ permissions,
2077
+ status,
2078
+ };
2079
+ expect(feed.updateFeedItem).toHaveBeenNthCalledWith(1, { status, isPending: true }, annotationId);
2080
+ expect(feed.updateFeedItem).toHaveBeenNthCalledWith(2, expectedUpdateFeedItemCommentData, annotationId);
2081
+ });
1978
2082
  });
1979
2083
 
1980
2084
  describe('updateCommentErrorCallback()', () => {
@@ -2062,4 +2166,25 @@ describe('api/Feed', () => {
2062
2166
  expect(successCallback).toBeCalled();
2063
2167
  });
2064
2168
  });
2169
+
2170
+ describe('modifyFeedItemRepliesCountBy()', () => {
2171
+ test('should throw if no file id', () => {
2172
+ feed.file = {};
2173
+ expect(() => feed.modifyFeedItemRepliesCountBy('123', 1)).toThrow(fileError);
2174
+ });
2175
+
2176
+ test('should call updateFeedItem if item is in cache', () => {
2177
+ const cachedItems = cloneDeep(mockThreadedComments);
2178
+ const { id, total_reply_count } = cachedItems[0];
2179
+ feed.file = file;
2180
+ feed.updateFeedItem = jest.fn();
2181
+ feed.getCachedItems = jest.fn().mockReturnValue({
2182
+ errors: [],
2183
+ items: cachedItems,
2184
+ });
2185
+
2186
+ feed.modifyFeedItemRepliesCountBy(id, 1);
2187
+ expect(feed.updateFeedItem).toBeCalledWith({ total_reply_count: total_reply_count + 1 }, id);
2188
+ });
2189
+ });
2065
2190
  });
@@ -32,6 +32,7 @@ describe('elements/content-sidebar/withSidebarAnnotations', () => {
32
32
  deleteAnnotation: jest.fn(),
33
33
  deleteFeedItem: jest.fn(),
34
34
  deleteReplyItem: jest.fn(),
35
+ modifyFeedItemRepliesCountBy: jest.fn(),
35
36
  updateFeedItem: jest.fn(),
36
37
  updateReplyItem: jest.fn(),
37
38
  };
@@ -337,7 +338,7 @@ describe('elements/content-sidebar/withSidebarAnnotations', () => {
337
338
  instance.addAnnotationReply();
338
339
 
339
340
  const expectedReplyData = { ...annotationReply, isPending: false };
340
- expect(feedAPI.updateFeedItem).toBeCalledWith({ total_reply_count: 3 }, annotation.id);
341
+ expect(feedAPI.modifyFeedItemRepliesCountBy).toBeCalledWith(annotation.id, 1);
341
342
  expect(feedAPI.updateReplyItem).toBeCalledWith(expectedReplyData, annotation.id, requestId);
342
343
  });
343
344
  });
@@ -415,7 +416,7 @@ describe('elements/content-sidebar/withSidebarAnnotations', () => {
415
416
 
416
417
  instance.deleteAnnotationReply();
417
418
 
418
- expect(feedAPI.updateFeedItem).toBeCalledWith({ total_reply_count: 1 }, annotation.id);
419
+ expect(feedAPI.modifyFeedItemRepliesCountBy).toBeCalledWith(annotation.id, -1);
419
420
  });
420
421
 
421
422
  test('should delete appropriate reply from the feed if it is currently in the feed given action = reply_delete_end', () => {
@@ -442,6 +443,7 @@ describe('elements/content-sidebar/withSidebarAnnotations', () => {
442
443
  instance.deleteAnnotationReply();
443
444
 
444
445
  expect(feedAPI.deleteReplyItem).toBeCalledWith(annotationReply.id, annotation.id);
446
+ expect(feedAPI.modifyFeedItemRepliesCountBy).toBeCalledWith(annotation.id, -1);
445
447
  });
446
448
  });
447
449
 
@@ -173,7 +173,7 @@ export default function withSidebarAnnotations(
173
173
  return;
174
174
  }
175
175
 
176
- feedAPI.updateFeedItem({ total_reply_count: annotationItem.total_reply_count + 1 }, annotationId);
176
+ feedAPI.modifyFeedItemRepliesCountBy(annotationId, 1);
177
177
  feedAPI.updateReplyItem({ ...annotationReply, isPending: false }, annotationId, requestId);
178
178
  }
179
179
 
@@ -223,14 +223,14 @@ export default function withSidebarAnnotations(
223
223
  return;
224
224
  }
225
225
 
226
- // Check if the parent annotation has the reply currently visible
226
+ // Check if the parent annotation has the reply currently visible and if so, remove it
227
227
  const replyItem = annotationItem.replies.find(({ id }) => id === replyId);
228
228
  if (replyItem) {
229
229
  feedAPI.deleteReplyItem(replyId, annotationId);
230
- } else if (annotationItem.total_reply_count > 0) {
231
- // Decrease the amount of replies by 1
232
- feedAPI.updateFeedItem({ total_reply_count: annotationItem.total_reply_count - 1 }, annotationId);
233
230
  }
231
+
232
+ // Decrease the amount of replies by 1
233
+ feedAPI.modifyFeedItemRepliesCountBy(annotationId, -1);
234
234
  }
235
235
 
236
236
  this.refreshActivitySidebar();
@@ -163,38 +163,15 @@ class ContentExplorerModalContainer extends Component {
163
163
 
164
164
  render() {
165
165
  const {
166
- breadcrumbProps,
167
166
  className,
168
- headerActionsAccessory,
169
167
  modalTitle,
170
168
  modalDescription,
171
- onRequestClose,
172
169
  onCreateFolderSubmit,
173
170
  onCreateFolderInput,
174
171
  isCreatingFolder,
175
172
  createFolderError,
176
- contentExplorerMode,
177
173
  initialFoldersPath,
178
- onChooseItems,
179
- onMoveItem,
180
- onCopyItem,
181
- isCreateNewFolderAllowed,
182
- onSearchSubmit,
183
- onExitSearch,
184
- onSelectedClick,
185
- onSelectItem,
186
- items,
187
- numItemsPerPage,
188
- numTotalItems,
189
- onLoadMoreItems,
190
- itemIconRenderer,
191
- itemNameLinkRenderer,
192
- itemButtonRenderer,
193
- showCreateNewFolderButton,
194
- searchInputProps,
195
- chooseButtonText,
196
- initialSelectedItems,
197
- isSelectAllAllowed,
174
+ ...rest
198
175
  } = this.props;
199
176
  const { foldersPath, isNewFolderModalOpen } = this.state;
200
177
  const currentFolder = foldersPath[foldersPath.length - 1];
@@ -202,37 +179,14 @@ class ContentExplorerModalContainer extends Component {
202
179
  return (
203
180
  <div className={classNames('content-explorer-modal-container', className)}>
204
181
  <ContentExplorerModal
205
- breadcrumbProps={breadcrumbProps}
206
182
  className={isNewFolderModalOpen ? 'hidden' : ''}
207
- headerActionsAccessory={headerActionsAccessory}
208
183
  title={modalTitle}
209
184
  description={modalDescription}
210
- isOpen
211
- onRequestClose={onRequestClose}
212
- contentExplorerMode={contentExplorerMode}
213
185
  initialFoldersPath={initialFoldersPath}
186
+ isOpen
214
187
  onEnterFolder={this.handleEnterFolder}
215
- onChooseItems={onChooseItems}
216
- onMoveItem={onMoveItem}
217
- onCopyItem={onCopyItem}
218
- onSelectedClick={onSelectedClick}
219
- onSelectItem={onSelectItem}
220
188
  onCreateNewFolderButtonClick={this.handleCreateNewFolderButtonClick}
221
- isCreateNewFolderAllowed={isCreateNewFolderAllowed}
222
- isSelectAllAllowed={isSelectAllAllowed}
223
- onSearchSubmit={onSearchSubmit}
224
- onExitSearch={onExitSearch}
225
- items={items}
226
- numItemsPerPage={numItemsPerPage}
227
- numTotalItems={numTotalItems}
228
- onLoadMoreItems={onLoadMoreItems}
229
- itemIconRenderer={itemIconRenderer}
230
- itemNameLinkRenderer={itemNameLinkRenderer}
231
- itemButtonRenderer={itemButtonRenderer}
232
- showCreateNewFolderButton={showCreateNewFolderButton}
233
- searchInputProps={searchInputProps}
234
- chooseButtonText={chooseButtonText}
235
- initialSelectedItems={initialSelectedItems}
189
+ {...rest}
236
190
  />
237
191
  {isNewFolderModalOpen && (
238
192
  <NewFolderModal