Skip to content

Commit cf1c5b7

Browse files
shikharmohanmergify[bot]
authored andcommitted
feat(tasks): add any task icon + tooltip (#1491)
* feat(tasks): add completion rule icon * feat(tasks): any task icon * feat(tasks): any task icon * feat(tasks): update icon to 32x32 * feat(tasks): updated icon svg and width, height to 11
1 parent 33dd037 commit cf1c5b7

File tree

12 files changed

+286
-0
lines changed

12 files changed

+286
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import type { TaskAssigneeCollection, TaskNew, TaskType } from '../../../../comm
3636
import { ACTIVITY_TARGETS } from '../../../common/interactionTargets';
3737
import { bdlGray80 } from '../../../../styles/variables';
3838
import TaskActions from './TaskActions';
39+
import TaskCompletionRuleIcon from './TaskCompletionRuleIcon';
3940
import TaskDueDate from './TaskDueDate';
4041
import TaskStatus from './TaskStatus';
4142
import AssigneeList from './AssigneeList';
@@ -345,6 +346,7 @@ class Task extends React.Component<Props, State> {
345346
<div className="bcs-Task-statusContainer">
346347
{!!due_at && <TaskDueDate dueDate={due_at} status={status} />}
347348
<TaskStatus status={status} />
349+
<TaskCompletionRuleIcon completionRule={completion_rule} />
348350
</div>
349351
<div className="bcs-Task-assigneeListContainer">
350352
<AssigneeList
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// @flow
2+
import * as React from 'react';
3+
import { FormattedMessage } from 'react-intl';
4+
import { TASK_COMPLETION_RULE_ANY } from '../../../../constants';
5+
import messages from './messages';
6+
import Tooltip from '../../../../components/tooltip';
7+
import IconAnyTask from '../../../../icons/general/IconAnyTask';
8+
import type { TaskCompletionRule } from '../../../../common/types/tasks';
9+
10+
import './TaskCompletionRuleIcon.scss';
11+
12+
type Props = {|
13+
completionRule: ?TaskCompletionRule,
14+
|};
15+
16+
const TaskCompletionRuleIcon = ({ completionRule }: Props): React.Node =>
17+
completionRule === TASK_COMPLETION_RULE_ANY && (
18+
<Tooltip position="top-center" text={<FormattedMessage {...messages.taskAnyAffordanceTooltip} />}>
19+
<span>
20+
<IconAnyTask height={11} width={11} className="bcs-TaskCompletionRuleIcon" />
21+
</span>
22+
</Tooltip>
23+
);
24+
25+
export default TaskCompletionRuleIcon;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.bcs-TaskCompletionRuleIcon {
2+
margin-left: 4px;
3+
}

src/elements/content-sidebar/activity-feed/task-new/TaskStatus.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
.bcs-TaskStatus {
44
color: $bdl-gray-62;
5+
display: inline-block;
56
font-weight: bold;
67
}
78

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import * as React from 'react';
2+
import { mount } from 'enzyme';
3+
import { TASK_COMPLETION_RULE_ALL, TASK_COMPLETION_RULE_ANY, TASK_NEW_IN_PROGRESS } from '../../../../../constants';
4+
import IconAnyTask from '../../../../../icons/general/IconAnyTask';
5+
import TaskCompletionRuleIcon from '../TaskCompletionRuleIcon';
6+
7+
const getWrapper = props => mount(<TaskCompletionRuleIcon {...props} />);
8+
9+
describe('elements/content-sidebar/ActivityFeed/task-new/TaskCompletionRuleIcon', () => {
10+
test.each`
11+
completionRule | iconLength
12+
${TASK_COMPLETION_RULE_ALL} | ${0}
13+
${TASK_COMPLETION_RULE_ANY} | ${1}
14+
${null} | ${0}
15+
`('should render the completion icon correctly', ({ completionRule, iconLength }) => {
16+
const wrapper = getWrapper({
17+
status: TASK_NEW_IN_PROGRESS,
18+
completionRule,
19+
});
20+
21+
expect(wrapper.find(IconAnyTask).length).toBe(iconLength);
22+
});
23+
});
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import * as React from 'react';
2+
import { mount } from 'enzyme';
3+
import {
4+
TASK_NEW_APPROVED,
5+
TASK_NEW_REJECTED,
6+
TASK_NEW_COMPLETED,
7+
TASK_NEW_NOT_STARTED,
8+
TASK_NEW_IN_PROGRESS,
9+
} from '../../../../../constants';
10+
import TaskStatus from '../TaskStatus';
11+
12+
const getWrapper = props => mount(<TaskStatus {...props} />);
13+
14+
describe('elements/content-sidebar/ActivityFeed/task-new/TaskStatus', () => {
15+
test.each`
16+
status
17+
${TASK_NEW_APPROVED}
18+
${TASK_NEW_REJECTED}
19+
${TASK_NEW_COMPLETED}
20+
${TASK_NEW_NOT_STARTED}
21+
${TASK_NEW_IN_PROGRESS}
22+
`('should render the correct task status $status', ({ status }) => {
23+
const wrapper = getWrapper({
24+
status,
25+
});
26+
27+
expect(wrapper).toMatchSnapshot();
28+
});
29+
});

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ exports[`elements/content-sidebar/ActivityFeed/task-new/Task should correctly re
112112
<Component
113113
status="NOT_STARTED"
114114
/>
115+
<TaskCompletionRuleIcon
116+
completionRule="ALL_ASSIGNEES"
117+
/>
115118
</div>
116119
<div
117120
className="bcs-Task-assigneeListContainer"
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`elements/content-sidebar/ActivityFeed/task-new/TaskStatus should render the correct task status APPROVED 1`] = `
4+
<Component
5+
status="APPROVED"
6+
>
7+
<FormattedMessage
8+
defaultMessage="Status: {taskStatus}"
9+
id="be.contentSidebar.activityFeed.taskNew.tasksFeedStatusLabel"
10+
values={
11+
Object {
12+
"taskStatus": <span
13+
className="bcs-TaskStatus-message approved"
14+
>
15+
<FormattedMessage
16+
defaultMessage="Approved"
17+
id="be.contentSidebar.activityFeed.taskNew.tasksFeedApprovedLabel"
18+
/>
19+
</span>,
20+
}
21+
}
22+
>
23+
<div />
24+
</FormattedMessage>
25+
</Component>
26+
`;
27+
28+
exports[`elements/content-sidebar/ActivityFeed/task-new/TaskStatus should render the correct task status COMPLETED 1`] = `
29+
<Component
30+
status="COMPLETED"
31+
>
32+
<FormattedMessage
33+
defaultMessage="Status: {taskStatus}"
34+
id="be.contentSidebar.activityFeed.taskNew.tasksFeedStatusLabel"
35+
values={
36+
Object {
37+
"taskStatus": <span
38+
className="bcs-TaskStatus-message completed"
39+
>
40+
<FormattedMessage
41+
defaultMessage="Completed"
42+
id="be.contentSidebar.activityFeed.taskNew.tasksFeedCompletedLabel"
43+
/>
44+
</span>,
45+
}
46+
}
47+
>
48+
<div />
49+
</FormattedMessage>
50+
</Component>
51+
`;
52+
53+
exports[`elements/content-sidebar/ActivityFeed/task-new/TaskStatus should render the correct task status IN_PROGRESS 1`] = `
54+
<Component
55+
status="IN_PROGRESS"
56+
>
57+
<FormattedMessage
58+
defaultMessage="Status: {taskStatus}"
59+
id="be.contentSidebar.activityFeed.taskNew.tasksFeedStatusLabel"
60+
values={
61+
Object {
62+
"taskStatus": <span
63+
className="bcs-TaskStatus-message inProgress"
64+
>
65+
<FormattedMessage
66+
defaultMessage="In Progress"
67+
id="be.contentSidebar.activityFeed.taskNew.tasksFeedInProgressLabel"
68+
/>
69+
</span>,
70+
}
71+
}
72+
>
73+
<div />
74+
</FormattedMessage>
75+
</Component>
76+
`;
77+
78+
exports[`elements/content-sidebar/ActivityFeed/task-new/TaskStatus should render the correct task status NOT_STARTED 1`] = `
79+
<Component
80+
status="NOT_STARTED"
81+
>
82+
<FormattedMessage
83+
defaultMessage="Status: {taskStatus}"
84+
id="be.contentSidebar.activityFeed.taskNew.tasksFeedStatusLabel"
85+
values={
86+
Object {
87+
"taskStatus": <span
88+
className="bcs-TaskStatus-message notStarted"
89+
>
90+
<FormattedMessage
91+
defaultMessage="In Progress"
92+
id="be.contentSidebar.activityFeed.taskNew.tasksFeedInProgressLabel"
93+
/>
94+
</span>,
95+
}
96+
}
97+
>
98+
<div />
99+
</FormattedMessage>
100+
</Component>
101+
`;
102+
103+
exports[`elements/content-sidebar/ActivityFeed/task-new/TaskStatus should render the correct task status REJECTED 1`] = `
104+
<Component
105+
status="REJECTED"
106+
>
107+
<FormattedMessage
108+
defaultMessage="Status: {taskStatus}"
109+
id="be.contentSidebar.activityFeed.taskNew.tasksFeedStatusLabel"
110+
values={
111+
Object {
112+
"taskStatus": <span
113+
className="bcs-TaskStatus-message rejected"
114+
>
115+
<FormattedMessage
116+
defaultMessage="Rejected"
117+
id="be.contentSidebar.activityFeed.taskNew.tasksFeedRejectedLabel"
118+
/>
119+
</span>,
120+
}
121+
}
122+
>
123+
<div />
124+
</FormattedMessage>
125+
</Component>
126+
`;

src/icons/general/IconAnyTask.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// @flow
2+
import * as React from 'react';
3+
4+
import AccessibleSVG from '../accessible-svg';
5+
import { bdlGray62 } from '../../styles/variables';
6+
7+
type Props = {
8+
className?: string,
9+
color?: string,
10+
height?: number,
11+
/** A text-only string describing the icon if it is not purely decorative for accessibility */
12+
title?: string,
13+
width?: number,
14+
};
15+
16+
const IconAnyTask = ({ className = '', color = bdlGray62, height = 32, title, width = 32 }: Props) => (
17+
<AccessibleSVG className={className} height={height} title={title} viewBox="0 0 32 32" width={width}>
18+
<g fill={color} fillRule="nonzero">
19+
<path d="M28.7484364 16.4549424c0 1.0039348.7442362 1.8177849 1.6622981 1.8177849.9180618 0 1.662298-.8138501 1.662298-1.8177849V5.54823284c0-1.47292747-1.5180216-2.33430191-2.6193324-1.48629378L26.960253 5.9818905c-.7506441.57799516-.9306825 1.71198921-.402127 2.5328466.4995837.7758637 1.4533974.99427836 2.1903104.52782657v7.41237873zM13.1639416 17.5454545c4.0166164 0 7.2727273-3.2561109 7.2727273-7.2727272C20.4366689 6.25611091 17.180558 3 13.1639416 3c-4.01661637 0-7.27272728 3.25611091-7.27272728 7.2727273 0 4.0166163 3.25611091 7.2727272 7.27272728 7.2727272zm0-3.6363636c-2.0083082 0-3.63636365-1.6280554-3.63636365-3.6363636 0-2.00830821 1.62805545-3.63636366 3.63636365-3.63636366s3.6363636 1.62805545 3.6363636 3.63636366c0 2.0083082-1.6280554 3.6363636-3.6363636 3.6363636zM26.0799741 26.82097c-2.6627973-4.6162045-7.5876175-7.459488-12.9167671-7.4573363-5.33091328-.0023936-10.25839928 2.8441776-12.9201858 7.4647912-.50123987.8701058-.20221498 1.9818011.66789077 2.4830409.87010576.5012399 1.98180104.202215 2.48304091-.6678907 2.01238031-3.4933049 5.73768893-5.6453874 9.76917202-5.6435766 4.0305283-.0016279 7.7538215 2.147969 9.766966 5.6379405.5017421.8698163 1.6136099 1.1681993 2.4834261.6664571.8698162-.5017421 1.1681992-1.6136098.6664571-2.4834261z" />
20+
</g>
21+
</AccessibleSVG>
22+
);
23+
24+
export default IconAnyTask;

src/icons/general/IconAnyTask.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```
2+
<IconAnyTask />
3+
```

0 commit comments

Comments
 (0)