Skip to content

Commit fb84aee

Browse files
shahzadazizmergify[bot]
authored andcommitted
feat(new-tasks): Fetch task collaborators (#1286)
* fix: Fetch task collaborators * fix: Fetch task collaborators on modal open * fix: fetch collaborator promise * fix: getTaskCollaborator test * fix: add tests * fix: return if there is no fileID
1 parent 3d486ff commit fb84aee

File tree

8 files changed

+111
-12
lines changed

8 files changed

+111
-12
lines changed

i18n/en-US.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,8 @@ be.taskActionErrorTitle = Error
366366
be.taskApprove = Complete
367367
# Error message when approving a task fails
368368
be.taskApproveErrorMessage = An error has occurred while approving this task. Please refresh the page and try again.
369+
# Error message when we failed to load the collaborators when user tries to edit a task
370+
be.taskCollaboratorLoadErrorMessage = An error has occurred while loading collaborators for this task. Please try again.
369371
# Error message when completing a task fails
370372
be.taskCompleteErrorMessage = An error has occurred while completing this task. Please refresh the page and try again.
371373
# Error message when a task creation fails

src/api/tasks/TaskCollaborators.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616

1717
class TaskCollaborators extends TasksBase {
1818
getUrlForTaskCollaborators(taskId: string): string {
19-
return `${this.getBaseApiUrl()}/undoc/tasks/${taskId}/task_collaborators?limit=${API_PAGE_LIMIT}`;
19+
return `${this.getBaseApiUrl()}/undoc/tasks/${taskId}/task_collaborators?role=ASSIGNEE&limit=${API_PAGE_LIMIT}`;
2020
}
2121

2222
getUrlForTaskCollaboratorCreate(): string {

src/api/tasks/__tests__/TaskCollaborators-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ describe('api/TaskCollaborators', () => {
129129

130130
expect(taskCollaborators.get).toBeCalledWith({
131131
id: FILE_ID,
132-
url: `${BASE_URL}/undoc/tasks/${taskId}/task_collaborators?limit=${API_PAGE_LIMIT}`,
132+
url: `${BASE_URL}/undoc/tasks/${taskId}/task_collaborators?role=ASSIGNEE&limit=${API_PAGE_LIMIT}`,
133133
successCallback,
134134
errorCallback,
135135
});

src/elements/common/messages.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,11 @@ const messages = defineMessages({
818818
description: 'Error message when a task deletion fails',
819819
defaultMessage: 'There was an error while deleting this task. Please refresh the page and try again.',
820820
},
821+
taskCollaboratorLoadErrorMessage: {
822+
id: 'be.taskCollaboratorLoadErrorMessage',
823+
description: 'Error message when we failed to load the collaborators when user tries to edit a task',
824+
defaultMessage: 'An error has occurred while loading collaborators for this task. Please try again.',
825+
},
821826
completedAssignment: {
822827
id: 'be.completedAssignment',
823828
defaultMessage: 'Completed',

src/elements/content-sidebar/TaskModal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type TaskModalProps = {
1616
isTaskFormOpen: boolean,
1717
onModalClose: () => void,
1818
onSubmitError: (e: ElementsXhrError) => void,
19-
onSubmitSuccess: () => void,
19+
onSubmitSuccess: () => any,
2020
taskFormProps: TaskFormProps,
2121
taskType: TaskType,
2222
};

src/elements/content-sidebar/activity-feed/comment/Comment.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type Props = {
4646
modified_at?: string | number,
4747
onDelete?: Function,
4848
onEdit?: Function,
49-
onEditClick?: () => void,
49+
onEditClick?: () => any,
5050
permissions?: BoxItemPermission,
5151
tagged_message: string,
5252
translatedTaggedMessage?: string,

src/elements/content-sidebar/activity-feed/task-new/Task.js

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import messages from '../../../common/messages';
88
import CommentInlineError from '../comment/CommentInlineError';
99
import IconTaskApproval from '../../../../icons/two-toned/IconTaskApproval';
1010
import IconTaskGeneral from '../../../../icons/two-toned/IconTaskGeneral';
11+
import { withAPIContext } from '../../../common/api-context';
12+
13+
import API from '../../../../api/APIFactory';
1114
import {
1215
TASK_NEW_APPROVED,
1316
TASK_NEW_REJECTED,
@@ -30,6 +33,7 @@ import './Task.scss';
3033

3134
type Props = {|
3235
...TaskNew,
36+
api: API,
3337
currentUser: User,
3438
error?: ActionItemError,
3539
features?: FeatureConfig,
@@ -47,7 +51,10 @@ type Props = {|
4751
|};
4852

4953
type State = {
54+
assigned_to: TaskAssigneeCollection,
5055
isEditing: boolean,
56+
isLoading: boolean,
57+
loadCollabError: ?ActionItemError,
5158
modalError: ?ElementsXhrError,
5259
};
5360

@@ -67,12 +74,23 @@ const getMessageForTask = (isCurrentUser: boolean, taskType: TaskType) => {
6774

6875
class Task extends React.Component<Props, State> {
6976
state = {
77+
loadCollabError: undefined,
78+
assigned_to: this.props.assigned_to,
7079
modalError: undefined,
7180
isEditing: false,
81+
isLoading: false,
7282
};
7383

74-
handleEditClick = (): void => {
75-
this.setState({ isEditing: true });
84+
handleEditClick = async () => {
85+
const { assigned_to } = this.state;
86+
87+
if (assigned_to.next_marker) {
88+
this.fetchTaskCollaborators().then(() => {
89+
this.setState({ isEditing: true });
90+
});
91+
} else {
92+
this.setState({ isEditing: true });
93+
}
7694
};
7795

7896
handleModalClose = () => {
@@ -88,7 +106,7 @@ class Task extends React.Component<Props, State> {
88106
};
89107

90108
getUsersFromTask = (): SelectorItems => {
91-
const { assigned_to } = this.props;
109+
const { assigned_to } = this.state;
92110

93111
return (
94112
assigned_to &&
@@ -105,9 +123,48 @@ class Task extends React.Component<Props, State> {
105123
);
106124
};
107125

126+
fetchTaskCollaborators = (): Promise<any> => {
127+
const { id, api, task_links } = this.props;
128+
const { entries } = task_links;
129+
let fileId = '';
130+
131+
if (entries[0] && entries[0].target) {
132+
fileId = entries[0].target.id;
133+
}
134+
135+
if (!fileId) {
136+
return Promise.reject();
137+
}
138+
139+
this.setState({ isLoading: true });
140+
141+
return new Promise((resolve, reject) => {
142+
api.getTaskCollaboratorsAPI(false).getTaskCollaborators({
143+
task: { id },
144+
file: { id: fileId },
145+
errorCallback: () => {
146+
const { errorOccured, taskCollaboratorLoadErrorMessage } = messages;
147+
148+
this.setState(
149+
{
150+
isLoading: false,
151+
loadCollabError: {
152+
message: taskCollaboratorLoadErrorMessage,
153+
title: errorOccured,
154+
},
155+
},
156+
reject,
157+
);
158+
},
159+
successCallback: assigned_to => {
160+
this.setState({ assigned_to, isLoading: false }, resolve);
161+
},
162+
});
163+
});
164+
};
165+
108166
render() {
109167
const {
110-
assigned_to,
111168
created_at,
112169
created_by,
113170
currentUser,
@@ -131,7 +188,7 @@ class Task extends React.Component<Props, State> {
131188
translations,
132189
} = this.props;
133190

134-
const { modalError, isEditing } = this.state;
191+
const { assigned_to, modalError, isEditing, isLoading, loadCollabError } = this.state;
135192

136193
const taskPermissions = {
137194
...permissions,
@@ -151,13 +208,14 @@ class Task extends React.Component<Props, State> {
151208
(status === TASK_NEW_NOT_STARTED || status === TASK_NEW_IN_PROGRESS);
152209

153210
const TaskTypeIcon = task_type === TASK_TYPE_APPROVAL ? IconTaskApproval : IconTaskGeneral;
211+
const inlineError = loadCollabError || error;
154212

155213
return (
156214
<div className="bcs-task-container">
157-
{error ? <CommentInlineError {...error} /> : null}
215+
{inlineError ? <CommentInlineError {...inlineError} /> : null}
158216
<div
159217
className={classNames('bcs-task', {
160-
'bcs-is-pending': isPending || error,
218+
'bcs-is-pending': isPending || isLoading,
161219
})}
162220
data-testid="task-card"
163221
>
@@ -249,4 +307,4 @@ class Task extends React.Component<Props, State> {
249307
}
250308

251309
export { Task as TaskComponent };
252-
export default flow([withFeatureConsumer])(Task);
310+
export default flow([withFeatureConsumer, withAPIContext])(Task);

src/elements/content-sidebar/activity-feed/task-new/__tests__/Task-test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ describe('elements/content-sidebar/ActivityFeed/task-new/Task', () => {
7474
expect(wrapper).toMatchSnapshot();
7575
});
7676

77+
test('should set assigned_to state when component mounts', () => {
78+
const wrapper = shallow(<Task currentUser={currentUser} {...task} />);
79+
expect(wrapper.state('assigned_to')).toEqual(task.assigned_to);
80+
});
81+
7782
test('should show assignment status badges for each assignee', () => {
7883
const wrapper = mount(<Task currentUser={currentUser} onEdit={jest.fn()} onDelete={jest.fn()} {...task} />);
7984
expect(wrapper.find('[data-testid="avatar-group-avatar-container"]')).toHaveLength(2);
@@ -251,4 +256,33 @@ describe('elements/content-sidebar/ActivityFeed/task-new/Task', () => {
251256

252257
expect(wrapper.find('CommentInlineError')).toHaveLength(1);
253258
});
259+
260+
test('should call fetchTaskCollaborators on modal open if there is a next_marker', async () => {
261+
const taskWithMarker = {
262+
...task,
263+
assigned_to: {
264+
next_marker: 'foo',
265+
entries: [],
266+
},
267+
};
268+
269+
const wrapper = mount(
270+
<Task
271+
{...taskWithMarker}
272+
currentUser={currentUser}
273+
error={{ title: 'blah', message: 'blah' }}
274+
onEdit={jest.fn()}
275+
onDelete={jest.fn()}
276+
/>,
277+
);
278+
const instance = wrapper.instance();
279+
instance.fetchTaskCollaborators = jest
280+
.fn()
281+
.mockRejectedValueOnce()
282+
.mockResolvedValueOnce({});
283+
284+
await instance.handleEditClick();
285+
286+
expect(instance.fetchTaskCollaborators).toBeCalled();
287+
});
254288
});

0 commit comments

Comments
 (0)