box-ui-elements 16.1.0-beta.32 → 16.1.0-beta.33

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.
@@ -6,6 +6,10 @@
6
6
 
7
7
  .bcs-ActivityThread {
8
8
  box-shadow: none;
9
+
10
+ &:hover {
11
+ background: none;
12
+ }
9
13
  }
10
14
 
11
15
  .bcs-ActivityThread-content {
@@ -71,7 +71,10 @@ var useAnnotationThread = function useAnnotationThread(_ref) {
71
71
  isLoading = _React$useState8[0],
72
72
  setIsLoading = _React$useState8[1];
73
73
 
74
- var fileId = file.id,
74
+ var _file$file_version = file.file_version;
75
+ _file$file_version = _file$file_version === void 0 ? {} : _file$file_version;
76
+ var fileVersionId = _file$file_version.id,
77
+ fileId = file.id,
75
78
  _file$permissions = file.permissions,
76
79
  filePermissions = _file$permissions === void 0 ? {} : _file$permissions;
77
80
 
@@ -102,7 +105,12 @@ var useAnnotationThread = function useAnnotationThread(_ref) {
102
105
  onAnnotationUpdateStart: setAnnotationPending
103
106
  }),
104
107
  emitAddAnnotationEndEvent = _useAnnotatorEvents.emitAddAnnotationEndEvent,
105
- emitAddAnnotationStartEvent = _useAnnotatorEvents.emitAddAnnotationStartEvent;
108
+ emitAddAnnotationStartEvent = _useAnnotatorEvents.emitAddAnnotationStartEvent,
109
+ emitAnnotationActiveChangeEvent = _useAnnotatorEvents.emitAnnotationActiveChangeEvent,
110
+ emitDeleteAnnotationEndEvent = _useAnnotatorEvents.emitDeleteAnnotationEndEvent,
111
+ emitDeleteAnnotationStartEvent = _useAnnotatorEvents.emitDeleteAnnotationStartEvent,
112
+ emitUpdateAnnotationEndEvent = _useAnnotatorEvents.emitUpdateAnnotationEndEvent,
113
+ emitUpdateAnnotationStartEvent = _useAnnotatorEvents.emitUpdateAnnotationStartEvent;
106
114
 
107
115
  var handleUpdateOrCreateReplyItem = function handleUpdateOrCreateReplyItem(replyId, updatedReplyValues) {
108
116
  setReplies(function (prevReplies) {
@@ -125,16 +133,6 @@ var useAnnotationThread = function useAnnotationThread(_ref) {
125
133
  });
126
134
  };
127
135
 
128
- var handleFetchAnnotationSuccess = function handleFetchAnnotationSuccess(_ref2) {
129
- var fetchedReplies = _ref2.replies,
130
- normalizedAnnotation = _objectWithoutProperties(_ref2, ["replies"]);
131
-
132
- setAnnotation(_objectSpread({}, normalizedAnnotation));
133
- setReplies(normalizeReplies(fetchedReplies));
134
- setError(undefined);
135
- setIsLoading(false);
136
- };
137
-
138
136
  var annotationErrorCallback = React.useCallback(function (e, code) {
139
137
  setIsLoading(false);
140
138
  setError({
@@ -158,16 +156,25 @@ var useAnnotationThread = function useAnnotationThread(_ref) {
158
156
  handleStatusChange = _useAnnotationAPI.handleStatusChange;
159
157
 
160
158
  React.useEffect(function () {
161
- if (!annotationId || annotation && annotation.id === annotationId) {
159
+ if (!annotationId || isLoading || annotation && annotation.id === annotationId) {
162
160
  return;
163
161
  }
164
162
 
165
163
  setIsLoading(true);
166
164
  handleFetch({
167
165
  id: annotationId,
168
- successCallback: handleFetchAnnotationSuccess
166
+ successCallback: function successCallback(_ref2) {
167
+ var fetchedReplies = _ref2.replies,
168
+ normalizedAnnotation = _objectWithoutProperties(_ref2, ["replies"]);
169
+
170
+ setAnnotation(_objectSpread({}, normalizedAnnotation));
171
+ setReplies(normalizeReplies(fetchedReplies));
172
+ setError(undefined);
173
+ setIsLoading(false);
174
+ emitAnnotationActiveChangeEvent(normalizedAnnotation.id, fileVersionId);
175
+ }
169
176
  });
170
- }, [annotation, annotationId, handleFetch]);
177
+ }, [annotation, annotationId, emitAnnotationActiveChangeEvent, fileVersionId, handleFetch, isLoading]);
171
178
 
172
179
  var _useRepliesAPI = useRepliesAPI({
173
180
  annotationId: annotationId,
@@ -209,7 +216,8 @@ var useAnnotationThread = function useAnnotationThread(_ref) {
209
216
  var id = _ref3.id,
210
217
  permissions = _ref3.permissions;
211
218
 
212
- var annotationDeleteSuccessCallback = function annotationDeleteSuccessCallback() {// will emit event
219
+ var annotationDeleteSuccessCallback = function annotationDeleteSuccessCallback() {
220
+ emitDeleteAnnotationEndEvent(id);
213
221
  };
214
222
 
215
223
  setAnnotation(function (prevAnnotation) {
@@ -217,6 +225,7 @@ var useAnnotationThread = function useAnnotationThread(_ref) {
217
225
  isPending: true
218
226
  });
219
227
  });
228
+ emitDeleteAnnotationStartEvent(id);
220
229
  handleDelete({
221
230
  id: id,
222
231
  permissions: permissions,
@@ -228,6 +237,7 @@ var useAnnotationThread = function useAnnotationThread(_ref) {
228
237
  handleUpdateAnnotation(_objectSpread({}, updatedAnnotation, {
229
238
  isPending: false
230
239
  }));
240
+ emitUpdateAnnotationEndEvent(updatedAnnotation);
231
241
  };
232
242
 
233
243
  var handleAnnotationEdit = function handleAnnotationEdit(id, text, permissions) {
@@ -236,6 +246,12 @@ var useAnnotationThread = function useAnnotationThread(_ref) {
236
246
  isPending: true
237
247
  });
238
248
  });
249
+ emitUpdateAnnotationStartEvent({
250
+ id: id,
251
+ description: {
252
+ message: text
253
+ }
254
+ });
239
255
  handleEdit({
240
256
  id: id,
241
257
  text: text,
@@ -86,7 +86,7 @@ const useAnnotationThread = ({
86
86
  const [error, setError] = React.useState<AnnotationThreadError | typeof undefined>();
87
87
  const [isLoading, setIsLoading] = React.useState<boolean>(false);
88
88
 
89
- const { id: fileId, permissions: filePermissions = {} } = file;
89
+ const { file_version: { id: fileVersionId } = {}, id: fileId, permissions: filePermissions = {} } = file;
90
90
 
91
91
  const setAnnotationPending = () => {
92
92
  if (annotation) {
@@ -100,7 +100,15 @@ const useAnnotationThread = ({
100
100
  }
101
101
  };
102
102
 
103
- const { emitAddAnnotationEndEvent, emitAddAnnotationStartEvent } = useAnnotatorEvents({
103
+ const {
104
+ emitAddAnnotationEndEvent,
105
+ emitAddAnnotationStartEvent,
106
+ emitAnnotationActiveChangeEvent,
107
+ emitDeleteAnnotationEndEvent,
108
+ emitDeleteAnnotationStartEvent,
109
+ emitUpdateAnnotationEndEvent,
110
+ emitUpdateAnnotationStartEvent,
111
+ } = useAnnotatorEvents({
104
112
  eventEmitter,
105
113
  onAnnotationDeleteStart: setAnnotationPending,
106
114
  onAnnotationUpdateEnd: handleAnnotationUpdateEnd,
@@ -129,13 +137,6 @@ const useAnnotationThread = ({
129
137
  setAnnotation(prevAnnotation => ({ ...prevAnnotation, ...updatedValues }));
130
138
  };
131
139
 
132
- const handleFetchAnnotationSuccess = ({ replies: fetchedReplies, ...normalizedAnnotation }: Annotation) => {
133
- setAnnotation({ ...normalizedAnnotation });
134
- setReplies(normalizeReplies(fetchedReplies));
135
- setError(undefined);
136
- setIsLoading(false);
137
- };
138
-
139
140
  const annotationErrorCallback = React.useCallback(
140
141
  (e: ElementsXhrError, code: string): void => {
141
142
  setIsLoading(false);
@@ -158,12 +159,21 @@ const useAnnotationThread = ({
158
159
  });
159
160
 
160
161
  React.useEffect(() => {
161
- if (!annotationId || (annotation && annotation.id === annotationId)) {
162
+ if (!annotationId || isLoading || (annotation && annotation.id === annotationId)) {
162
163
  return;
163
164
  }
164
165
  setIsLoading(true);
165
- handleFetch({ id: annotationId, successCallback: handleFetchAnnotationSuccess });
166
- }, [annotation, annotationId, handleFetch]);
166
+ handleFetch({
167
+ id: annotationId,
168
+ successCallback: ({ replies: fetchedReplies, ...normalizedAnnotation }: Annotation) => {
169
+ setAnnotation({ ...normalizedAnnotation });
170
+ setReplies(normalizeReplies(fetchedReplies));
171
+ setError(undefined);
172
+ setIsLoading(false);
173
+ emitAnnotationActiveChangeEvent(normalizedAnnotation.id, fileVersionId);
174
+ },
175
+ });
176
+ }, [annotation, annotationId, emitAnnotationActiveChangeEvent, fileVersionId, handleFetch, isLoading]);
167
177
 
168
178
  const { handleReplyCreate, handleReplyEdit, handleReplyDelete } = useRepliesAPI({
169
179
  annotationId,
@@ -198,10 +208,13 @@ const useAnnotationThread = ({
198
208
 
199
209
  const handleAnnotationDelete = ({ id, permissions }: { id: string, permissions: AnnotationPermission }): void => {
200
210
  const annotationDeleteSuccessCallback = () => {
201
- // will emit event
211
+ emitDeleteAnnotationEndEvent(id);
202
212
  };
203
213
 
204
214
  setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));
215
+
216
+ emitDeleteAnnotationStartEvent(id);
217
+
205
218
  handleDelete({
206
219
  id,
207
220
  permissions,
@@ -214,11 +227,18 @@ const useAnnotationThread = ({
214
227
  ...updatedAnnotation,
215
228
  isPending: false,
216
229
  });
230
+
231
+ emitUpdateAnnotationEndEvent(updatedAnnotation);
217
232
  };
218
233
 
219
234
  const handleAnnotationEdit = (id: string, text: string, permissions: AnnotationPermission): void => {
220
235
  setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));
221
236
 
237
+ emitUpdateAnnotationStartEvent({
238
+ id,
239
+ description: { message: text },
240
+ });
241
+
222
242
  handleEdit({
223
243
  id,
224
244
  text,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/elements/content-sidebar/activity-feed/annotation-thread/useAnnotationThread.js"],"names":["React","uniqueId","commonMessages","annotationErrors","API","useRepliesAPI","useAnnotatorEvents","useAnnotationAPI","normalizeReplies","repliesArray","reduce","prevValues","reply","id","denormalizeReplies","repliesMap","Object","keys","map","key","useAnnotationThread","annotationId","api","currentUser","errorCallback","eventEmitter","file","onAnnotationCreate","target","useState","annotation","setAnnotation","replies","setReplies","error","setError","isLoading","setIsLoading","fileId","permissions","filePermissions","setAnnotationPending","prevAnnotation","isPending","handleAnnotationUpdateEnd","updatedAnnotation","onAnnotationDeleteStart","onAnnotationUpdateEnd","onAnnotationUpdateStart","emitAddAnnotationEndEvent","emitAddAnnotationStartEvent","handleUpdateOrCreateReplyItem","replyId","updatedReplyValues","prevReplies","handleRemoveReplyItem","newReplies","handleUpdateAnnotation","updatedValues","handleFetchAnnotationSuccess","fetchedReplies","normalizedAnnotation","undefined","annotationErrorCallback","useCallback","e","code","title","errorOccured","message","default","handleCreate","handleDelete","handleEdit","handleFetch","handleStatusChange","useEffect","successCallback","handleReplyCreate","handleReplyEdit","handleReplyDelete","handleAnnotationCreate","text","requestId","newAnnotation","payload","description","handleAnnotationDelete","annotationDeleteSuccessCallback","onAnnotationEditSuccessCallback","handleAnnotationEdit","handleAnnotationStatusChange","status","annotationActions","repliesActions"],"mappings":"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","sourcesContent":["// @flow\n\nimport React from 'react';\nimport uniqueId from 'lodash/uniqueId';\nimport type EventEmitter from 'events';\nimport commonMessages from '../../../common/messages';\nimport { annotationErrors } from './errors';\nimport API from '../../../../api/APIFactory';\nimport useRepliesAPI from './useRepliesAPI';\nimport { useAnnotatorEvents } from '../../../common/annotator-context';\nimport useAnnotationAPI from './useAnnotationAPI';\nimport type { Annotation, AnnotationPermission, NewAnnotation, Target } from '../../../../common/types/annotations';\nimport type { BoxItem, User } from '../../../../common/types/core';\nimport type { BoxCommentPermission, Comment, FeedItemStatus } from '../../../../common/types/feed';\nimport type { ElementOrigin, ElementsXhrError } from '../../../../common/types/api';\nimport type { AnnotationThreadError } from './types';\n\nconst normalizeReplies = (repliesArray?: Array<Comment>): { [string]: Comment } => {\n if (!repliesArray) {\n return {};\n }\n return repliesArray.reduce((prevValues, reply) => {\n return {\n ...prevValues,\n [reply.id]: reply,\n };\n }, {});\n};\n\nconst denormalizeReplies = (repliesMap: { [string]: Comment }): Array<Comment> => {\n return Object.keys(repliesMap).map(key => repliesMap[key]);\n};\n\ntype Props = {\n annotationId?: string,\n api: API,\n currentUser: User,\n errorCallback: (\n error: ElementsXhrError | Error,\n code: string,\n contextInfo?: Object,\n origin?: ElementOrigin,\n ) => void,\n eventEmitter: EventEmitter,\n file: BoxItem,\n onAnnotationCreate: (annotation: Annotation) => void,\n target: Target,\n};\n\ntype UseAnnotationThread = {\n annotation?: Annotation,\n annotationActions: {\n handleAnnotationCreate: (text: string) => void,\n handleAnnotationDelete: ({ id: string, permissions: AnnotationPermission }) => void,\n handleAnnotationEdit: (id: string, text: string, permissions: AnnotationPermission) => void,\n handleAnnotationStatusChange: (id: string, status: FeedItemStatus, permissions: AnnotationPermission) => void,\n },\n error?: AnnotationThreadError,\n isLoading: boolean,\n replies: Array<Comment>,\n repliesActions: {\n handleReplyCreate: (message: string) => void,\n handleReplyDelete: ({ id: string, permissions: BoxCommentPermission }) => void,\n handleReplyEdit: (\n replyId: string,\n message: string,\n status?: FeedItemStatus,\n hasMention?: boolean,\n permissions: BoxCommentPermission,\n ) => void,\n },\n};\n\nconst useAnnotationThread = ({\n annotationId,\n api,\n currentUser,\n errorCallback,\n eventEmitter,\n file,\n onAnnotationCreate,\n target,\n}: Props): UseAnnotationThread => {\n const [annotation, setAnnotation] = React.useState<Annotation | typeof undefined>();\n const [replies, setReplies] = React.useState<{ [string]: Comment }>({});\n const [error, setError] = React.useState<AnnotationThreadError | typeof undefined>();\n const [isLoading, setIsLoading] = React.useState<boolean>(false);\n\n const { id: fileId, permissions: filePermissions = {} } = file;\n\n const setAnnotationPending = () => {\n if (annotation) {\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));\n }\n };\n\n const handleAnnotationUpdateEnd = (updatedAnnotation: Annotation) => {\n if (annotation && updatedAnnotation.id === annotationId) {\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, ...updatedAnnotation, isPending: false }));\n }\n };\n\n const { emitAddAnnotationEndEvent, emitAddAnnotationStartEvent } = useAnnotatorEvents({\n eventEmitter,\n onAnnotationDeleteStart: setAnnotationPending,\n onAnnotationUpdateEnd: handleAnnotationUpdateEnd,\n onAnnotationUpdateStart: setAnnotationPending,\n });\n\n const handleUpdateOrCreateReplyItem = (replyId: string, updatedReplyValues: Object) => {\n setReplies(prevReplies => ({\n ...prevReplies,\n [replyId]: {\n ...prevReplies[replyId],\n ...updatedReplyValues,\n },\n }));\n };\n\n const handleRemoveReplyItem = (replyId: string) => {\n setReplies(prevReplies => {\n const newReplies = { ...prevReplies };\n delete newReplies[replyId];\n return newReplies;\n });\n };\n\n const handleUpdateAnnotation = (updatedValues: Object) => {\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, ...updatedValues }));\n };\n\n const handleFetchAnnotationSuccess = ({ replies: fetchedReplies, ...normalizedAnnotation }: Annotation) => {\n setAnnotation({ ...normalizedAnnotation });\n setReplies(normalizeReplies(fetchedReplies));\n setError(undefined);\n setIsLoading(false);\n };\n\n const annotationErrorCallback = React.useCallback(\n (e: ElementsXhrError, code: string): void => {\n setIsLoading(false);\n setError({\n title: commonMessages.errorOccured,\n message: annotationErrors[code] || annotationErrors.default,\n });\n\n errorCallback(e, code, {\n error: e,\n });\n },\n [errorCallback],\n );\n\n const { handleCreate, handleDelete, handleEdit, handleFetch, handleStatusChange } = useAnnotationAPI({\n api,\n file,\n errorCallback: annotationErrorCallback,\n });\n\n React.useEffect(() => {\n if (!annotationId || (annotation && annotation.id === annotationId)) {\n return;\n }\n setIsLoading(true);\n handleFetch({ id: annotationId, successCallback: handleFetchAnnotationSuccess });\n }, [annotation, annotationId, handleFetch]);\n\n const { handleReplyCreate, handleReplyEdit, handleReplyDelete } = useRepliesAPI({\n annotationId,\n api,\n currentUser,\n fileId,\n filePermissions,\n handleRemoveReplyItem,\n handleUpdateOrCreateReplyItem,\n });\n\n const handleAnnotationCreate = (text: string) => {\n setIsLoading(true);\n\n const requestId = uniqueId('annotation_');\n\n const successCallback = (newAnnotation: Annotation) => {\n setIsLoading(false);\n emitAddAnnotationEndEvent(newAnnotation, requestId);\n onAnnotationCreate(newAnnotation);\n };\n\n const payload: NewAnnotation = {\n description: { message: text },\n target,\n };\n\n emitAddAnnotationStartEvent(payload, requestId);\n\n handleCreate({ payload, successCallback });\n };\n\n const handleAnnotationDelete = ({ id, permissions }: { id: string, permissions: AnnotationPermission }): void => {\n const annotationDeleteSuccessCallback = () => {\n // will emit event\n };\n\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));\n handleDelete({\n id,\n permissions,\n successCallback: annotationDeleteSuccessCallback,\n });\n };\n\n const onAnnotationEditSuccessCallback = (updatedAnnotation: Annotation): void => {\n handleUpdateAnnotation({\n ...updatedAnnotation,\n isPending: false,\n });\n };\n\n const handleAnnotationEdit = (id: string, text: string, permissions: AnnotationPermission): void => {\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));\n\n handleEdit({\n id,\n text,\n permissions,\n successCallback: onAnnotationEditSuccessCallback,\n });\n };\n\n const handleAnnotationStatusChange = (\n id: string,\n status: FeedItemStatus,\n permissions: AnnotationPermission,\n ): void => {\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));\n\n handleStatusChange({\n id,\n status,\n permissions,\n successCallback: onAnnotationEditSuccessCallback,\n });\n };\n\n return {\n annotation,\n error,\n isLoading,\n replies: denormalizeReplies(replies),\n annotationActions: {\n handleAnnotationCreate,\n handleAnnotationDelete,\n handleAnnotationEdit,\n handleAnnotationStatusChange,\n },\n repliesActions: {\n handleReplyCreate,\n handleReplyEdit,\n handleReplyDelete,\n },\n };\n};\n\nexport default useAnnotationThread;\n"],"file":"useAnnotationThread.js"}
1
+ {"version":3,"sources":["../../../../../src/elements/content-sidebar/activity-feed/annotation-thread/useAnnotationThread.js"],"names":["React","uniqueId","commonMessages","annotationErrors","API","useRepliesAPI","useAnnotatorEvents","useAnnotationAPI","normalizeReplies","repliesArray","reduce","prevValues","reply","id","denormalizeReplies","repliesMap","Object","keys","map","key","useAnnotationThread","annotationId","api","currentUser","errorCallback","eventEmitter","file","onAnnotationCreate","target","useState","annotation","setAnnotation","replies","setReplies","error","setError","isLoading","setIsLoading","file_version","fileVersionId","fileId","permissions","filePermissions","setAnnotationPending","prevAnnotation","isPending","handleAnnotationUpdateEnd","updatedAnnotation","onAnnotationDeleteStart","onAnnotationUpdateEnd","onAnnotationUpdateStart","emitAddAnnotationEndEvent","emitAddAnnotationStartEvent","emitAnnotationActiveChangeEvent","emitDeleteAnnotationEndEvent","emitDeleteAnnotationStartEvent","emitUpdateAnnotationEndEvent","emitUpdateAnnotationStartEvent","handleUpdateOrCreateReplyItem","replyId","updatedReplyValues","prevReplies","handleRemoveReplyItem","newReplies","handleUpdateAnnotation","updatedValues","annotationErrorCallback","useCallback","e","code","title","errorOccured","message","default","handleCreate","handleDelete","handleEdit","handleFetch","handleStatusChange","useEffect","successCallback","fetchedReplies","normalizedAnnotation","undefined","handleReplyCreate","handleReplyEdit","handleReplyDelete","handleAnnotationCreate","text","requestId","newAnnotation","payload","description","handleAnnotationDelete","annotationDeleteSuccessCallback","onAnnotationEditSuccessCallback","handleAnnotationEdit","handleAnnotationStatusChange","status","annotationActions","repliesActions"],"mappings":";;;;;;;;;;;;;;;;;;AAEA,OAAOA,KAAP,MAAkB,OAAlB;AACA,OAAOC,QAAP,MAAqB,iBAArB;AAEA,OAAOC,cAAP,MAA2B,0BAA3B;AACA,SAASC,gBAAT,QAAiC,UAAjC;AACA,OAAOC,GAAP,MAAgB,4BAAhB;AACA,OAAOC,aAAP,MAA0B,iBAA1B;AACA,SAASC,kBAAT,QAAmC,mCAAnC;AACA,OAAOC,gBAAP,MAA6B,oBAA7B;;AAOA,IAAMC,gBAAgB,GAAG,SAAnBA,gBAAmB,CAACC,YAAD,EAA0D;AAC/E,MAAI,CAACA,YAAL,EAAmB;AACf,WAAO,EAAP;AACH;;AACD,SAAOA,YAAY,CAACC,MAAb,CAAoB,UAACC,UAAD,EAAaC,KAAb,EAAuB;AAC9C,6BACOD,UADP,sBAEKC,KAAK,CAACC,EAFX,EAEgBD,KAFhB;AAIH,GALM,EAKJ,EALI,CAAP;AAMH,CAVD;;AAYA,IAAME,kBAAkB,GAAG,SAArBA,kBAAqB,CAACC,UAAD,EAAuD;AAC9E,SAAOC,MAAM,CAACC,IAAP,CAAYF,UAAZ,EAAwBG,GAAxB,CAA4B,UAAAC,GAAG;AAAA,WAAIJ,UAAU,CAACI,GAAD,CAAd;AAAA,GAA/B,CAAP;AACH,CAFD;;AA4CA,IAAMC,mBAAmB,GAAG,SAAtBA,mBAAsB,OASM;AAAA,MAR9BC,YAQ8B,QAR9BA,YAQ8B;AAAA,MAP9BC,GAO8B,QAP9BA,GAO8B;AAAA,MAN9BC,WAM8B,QAN9BA,WAM8B;AAAA,MAL9BC,aAK8B,QAL9BA,aAK8B;AAAA,MAJ9BC,YAI8B,QAJ9BA,YAI8B;AAAA,MAH9BC,IAG8B,QAH9BA,IAG8B;AAAA,MAF9BC,kBAE8B,QAF9BA,kBAE8B;AAAA,MAD9BC,MAC8B,QAD9BA,MAC8B;;AAAA,wBACM5B,KAAK,CAAC6B,QAAN,EADN;AAAA;AAAA,MACvBC,UADuB;AAAA,MACXC,aADW;;AAAA,yBAEA/B,KAAK,CAAC6B,QAAN,CAAsC,EAAtC,CAFA;AAAA;AAAA,MAEvBG,OAFuB;AAAA,MAEdC,UAFc;;AAAA,yBAGJjC,KAAK,CAAC6B,QAAN,EAHI;AAAA;AAAA,MAGvBK,KAHuB;AAAA,MAGhBC,QAHgB;;AAAA,yBAIInC,KAAK,CAAC6B,QAAN,CAAwB,KAAxB,CAJJ;AAAA;AAAA,MAIvBO,SAJuB;AAAA,MAIZC,YAJY;;AAAA,2BAMsEX,IANtE,CAMtBY,YANsB;AAAA,uDAMgB,EANhB;AAAA,MAMFC,aANE,sBAMN1B,EANM;AAAA,MAMwB2B,MANxB,GAMsEd,IANtE,CAMoBb,EANpB;AAAA,0BAMsEa,IANtE,CAMgCe,WANhC;AAAA,MAM6CC,eAN7C,kCAM+D,EAN/D;;AAQ9B,MAAMC,oBAAoB,GAAG,SAAvBA,oBAAuB,GAAM;AAC/B,QAAIb,UAAJ,EAAgB;AACZC,MAAAA,aAAa,CAAC,UAAAa,cAAc;AAAA,iCAAUA,cAAV;AAA0BC,UAAAA,SAAS,EAAE;AAArC;AAAA,OAAf,CAAb;AACH;AACJ,GAJD;;AAMA,MAAMC,yBAAyB,GAAG,SAA5BA,yBAA4B,CAACC,iBAAD,EAAmC;AACjE,QAAIjB,UAAU,IAAIiB,iBAAiB,CAAClC,EAAlB,KAAyBQ,YAA3C,EAAyD;AACrDU,MAAAA,aAAa,CAAC,UAAAa,cAAc;AAAA,iCAAUA,cAAV,MAA6BG,iBAA7B;AAAgDF,UAAAA,SAAS,EAAE;AAA3D;AAAA,OAAf,CAAb;AACH;AACJ,GAJD;;AAd8B,4BA4B1BvC,kBAAkB,CAAC;AACnBmB,IAAAA,YAAY,EAAZA,YADmB;AAEnBuB,IAAAA,uBAAuB,EAAEL,oBAFN;AAGnBM,IAAAA,qBAAqB,EAAEH,yBAHJ;AAInBI,IAAAA,uBAAuB,EAAEP;AAJN,GAAD,CA5BQ;AAAA,MAqB1BQ,yBArB0B,uBAqB1BA,yBArB0B;AAAA,MAsB1BC,2BAtB0B,uBAsB1BA,2BAtB0B;AAAA,MAuB1BC,+BAvB0B,uBAuB1BA,+BAvB0B;AAAA,MAwB1BC,4BAxB0B,uBAwB1BA,4BAxB0B;AAAA,MAyB1BC,8BAzB0B,uBAyB1BA,8BAzB0B;AAAA,MA0B1BC,4BA1B0B,uBA0B1BA,4BA1B0B;AAAA,MA2B1BC,8BA3B0B,uBA2B1BA,8BA3B0B;;AAmC9B,MAAMC,6BAA6B,GAAG,SAAhCA,6BAAgC,CAACC,OAAD,EAAkBC,kBAAlB,EAAiD;AACnF3B,IAAAA,UAAU,CAAC,UAAA4B,WAAW;AAAA,+BACfA,WADe,sBAEjBF,OAFiB,oBAGXE,WAAW,CAACF,OAAD,CAHA,MAIXC,kBAJW;AAAA,KAAZ,CAAV;AAOH,GARD;;AAUA,MAAME,qBAAqB,GAAG,SAAxBA,qBAAwB,CAACH,OAAD,EAAqB;AAC/C1B,IAAAA,UAAU,CAAC,UAAA4B,WAAW,EAAI;AACtB,UAAME,UAAU,qBAAQF,WAAR,CAAhB;;AACA,aAAOE,UAAU,CAACJ,OAAD,CAAjB;AACA,aAAOI,UAAP;AACH,KAJS,CAAV;AAKH,GAND;;AAQA,MAAMC,sBAAsB,GAAG,SAAzBA,sBAAyB,CAACC,aAAD,EAA2B;AACtDlC,IAAAA,aAAa,CAAC,UAAAa,cAAc;AAAA,+BAAUA,cAAV,MAA6BqB,aAA7B;AAAA,KAAf,CAAb;AACH,GAFD;;AAIA,MAAMC,uBAAuB,GAAGlE,KAAK,CAACmE,WAAN,CAC5B,UAACC,CAAD,EAAsBC,IAAtB,EAA6C;AACzChC,IAAAA,YAAY,CAAC,KAAD,CAAZ;AACAF,IAAAA,QAAQ,CAAC;AACLmC,MAAAA,KAAK,EAAEpE,cAAc,CAACqE,YADjB;AAELC,MAAAA,OAAO,EAAErE,gBAAgB,CAACkE,IAAD,CAAhB,IAA0BlE,gBAAgB,CAACsE;AAF/C,KAAD,CAAR;AAKAjD,IAAAA,aAAa,CAAC4C,CAAD,EAAIC,IAAJ,EAAU;AACnBnC,MAAAA,KAAK,EAAEkC;AADY,KAAV,CAAb;AAGH,GAX2B,EAY5B,CAAC5C,aAAD,CAZ4B,CAAhC;;AAzD8B,0BAwEsDjB,gBAAgB,CAAC;AACjGe,IAAAA,GAAG,EAAHA,GADiG;AAEjGI,IAAAA,IAAI,EAAJA,IAFiG;AAGjGF,IAAAA,aAAa,EAAE0C;AAHkF,GAAD,CAxEtE;AAAA,MAwEtBQ,YAxEsB,qBAwEtBA,YAxEsB;AAAA,MAwERC,YAxEQ,qBAwERA,YAxEQ;AAAA,MAwEMC,UAxEN,qBAwEMA,UAxEN;AAAA,MAwEkBC,WAxElB,qBAwEkBA,WAxElB;AAAA,MAwE+BC,kBAxE/B,qBAwE+BA,kBAxE/B;;AA8E9B9E,EAAAA,KAAK,CAAC+E,SAAN,CAAgB,YAAM;AAClB,QAAI,CAAC1D,YAAD,IAAiBe,SAAjB,IAA+BN,UAAU,IAAIA,UAAU,CAACjB,EAAX,KAAkBQ,YAAnE,EAAkF;AAC9E;AACH;;AACDgB,IAAAA,YAAY,CAAC,IAAD,CAAZ;AACAwC,IAAAA,WAAW,CAAC;AACRhE,MAAAA,EAAE,EAAEQ,YADI;AAER2D,MAAAA,eAAe,EAAE,gCAAsE;AAAA,YAA1DC,cAA0D,SAAnEjD,OAAmE;AAAA,YAAvCkD,oBAAuC;;AACnFnD,QAAAA,aAAa,mBAAMmD,oBAAN,EAAb;AACAjD,QAAAA,UAAU,CAACzB,gBAAgB,CAACyE,cAAD,CAAjB,CAAV;AACA9C,QAAAA,QAAQ,CAACgD,SAAD,CAAR;AACA9C,QAAAA,YAAY,CAAC,KAAD,CAAZ;AACAgB,QAAAA,+BAA+B,CAAC6B,oBAAoB,CAACrE,EAAtB,EAA0B0B,aAA1B,CAA/B;AACH;AARO,KAAD,CAAX;AAUH,GAfD,EAeG,CAACT,UAAD,EAAaT,YAAb,EAA2BgC,+BAA3B,EAA4Dd,aAA5D,EAA2EsC,WAA3E,EAAwFzC,SAAxF,CAfH;;AA9E8B,uBA+FoC/B,aAAa,CAAC;AAC5EgB,IAAAA,YAAY,EAAZA,YAD4E;AAE5EC,IAAAA,GAAG,EAAHA,GAF4E;AAG5EC,IAAAA,WAAW,EAAXA,WAH4E;AAI5EiB,IAAAA,MAAM,EAANA,MAJ4E;AAK5EE,IAAAA,eAAe,EAAfA,eAL4E;AAM5EoB,IAAAA,qBAAqB,EAArBA,qBAN4E;AAO5EJ,IAAAA,6BAA6B,EAA7BA;AAP4E,GAAD,CA/FjD;AAAA,MA+FtB0B,iBA/FsB,kBA+FtBA,iBA/FsB;AAAA,MA+FHC,eA/FG,kBA+FHA,eA/FG;AAAA,MA+FcC,iBA/Fd,kBA+FcA,iBA/Fd;;AAyG9B,MAAMC,sBAAsB,GAAG,SAAzBA,sBAAyB,CAACC,IAAD,EAAkB;AAC7CnD,IAAAA,YAAY,CAAC,IAAD,CAAZ;AAEA,QAAMoD,SAAS,GAAGxF,QAAQ,CAAC,aAAD,CAA1B;;AAEA,QAAM+E,eAAe,GAAG,SAAlBA,eAAkB,CAACU,aAAD,EAA+B;AACnDrD,MAAAA,YAAY,CAAC,KAAD,CAAZ;AACAc,MAAAA,yBAAyB,CAACuC,aAAD,EAAgBD,SAAhB,CAAzB;AACA9D,MAAAA,kBAAkB,CAAC+D,aAAD,CAAlB;AACH,KAJD;;AAMA,QAAMC,OAAsB,GAAG;AAC3BC,MAAAA,WAAW,EAAE;AAAEpB,QAAAA,OAAO,EAAEgB;AAAX,OADc;AAE3B5D,MAAAA,MAAM,EAANA;AAF2B,KAA/B;AAKAwB,IAAAA,2BAA2B,CAACuC,OAAD,EAAUF,SAAV,CAA3B;AAEAf,IAAAA,YAAY,CAAC;AAAEiB,MAAAA,OAAO,EAAPA,OAAF;AAAWX,MAAAA,eAAe,EAAfA;AAAX,KAAD,CAAZ;AACH,GAnBD;;AAqBA,MAAMa,sBAAsB,GAAG,SAAzBA,sBAAyB,QAAkF;AAAA,QAA/EhF,EAA+E,SAA/EA,EAA+E;AAAA,QAA3E4B,WAA2E,SAA3EA,WAA2E;;AAC7G,QAAMqD,+BAA+B,GAAG,SAAlCA,+BAAkC,GAAM;AAC1CxC,MAAAA,4BAA4B,CAACzC,EAAD,CAA5B;AACH,KAFD;;AAIAkB,IAAAA,aAAa,CAAC,UAAAa,cAAc;AAAA,+BAAUA,cAAV;AAA0BC,QAAAA,SAAS,EAAE;AAArC;AAAA,KAAf,CAAb;AAEAU,IAAAA,8BAA8B,CAAC1C,EAAD,CAA9B;AAEA8D,IAAAA,YAAY,CAAC;AACT9D,MAAAA,EAAE,EAAFA,EADS;AAET4B,MAAAA,WAAW,EAAXA,WAFS;AAGTuC,MAAAA,eAAe,EAAEc;AAHR,KAAD,CAAZ;AAKH,GAdD;;AAgBA,MAAMC,+BAA+B,GAAG,SAAlCA,+BAAkC,CAAChD,iBAAD,EAAyC;AAC7EiB,IAAAA,sBAAsB,mBACfjB,iBADe;AAElBF,MAAAA,SAAS,EAAE;AAFO,OAAtB;AAKAW,IAAAA,4BAA4B,CAACT,iBAAD,CAA5B;AACH,GAPD;;AASA,MAAMiD,oBAAoB,GAAG,SAAvBA,oBAAuB,CAACnF,EAAD,EAAa2E,IAAb,EAA2B/C,WAA3B,EAAuE;AAChGV,IAAAA,aAAa,CAAC,UAAAa,cAAc;AAAA,+BAAUA,cAAV;AAA0BC,QAAAA,SAAS,EAAE;AAArC;AAAA,KAAf,CAAb;AAEAY,IAAAA,8BAA8B,CAAC;AAC3B5C,MAAAA,EAAE,EAAFA,EAD2B;AAE3B+E,MAAAA,WAAW,EAAE;AAAEpB,QAAAA,OAAO,EAAEgB;AAAX;AAFc,KAAD,CAA9B;AAKAZ,IAAAA,UAAU,CAAC;AACP/D,MAAAA,EAAE,EAAFA,EADO;AAEP2E,MAAAA,IAAI,EAAJA,IAFO;AAGP/C,MAAAA,WAAW,EAAXA,WAHO;AAIPuC,MAAAA,eAAe,EAAEe;AAJV,KAAD,CAAV;AAMH,GAdD;;AAgBA,MAAME,4BAA4B,GAAG,SAA/BA,4BAA+B,CACjCpF,EADiC,EAEjCqF,MAFiC,EAGjCzD,WAHiC,EAI1B;AACPV,IAAAA,aAAa,CAAC,UAAAa,cAAc;AAAA,+BAAUA,cAAV;AAA0BC,QAAAA,SAAS,EAAE;AAArC;AAAA,KAAf,CAAb;AAEAiC,IAAAA,kBAAkB,CAAC;AACfjE,MAAAA,EAAE,EAAFA,EADe;AAEfqF,MAAAA,MAAM,EAANA,MAFe;AAGfzD,MAAAA,WAAW,EAAXA,WAHe;AAIfuC,MAAAA,eAAe,EAAEe;AAJF,KAAD,CAAlB;AAMH,GAbD;;AAeA,SAAO;AACHjE,IAAAA,UAAU,EAAVA,UADG;AAEHI,IAAAA,KAAK,EAALA,KAFG;AAGHE,IAAAA,SAAS,EAATA,SAHG;AAIHJ,IAAAA,OAAO,EAAElB,kBAAkB,CAACkB,OAAD,CAJxB;AAKHmE,IAAAA,iBAAiB,EAAE;AACfZ,MAAAA,sBAAsB,EAAtBA,sBADe;AAEfM,MAAAA,sBAAsB,EAAtBA,sBAFe;AAGfG,MAAAA,oBAAoB,EAApBA,oBAHe;AAIfC,MAAAA,4BAA4B,EAA5BA;AAJe,KALhB;AAWHG,IAAAA,cAAc,EAAE;AACZhB,MAAAA,iBAAiB,EAAjBA,iBADY;AAEZC,MAAAA,eAAe,EAAfA,eAFY;AAGZC,MAAAA,iBAAiB,EAAjBA;AAHY;AAXb,GAAP;AAiBH,CAhND;;AAkNA,eAAelE,mBAAf","sourcesContent":["// @flow\n\nimport React from 'react';\nimport uniqueId from 'lodash/uniqueId';\nimport type EventEmitter from 'events';\nimport commonMessages from '../../../common/messages';\nimport { annotationErrors } from './errors';\nimport API from '../../../../api/APIFactory';\nimport useRepliesAPI from './useRepliesAPI';\nimport { useAnnotatorEvents } from '../../../common/annotator-context';\nimport useAnnotationAPI from './useAnnotationAPI';\nimport type { Annotation, AnnotationPermission, NewAnnotation, Target } from '../../../../common/types/annotations';\nimport type { BoxItem, User } from '../../../../common/types/core';\nimport type { BoxCommentPermission, Comment, FeedItemStatus } from '../../../../common/types/feed';\nimport type { ElementOrigin, ElementsXhrError } from '../../../../common/types/api';\nimport type { AnnotationThreadError } from './types';\n\nconst normalizeReplies = (repliesArray?: Array<Comment>): { [string]: Comment } => {\n if (!repliesArray) {\n return {};\n }\n return repliesArray.reduce((prevValues, reply) => {\n return {\n ...prevValues,\n [reply.id]: reply,\n };\n }, {});\n};\n\nconst denormalizeReplies = (repliesMap: { [string]: Comment }): Array<Comment> => {\n return Object.keys(repliesMap).map(key => repliesMap[key]);\n};\n\ntype Props = {\n annotationId?: string,\n api: API,\n currentUser: User,\n errorCallback: (\n error: ElementsXhrError | Error,\n code: string,\n contextInfo?: Object,\n origin?: ElementOrigin,\n ) => void,\n eventEmitter: EventEmitter,\n file: BoxItem,\n onAnnotationCreate: (annotation: Annotation) => void,\n target: Target,\n};\n\ntype UseAnnotationThread = {\n annotation?: Annotation,\n annotationActions: {\n handleAnnotationCreate: (text: string) => void,\n handleAnnotationDelete: ({ id: string, permissions: AnnotationPermission }) => void,\n handleAnnotationEdit: (id: string, text: string, permissions: AnnotationPermission) => void,\n handleAnnotationStatusChange: (id: string, status: FeedItemStatus, permissions: AnnotationPermission) => void,\n },\n error?: AnnotationThreadError,\n isLoading: boolean,\n replies: Array<Comment>,\n repliesActions: {\n handleReplyCreate: (message: string) => void,\n handleReplyDelete: ({ id: string, permissions: BoxCommentPermission }) => void,\n handleReplyEdit: (\n replyId: string,\n message: string,\n status?: FeedItemStatus,\n hasMention?: boolean,\n permissions: BoxCommentPermission,\n ) => void,\n },\n};\n\nconst useAnnotationThread = ({\n annotationId,\n api,\n currentUser,\n errorCallback,\n eventEmitter,\n file,\n onAnnotationCreate,\n target,\n}: Props): UseAnnotationThread => {\n const [annotation, setAnnotation] = React.useState<Annotation | typeof undefined>();\n const [replies, setReplies] = React.useState<{ [string]: Comment }>({});\n const [error, setError] = React.useState<AnnotationThreadError | typeof undefined>();\n const [isLoading, setIsLoading] = React.useState<boolean>(false);\n\n const { file_version: { id: fileVersionId } = {}, id: fileId, permissions: filePermissions = {} } = file;\n\n const setAnnotationPending = () => {\n if (annotation) {\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));\n }\n };\n\n const handleAnnotationUpdateEnd = (updatedAnnotation: Annotation) => {\n if (annotation && updatedAnnotation.id === annotationId) {\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, ...updatedAnnotation, isPending: false }));\n }\n };\n\n const {\n emitAddAnnotationEndEvent,\n emitAddAnnotationStartEvent,\n emitAnnotationActiveChangeEvent,\n emitDeleteAnnotationEndEvent,\n emitDeleteAnnotationStartEvent,\n emitUpdateAnnotationEndEvent,\n emitUpdateAnnotationStartEvent,\n } = useAnnotatorEvents({\n eventEmitter,\n onAnnotationDeleteStart: setAnnotationPending,\n onAnnotationUpdateEnd: handleAnnotationUpdateEnd,\n onAnnotationUpdateStart: setAnnotationPending,\n });\n\n const handleUpdateOrCreateReplyItem = (replyId: string, updatedReplyValues: Object) => {\n setReplies(prevReplies => ({\n ...prevReplies,\n [replyId]: {\n ...prevReplies[replyId],\n ...updatedReplyValues,\n },\n }));\n };\n\n const handleRemoveReplyItem = (replyId: string) => {\n setReplies(prevReplies => {\n const newReplies = { ...prevReplies };\n delete newReplies[replyId];\n return newReplies;\n });\n };\n\n const handleUpdateAnnotation = (updatedValues: Object) => {\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, ...updatedValues }));\n };\n\n const annotationErrorCallback = React.useCallback(\n (e: ElementsXhrError, code: string): void => {\n setIsLoading(false);\n setError({\n title: commonMessages.errorOccured,\n message: annotationErrors[code] || annotationErrors.default,\n });\n\n errorCallback(e, code, {\n error: e,\n });\n },\n [errorCallback],\n );\n\n const { handleCreate, handleDelete, handleEdit, handleFetch, handleStatusChange } = useAnnotationAPI({\n api,\n file,\n errorCallback: annotationErrorCallback,\n });\n\n React.useEffect(() => {\n if (!annotationId || isLoading || (annotation && annotation.id === annotationId)) {\n return;\n }\n setIsLoading(true);\n handleFetch({\n id: annotationId,\n successCallback: ({ replies: fetchedReplies, ...normalizedAnnotation }: Annotation) => {\n setAnnotation({ ...normalizedAnnotation });\n setReplies(normalizeReplies(fetchedReplies));\n setError(undefined);\n setIsLoading(false);\n emitAnnotationActiveChangeEvent(normalizedAnnotation.id, fileVersionId);\n },\n });\n }, [annotation, annotationId, emitAnnotationActiveChangeEvent, fileVersionId, handleFetch, isLoading]);\n\n const { handleReplyCreate, handleReplyEdit, handleReplyDelete } = useRepliesAPI({\n annotationId,\n api,\n currentUser,\n fileId,\n filePermissions,\n handleRemoveReplyItem,\n handleUpdateOrCreateReplyItem,\n });\n\n const handleAnnotationCreate = (text: string) => {\n setIsLoading(true);\n\n const requestId = uniqueId('annotation_');\n\n const successCallback = (newAnnotation: Annotation) => {\n setIsLoading(false);\n emitAddAnnotationEndEvent(newAnnotation, requestId);\n onAnnotationCreate(newAnnotation);\n };\n\n const payload: NewAnnotation = {\n description: { message: text },\n target,\n };\n\n emitAddAnnotationStartEvent(payload, requestId);\n\n handleCreate({ payload, successCallback });\n };\n\n const handleAnnotationDelete = ({ id, permissions }: { id: string, permissions: AnnotationPermission }): void => {\n const annotationDeleteSuccessCallback = () => {\n emitDeleteAnnotationEndEvent(id);\n };\n\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));\n\n emitDeleteAnnotationStartEvent(id);\n\n handleDelete({\n id,\n permissions,\n successCallback: annotationDeleteSuccessCallback,\n });\n };\n\n const onAnnotationEditSuccessCallback = (updatedAnnotation: Annotation): void => {\n handleUpdateAnnotation({\n ...updatedAnnotation,\n isPending: false,\n });\n\n emitUpdateAnnotationEndEvent(updatedAnnotation);\n };\n\n const handleAnnotationEdit = (id: string, text: string, permissions: AnnotationPermission): void => {\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));\n\n emitUpdateAnnotationStartEvent({\n id,\n description: { message: text },\n });\n\n handleEdit({\n id,\n text,\n permissions,\n successCallback: onAnnotationEditSuccessCallback,\n });\n };\n\n const handleAnnotationStatusChange = (\n id: string,\n status: FeedItemStatus,\n permissions: AnnotationPermission,\n ): void => {\n setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));\n\n handleStatusChange({\n id,\n status,\n permissions,\n successCallback: onAnnotationEditSuccessCallback,\n });\n };\n\n return {\n annotation,\n error,\n isLoading,\n replies: denormalizeReplies(replies),\n annotationActions: {\n handleAnnotationCreate,\n handleAnnotationDelete,\n handleAnnotationEdit,\n handleAnnotationStatusChange,\n },\n repliesActions: {\n handleReplyCreate,\n handleReplyEdit,\n handleReplyDelete,\n },\n };\n};\n\nexport default useAnnotationThread;\n"],"file":"useAnnotationThread.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "box-ui-elements",
3
- "version": "16.1.0-beta.32",
3
+ "version": "16.1.0-beta.33",
4
4
  "description": "Box UI Elements",
5
5
  "author": "Box (https://www.box.com/)",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -6,6 +6,10 @@
6
6
 
7
7
  .bcs-ActivityThread {
8
8
  box-shadow: none;
9
+
10
+ &:hover {
11
+ background: none;
12
+ }
9
13
  }
10
14
 
11
15
  .bcs-ActivityThread-content {
@@ -3,14 +3,11 @@ import { annotation as mockAnnotation } from '../../../../../__mocks__/annotatio
3
3
  export default () => ({
4
4
  annotation: mockAnnotation,
5
5
  annotationActions: {
6
+ handleCreate: jest.fn(),
6
7
  handleDelete: jest.fn(),
7
8
  handleEdit: jest.fn(),
8
9
  handleResolve: jest.fn(),
9
10
  },
10
- annotationEvents: {
11
- handleAnnotationCreateStart: jest.fn(),
12
- handleAnnotationCreateEnd: jest.fn(),
13
- },
14
11
  error: {},
15
12
  isLoading: false,
16
13
  replies: [],
@@ -50,7 +50,7 @@ describe('elements/content-sidebar/activity-feed/annotation-thread/AnnotationThr
50
50
  expect(getByTestId('annotation-create')).toHaveClass('is-pending');
51
51
  });
52
52
 
53
- test('Should handle create', () => {
53
+ test('Should call onFormSubmit on create', () => {
54
54
  const onFormSubmit = jest.fn();
55
55
 
56
56
  const { getByText } = getWrapper({ onFormSubmit });
@@ -60,7 +60,7 @@ describe('elements/content-sidebar/activity-feed/annotation-thread/AnnotationThr
60
60
  expect(onFormSubmit).toBeCalledWith('example message');
61
61
  });
62
62
 
63
- test('Should call handleCancel on cancel', () => {
63
+ test('Should call onFormCancel on cancel', () => {
64
64
  const onFormCancel = jest.fn();
65
65
 
66
66
  const { getByText } = getWrapper({ onFormCancel });
@@ -18,6 +18,7 @@ describe('src/elements/content-sidebar/activity-feed/useAnnotationThread', () =>
18
18
  const mockUseAnnotatorEventsResult = {
19
19
  emitAddAnnotationEndEvent: jest.fn(),
20
20
  emitAddAnnotationStartEvent: jest.fn(),
21
+ emitAnnotationActiveChangeEvent: jest.fn(),
21
22
  emitDeleteAnnotationEndEvent: jest.fn(),
22
23
  emitDeleteAnnotationStartEvent: jest.fn(),
23
24
  emitUpdateAnnotationEndEvent: jest.fn(),
@@ -40,16 +41,19 @@ describe('src/elements/content-sidebar/activity-feed/useAnnotationThread', () =>
40
41
  const filePermissions = { can_annotate: true, can_view_annotations: true };
41
42
  const errorCallback = jest.fn();
42
43
 
44
+ const getFileProps = props => ({
45
+ id: 'fileId',
46
+ file_version: { id: '123' },
47
+ permissions: filePermissions,
48
+ ...props,
49
+ });
50
+
43
51
  const getHook = props =>
44
52
  renderHook(() =>
45
53
  useAnnotationThread({
46
54
  api: {},
47
55
  currentUser: {},
48
- file: {
49
- id: 'fileId',
50
- file_version: { id: '123' },
51
- permissions: filePermissions,
52
- },
56
+ file: getFileProps(),
53
57
  annotationId: annotation.id,
54
58
  errorCallback,
55
59
  eventEmitter: {},
@@ -77,20 +81,85 @@ describe('src/elements/content-sidebar/activity-feed/useAnnotationThread', () =>
77
81
  expect(result.current.replies).toEqual([]);
78
82
  });
79
83
 
80
- test('should return correct values after fetch', () => {
84
+ test('should return correct values after fetch and call emitAnnotationActiveChangeEvent', () => {
81
85
  const { replies, ...normalizedAnnotation } = annotation;
82
86
  const mockHandleFetch = jest.fn().mockImplementation(({ successCallback }) => successCallback(annotation));
83
87
  useAnnotationAPI.mockImplementation(() => ({
84
88
  ...mockUseAnnotationAPIResult,
85
89
  handleFetch: mockHandleFetch,
86
90
  }));
91
+ const fileVersionId = '456';
92
+ const file = getFileProps({ file_version: { id: fileVersionId } });
87
93
 
88
- const { result } = getHook();
94
+ const { result } = getHook({ file });
89
95
 
90
96
  expect(result.current.annotation).toEqual(normalizedAnnotation);
91
97
  expect(result.current.isLoading).toEqual(false);
92
98
  expect(result.current.error).toEqual(undefined);
93
99
  expect(result.current.replies).toEqual(replies);
100
+ expect(mockUseAnnotatorEventsResult.emitAnnotationActiveChangeEvent).toBeCalledWith(
101
+ annotation.id,
102
+ fileVersionId,
103
+ );
104
+ });
105
+
106
+ describe('handleAnnotationEdit', () => {
107
+ test('should call handleEdit from useAnnotationAPI and call emitUpdateAnnotationStartEvent + emitUpdateAnnotationEndEvent', () => {
108
+ const updatedText = 'new text';
109
+ const updatedAnnotation = {
110
+ id: annotation.id,
111
+ description: { message: updatedText },
112
+ };
113
+ const mockHandleEdit = jest.fn().mockImplementation(({ successCallback }) => {
114
+ successCallback(updatedAnnotation);
115
+ });
116
+ useAnnotationAPI.mockImplementation(() => ({
117
+ ...mockUseAnnotationAPIResult,
118
+ handleEdit: mockHandleEdit,
119
+ }));
120
+
121
+ const { result } = getHook();
122
+ act(() => {
123
+ result.current.annotationActions.handleAnnotationEdit(annotation.id, updatedText, { can_edit: true });
124
+ });
125
+
126
+ expect(mockHandleEdit).toBeCalledWith({
127
+ id: annotation.id,
128
+ permissions: { can_edit: true },
129
+ text: updatedText,
130
+ successCallback: expect.any(Function),
131
+ });
132
+ expect(mockUseAnnotatorEventsResult.emitUpdateAnnotationStartEvent).toBeCalledWith(updatedAnnotation);
133
+ expect(mockUseAnnotatorEventsResult.emitUpdateAnnotationEndEvent).toBeCalledWith(updatedAnnotation);
134
+ });
135
+ });
136
+
137
+ describe('handleAnnotationDelete', () => {
138
+ test('should call handleDelete from useAnnotationAPI and call emitDeleteAnnotationStartEvent + emitDeleteAnnotationEndEvent', () => {
139
+ const mockHandleDelete = jest.fn().mockImplementation(({ successCallback }) => {
140
+ successCallback();
141
+ });
142
+ useAnnotationAPI.mockImplementation(() => ({
143
+ ...mockUseAnnotationAPIResult,
144
+ handleDelete: mockHandleDelete,
145
+ }));
146
+
147
+ const { result } = getHook();
148
+ act(() => {
149
+ result.current.annotationActions.handleAnnotationDelete({
150
+ id: annotation.id,
151
+ permissions: { can_delete: true },
152
+ });
153
+ });
154
+
155
+ expect(mockHandleDelete).toBeCalledWith({
156
+ id: annotation.id,
157
+ permissions: { can_delete: true },
158
+ successCallback: expect.any(Function),
159
+ });
160
+ expect(mockUseAnnotatorEventsResult.emitDeleteAnnotationStartEvent).toBeCalledWith(annotation.id);
161
+ expect(mockUseAnnotatorEventsResult.emitDeleteAnnotationEndEvent).toBeCalledWith(annotation.id);
162
+ });
94
163
  });
95
164
 
96
165
  describe('useAnnotationAPI', () => {
@@ -143,48 +212,6 @@ describe('src/elements/content-sidebar/activity-feed/useAnnotationThread', () =>
143
212
  expect(mockOnAnnotationCreate).toBeCalledWith(createdAnnotation);
144
213
  });
145
214
 
146
- test('should call handleAnnotationEdit with correct params', () => {
147
- const mockHandleEdit = jest.fn();
148
- useAnnotationAPI.mockImplementation(() => ({
149
- ...mockUseAnnotationAPIResult,
150
- handleEdit: mockHandleEdit,
151
- }));
152
-
153
- const { result } = getHook();
154
- act(() => {
155
- result.current.annotationActions.handleAnnotationEdit(annotation.id, 'new text', { can_edit: true });
156
- });
157
-
158
- expect(mockHandleEdit).toBeCalledWith({
159
- id: annotation.id,
160
- permissions: { can_edit: true },
161
- text: 'new text',
162
- successCallback: expect.any(Function),
163
- });
164
- });
165
-
166
- test('should call handleAnnotationDelete with correct params', () => {
167
- const mockHandleDelete = jest.fn();
168
- useAnnotationAPI.mockImplementation(() => ({
169
- ...mockUseAnnotationAPIResult,
170
- handleDelete: mockHandleDelete,
171
- }));
172
-
173
- const { result } = getHook();
174
- act(() => {
175
- result.current.annotationActions.handleAnnotationDelete({
176
- id: annotation.id,
177
- permissions: { can_delete: true },
178
- });
179
- });
180
-
181
- expect(mockHandleDelete).toBeCalledWith({
182
- id: annotation.id,
183
- permissions: { can_delete: true },
184
- successCallback: expect.any(Function),
185
- });
186
- });
187
-
188
215
  test('should call handleAnnotationStatusChange with correct params and set annotation state to pending', () => {
189
216
  const mockHandleStatusChange = jest.fn();
190
217
  useAnnotationAPI.mockImplementation(() => ({
@@ -86,7 +86,7 @@ const useAnnotationThread = ({
86
86
  const [error, setError] = React.useState<AnnotationThreadError | typeof undefined>();
87
87
  const [isLoading, setIsLoading] = React.useState<boolean>(false);
88
88
 
89
- const { id: fileId, permissions: filePermissions = {} } = file;
89
+ const { file_version: { id: fileVersionId } = {}, id: fileId, permissions: filePermissions = {} } = file;
90
90
 
91
91
  const setAnnotationPending = () => {
92
92
  if (annotation) {
@@ -100,7 +100,15 @@ const useAnnotationThread = ({
100
100
  }
101
101
  };
102
102
 
103
- const { emitAddAnnotationEndEvent, emitAddAnnotationStartEvent } = useAnnotatorEvents({
103
+ const {
104
+ emitAddAnnotationEndEvent,
105
+ emitAddAnnotationStartEvent,
106
+ emitAnnotationActiveChangeEvent,
107
+ emitDeleteAnnotationEndEvent,
108
+ emitDeleteAnnotationStartEvent,
109
+ emitUpdateAnnotationEndEvent,
110
+ emitUpdateAnnotationStartEvent,
111
+ } = useAnnotatorEvents({
104
112
  eventEmitter,
105
113
  onAnnotationDeleteStart: setAnnotationPending,
106
114
  onAnnotationUpdateEnd: handleAnnotationUpdateEnd,
@@ -129,13 +137,6 @@ const useAnnotationThread = ({
129
137
  setAnnotation(prevAnnotation => ({ ...prevAnnotation, ...updatedValues }));
130
138
  };
131
139
 
132
- const handleFetchAnnotationSuccess = ({ replies: fetchedReplies, ...normalizedAnnotation }: Annotation) => {
133
- setAnnotation({ ...normalizedAnnotation });
134
- setReplies(normalizeReplies(fetchedReplies));
135
- setError(undefined);
136
- setIsLoading(false);
137
- };
138
-
139
140
  const annotationErrorCallback = React.useCallback(
140
141
  (e: ElementsXhrError, code: string): void => {
141
142
  setIsLoading(false);
@@ -158,12 +159,21 @@ const useAnnotationThread = ({
158
159
  });
159
160
 
160
161
  React.useEffect(() => {
161
- if (!annotationId || (annotation && annotation.id === annotationId)) {
162
+ if (!annotationId || isLoading || (annotation && annotation.id === annotationId)) {
162
163
  return;
163
164
  }
164
165
  setIsLoading(true);
165
- handleFetch({ id: annotationId, successCallback: handleFetchAnnotationSuccess });
166
- }, [annotation, annotationId, handleFetch]);
166
+ handleFetch({
167
+ id: annotationId,
168
+ successCallback: ({ replies: fetchedReplies, ...normalizedAnnotation }: Annotation) => {
169
+ setAnnotation({ ...normalizedAnnotation });
170
+ setReplies(normalizeReplies(fetchedReplies));
171
+ setError(undefined);
172
+ setIsLoading(false);
173
+ emitAnnotationActiveChangeEvent(normalizedAnnotation.id, fileVersionId);
174
+ },
175
+ });
176
+ }, [annotation, annotationId, emitAnnotationActiveChangeEvent, fileVersionId, handleFetch, isLoading]);
167
177
 
168
178
  const { handleReplyCreate, handleReplyEdit, handleReplyDelete } = useRepliesAPI({
169
179
  annotationId,
@@ -198,10 +208,13 @@ const useAnnotationThread = ({
198
208
 
199
209
  const handleAnnotationDelete = ({ id, permissions }: { id: string, permissions: AnnotationPermission }): void => {
200
210
  const annotationDeleteSuccessCallback = () => {
201
- // will emit event
211
+ emitDeleteAnnotationEndEvent(id);
202
212
  };
203
213
 
204
214
  setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));
215
+
216
+ emitDeleteAnnotationStartEvent(id);
217
+
205
218
  handleDelete({
206
219
  id,
207
220
  permissions,
@@ -214,11 +227,18 @@ const useAnnotationThread = ({
214
227
  ...updatedAnnotation,
215
228
  isPending: false,
216
229
  });
230
+
231
+ emitUpdateAnnotationEndEvent(updatedAnnotation);
217
232
  };
218
233
 
219
234
  const handleAnnotationEdit = (id: string, text: string, permissions: AnnotationPermission): void => {
220
235
  setAnnotation(prevAnnotation => ({ ...prevAnnotation, isPending: true }));
221
236
 
237
+ emitUpdateAnnotationStartEvent({
238
+ id,
239
+ description: { message: text },
240
+ });
241
+
222
242
  handleEdit({
223
243
  id,
224
244
  text,