Skip to content

Commit d13839c

Browse files
authored
feat(task-new): Add support for edit modal (#1261)
* Add support for edit modal * clean up types for handleEditClick * Add test for custom edit click handler * address comments from PR * Update button copy
1 parent 33246cd commit d13839c

File tree

15 files changed

+345
-157
lines changed

15 files changed

+345
-157
lines changed

i18n/en-US.properties

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,16 +406,18 @@ be.tasks.addTaskForm.dueDateLabel = Due Date
406406
be.tasks.addTaskForm.messageLabel = Message
407407
# label for task create form assignee input
408408
be.tasks.addTaskForm.selectAssigneesLabel = Select Assignees
409-
# label for create button in create task popup
410-
be.tasks.addTaskForm.submit = Add Task
409+
# label for create button in create task modal in create mode
410+
be.tasks.addTaskForm.submit = Create
411411
# title for approval task popup
412412
be.tasks.createTask.approval.title = Create Approval Task
413413
# title for general task popup
414414
be.tasks.createTask.general.title = Create General Task
415415
# title for when editing an existing approval task
416-
be.tasks.editTask.approval.title = Edit Approval Task
416+
be.tasks.editTask.approval.title = Modify Approval Task
417417
# modal title for when editing an existing general task
418-
be.tasks.editTask.general.title = Edit General Task
418+
be.tasks.editTask.general.title = Modify General Task
419+
# label for edit button in create task modal in edit mode
420+
be.tasks.editTaskForm.submit = Update
419421
# Approve option for an approval task
420422
be.tasks.feed.approveAction = Approve
421423
# Label for an approved task

src/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ export const KEYS = {
378378
arrowUp: 'ArrowUp',
379379
backspace: 'Backspace',
380380
enter: 'Enter',
381+
escape: 'Escape',
381382
space: ' ',
382383
};
383384

src/elements/common/messages.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -940,12 +940,12 @@ const messages = defineMessages({
940940
},
941941
tasksEditApprovalTaskFormTitle: {
942942
id: 'be.tasks.editTask.approval.title',
943-
defaultMessage: 'Edit Approval Task',
943+
defaultMessage: 'Modify Approval Task',
944944
description: 'title for when editing an existing approval task',
945945
},
946946
tasksEditGeneralTaskFormTitle: {
947947
id: 'be.tasks.editTask.general.title',
948-
defaultMessage: 'Edit General Task',
948+
defaultMessage: 'Modify General Task',
949949
description: 'modal title for when editing an existing general task',
950950
},
951951
tasksAddTaskFormSelectAssigneesLabel: {
@@ -965,8 +965,13 @@ const messages = defineMessages({
965965
},
966966
tasksAddTaskFormSubmitLabel: {
967967
id: 'be.tasks.addTaskForm.submit',
968-
defaultMessage: 'Add Task',
969-
description: 'label for create button in create task popup',
968+
defaultMessage: 'Create',
969+
description: 'label for create button in create task modal in create mode',
970+
},
971+
tasksEditTaskFormSubmitLabel: {
972+
id: 'be.tasks.editTaskForm.submit',
973+
defaultMessage: 'Update',
974+
description: 'label for edit button in create task modal in edit mode',
970975
},
971976
tasksAddTaskFormCancelLabel: {
972977
id: 'be.tasks.addTaskForm.cancel',

src/elements/content-sidebar/ActivitySidebar.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ class ActivitySidebar extends React.PureComponent<Props, State> {
585585
createTask,
586586
getApproverWithQuery,
587587
getAvatarUrl,
588+
message: '',
588589
};
589590
return (
590591
<FeatureFlag feature="activityFeed.tasks.newApi">

src/elements/content-sidebar/AddTaskButton.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ class AddTaskButton extends React.Component<Props, State> {
5050
<TaskModal
5151
error={error}
5252
feedbackUrl={feedbackUrl}
53-
handleCreateError={this.handleCreateError}
54-
handleCreateSuccess={this.handleCreateSuccess}
55-
handleModalClose={this.handleModalClose}
53+
onCreateError={this.handleCreateError}
54+
onCreateSuccess={this.handleCreateSuccess}
55+
onModalClose={this.handleModalClose}
5656
isTaskFormOpen={isTaskFormOpen}
5757
taskFormProps={taskFormProps}
5858
taskType={taskType}

src/elements/content-sidebar/TaskModal.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ type TaskModalProps = {
1313
editMode?: TaskEditMode,
1414
error: ?ElementsXhrError,
1515
feedbackUrl: string,
16-
handleCreateError: (e: ElementsXhrError) => void,
17-
handleCreateSuccess: () => void,
18-
handleModalClose: () => void,
1916
isTaskFormOpen: boolean,
17+
onCreateError: (e: ElementsXhrError) => void,
18+
onCreateSuccess: () => void,
19+
onModalClose: () => void,
2020
taskFormProps: TaskFormProps,
2121
taskType: TaskType,
2222
};
@@ -41,9 +41,9 @@ const TaskModal = (props: TaskModalProps) => {
4141
const {
4242
editMode = TASK_EDIT_MODE_CREATE,
4343
error,
44-
handleCreateError,
45-
handleCreateSuccess,
46-
handleModalClose,
44+
onCreateError,
45+
onCreateSuccess,
46+
onModalClose,
4747
taskType,
4848
feedbackUrl,
4949
isTaskFormOpen,
@@ -57,7 +57,7 @@ const TaskModal = (props: TaskModalProps) => {
5757
data-testid="create-task-modal"
5858
focusElementSelector={focusTargetSelector}
5959
isOpen={isTaskFormOpen}
60-
onRequestClose={handleModalClose}
60+
onRequestClose={onModalClose}
6161
title={
6262
<React.Fragment>
6363
<FormattedMessage {...getMessageForModalTitle(taskType, editMode)} />
@@ -67,10 +67,11 @@ const TaskModal = (props: TaskModalProps) => {
6767
>
6868
<div className="be">
6969
<TaskForm
70+
editMode={editMode}
7071
error={error}
71-
onCancel={handleModalClose}
72-
onCreateSuccess={handleCreateSuccess}
73-
onCreateError={handleCreateError}
72+
onCancel={onModalClose}
73+
onCreateSuccess={onCreateSuccess}
74+
onCreateError={onCreateError}
7475
taskType={taskType}
7576
{...taskFormProps}
7677
/>

src/elements/content-sidebar/__tests__/TaskModal-test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ describe('elements/content-sidebar/TaskModal', () => {
77
return shallow(
88
<TaskModal
99
feedbackUrl="http://example.dentist/"
10-
handleCreateError={jest.fn()}
11-
handleCreateSuccess={jest.fn()}
12-
handleModalClose={jest.fn()}
10+
onCreateError={jest.fn()}
11+
onCreateSuccess={jest.fn()}
12+
onModalClose={jest.fn()}
1313
isTaskFormOpen
1414
taskFormProps={{
1515
approverSelectorContacts: null,

src/elements/content-sidebar/__tests__/__snapshots__/TaskModal-test.js.snap

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ exports[`elements/content-sidebar/TaskModal render should render a default compo
3232
<TaskForm
3333
approverSelectorContacts={null}
3434
createTask={[MockFunction]}
35+
editMode="CREATE"
3536
getAvatarUrl={[MockFunction]}
3637
onCancel={[MockFunction]}
3738
onCreateError={[MockFunction]}
@@ -73,6 +74,7 @@ exports[`elements/content-sidebar/TaskModal render using type APPROVAL and mode
7374
<TaskForm
7475
approverSelectorContacts={null}
7576
createTask={[MockFunction]}
77+
editMode="CREATE"
7678
getAvatarUrl={[MockFunction]}
7779
onCancel={[MockFunction]}
7880
onCreateError={[MockFunction]}
@@ -99,7 +101,7 @@ exports[`elements/content-sidebar/TaskModal render using type APPROVAL and mode
99101
title={
100102
<React.Fragment>
101103
<FormattedMessage
102-
defaultMessage="Edit Approval Task"
104+
defaultMessage="Modify Approval Task"
103105
id="be.tasks.editTask.approval.title"
104106
/>
105107
<BetaFeedbackBadge
@@ -115,6 +117,7 @@ exports[`elements/content-sidebar/TaskModal render using type APPROVAL and mode
115117
<TaskForm
116118
approverSelectorContacts={null}
117119
createTask={[MockFunction]}
120+
editMode="EDIT"
118121
getAvatarUrl={[MockFunction]}
119122
onCancel={[MockFunction]}
120123
onCreateError={[MockFunction]}
@@ -157,6 +160,7 @@ exports[`elements/content-sidebar/TaskModal render using type GENERAL and mode C
157160
<TaskForm
158161
approverSelectorContacts={null}
159162
createTask={[MockFunction]}
163+
editMode="CREATE"
160164
getAvatarUrl={[MockFunction]}
161165
onCancel={[MockFunction]}
162166
onCreateError={[MockFunction]}
@@ -183,7 +187,7 @@ exports[`elements/content-sidebar/TaskModal render using type GENERAL and mode E
183187
title={
184188
<React.Fragment>
185189
<FormattedMessage
186-
defaultMessage="Edit General Task"
190+
defaultMessage="Modify General Task"
187191
id="be.tasks.editTask.general.title"
188192
/>
189193
<BetaFeedbackBadge
@@ -199,6 +203,7 @@ exports[`elements/content-sidebar/TaskModal render using type GENERAL and mode E
199203
<TaskForm
200204
approverSelectorContacts={null}
201205
createTask={[MockFunction]}
206+
editMode="EDIT"
202207
getAvatarUrl={[MockFunction]}
203208
onCancel={[MockFunction]}
204209
onCreateError={[MockFunction]}

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import formatTaggedMessage from '../utils/formatTaggedMessage';
2727
import Avatar from '../Avatar';
2828

2929
import './Comment.scss';
30-
import { COMMENT_TYPE_DEFAULT, COMMENT_TYPE_TASK, PLACEHOLDER_USER } from '../../../../constants';
30+
import { COMMENT_TYPE_DEFAULT, COMMENT_TYPE_TASK, PLACEHOLDER_USER, KEYS } from '../../../../constants';
3131

3232
type Props = {
3333
avatarRenderer?: React.Node => React.Element<any>,
@@ -46,6 +46,7 @@ type Props = {
4646
modified_at?: string | number,
4747
onDelete?: Function,
4848
onEdit?: Function,
49+
onEditClick?: () => void,
4950
permissions?: BoxItemPermission,
5051
tagged_message: string,
5152
translatedTaggedMessage?: string,
@@ -88,7 +89,13 @@ class Comment extends React.Component<Props, State> {
8889
};
8990

9091
handleEditClick = (): void => {
91-
this.setState({ isEditing: true, isInputOpen: true });
92+
const { onEditClick } = this.props;
93+
94+
if (onEditClick) {
95+
onEditClick();
96+
} else {
97+
this.setState({ isEditing: true, isInputOpen: true });
98+
}
9299
};
93100

94101
onKeyDown = (event: SyntheticKeyboardEvent<>): void => {
@@ -98,14 +105,14 @@ class Comment extends React.Component<Props, State> {
98105
nativeEvent.stopImmediatePropagation();
99106

100107
switch (event.key) {
101-
case 'Escape':
108+
case KEYS.escape:
102109
event.stopPropagation();
103110
event.preventDefault();
104111
if (isConfirming) {
105112
this.handleDeleteCancel();
106113
}
107114
break;
108-
case 'Enter':
115+
case KEYS.enter:
109116
event.stopPropagation();
110117
event.preventDefault();
111118
if (isConfirming) {

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,43 @@ describe('elements/content-sidebar/ActivityFeed/comment/Comment', () => {
192192
expect(wrapper.state('isInputOpen')).toBe(false);
193193
});
194194

195+
test('should handle custom edit click handling if edit permissions exist and the handler is defined', () => {
196+
const comment = {
197+
created_at: TIME_STRING_SEPT_27_2017,
198+
tagged_message: 'test',
199+
created_by: { name: '50 Cent', id: 10 },
200+
permissions: { can_edit: true },
201+
onEditClick: jest.fn(),
202+
};
203+
const wrapper = mount(
204+
<Comment
205+
id="123"
206+
{...comment}
207+
approverSelectorContacts={approverSelectorContacts}
208+
currentUser={currentUser}
209+
handlers={allHandlers}
210+
mentionSelectorContacts={mentionSelectorContacts}
211+
onEdit={jest.fn()}
212+
/>,
213+
);
214+
215+
const instance = wrapper.instance();
216+
217+
expect(wrapper.find('CommentMenu').length).toEqual(2);
218+
expect(wrapper.find('ApprovalCommentForm').length).toEqual(0);
219+
expect(wrapper.find('CommentText').length).toEqual(1);
220+
expect(wrapper.state('isEditing')).toBe(false);
221+
222+
expect(wrapper.state('isEditing')).toBe(false);
223+
instance.handleEditClick();
224+
wrapper.update();
225+
expect(wrapper.find('CommentText').length).toEqual(1);
226+
expect(wrapper.state('isEditing')).toBe(false);
227+
expect(wrapper.state('isInputOpen')).toBe(false);
228+
229+
expect(comment.onEditClick).toHaveBeenCalledTimes(1);
230+
});
231+
195232
test('should render an error when one is defined', () => {
196233
const comment = {
197234
created_at: TIME_STRING_SEPT_27_2017,

0 commit comments

Comments
 (0)