foreman-tasks 0.15.1 → 0.15.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.babelrc +9 -1
  3. data/.eslintrc +6 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +6 -0
  6. data/.storybook/webpack.config.js +51 -54
  7. data/app/controllers/foreman_tasks/api/tasks_controller.rb +0 -2
  8. data/app/controllers/foreman_tasks/tasks_controller.rb +6 -1
  9. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +8 -0
  10. data/app/lib/actions/base.rb +7 -0
  11. data/app/lib/actions/helpers/lifecycle_logging.rb +21 -0
  12. data/app/lib/actions/proxy_action.rb +4 -2
  13. data/app/models/foreman_tasks/task.rb +23 -0
  14. data/app/models/foreman_tasks/task/summarizer.rb +96 -6
  15. data/app/models/foreman_tasks/triggering.rb +2 -2
  16. data/app/models/setting/foreman_tasks.rb +8 -1
  17. data/app/services/foreman_tasks/dashboard_table_filter.rb +47 -0
  18. data/app/services/foreman_tasks/troubleshooting_help_generator.rb +92 -0
  19. data/app/services/ui_notifications/tasks.rb +20 -0
  20. data/app/services/ui_notifications/tasks/task_paused_admin.rb +43 -0
  21. data/app/services/ui_notifications/tasks/task_paused_owner.rb +30 -0
  22. data/app/views/foreman_tasks/tasks/_details.html.erb +5 -3
  23. data/app/views/foreman_tasks/tasks/index.html.erb +13 -0
  24. data/config/routes.rb +1 -0
  25. data/db/migrate/20190318153925_add_task_state_updated_at.foreman_tasks.rb +5 -0
  26. data/db/migrate/20190404132157_add_implicit_varchar_uuid_cast.rb +25 -0
  27. data/db/seeds.d/30-notification_blueprints.rb +33 -0
  28. data/foreman-tasks.gemspec +1 -1
  29. data/lib/foreman_tasks/cleaner.rb +5 -4
  30. data/lib/foreman_tasks/engine.rb +1 -1
  31. data/lib/foreman_tasks/test_helpers.rb +10 -0
  32. data/lib/foreman_tasks/version.rb +1 -1
  33. data/package.json +14 -11
  34. data/test/controllers/tasks_controller_test.rb +10 -0
  35. data/test/foreman_tasks_test_helper.rb +4 -0
  36. data/test/support/dummy_dynflow_action.rb +29 -0
  37. data/test/support/history_tasks_builder.rb +42 -0
  38. data/test/unit/actions/action_with_sub_plans_test.rb +4 -1
  39. data/test/unit/actions/bulk_action_test.rb +2 -0
  40. data/test/unit/cleaner_test.rb +15 -0
  41. data/test/unit/dashboard_table_filter_test.rb +65 -0
  42. data/test/unit/summarizer_test.rb +39 -0
  43. data/test/unit/task_test.rb +14 -0
  44. data/test/unit/troubleshooting_help_generator_test.rb +71 -0
  45. data/test/unit/ui_notifications_test.rb +86 -0
  46. data/webpack/ForemanTasks/Components/Chart/Chart.js +128 -0
  47. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/PausedTasksCard.js +20 -0
  48. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/PausedTasksCard.stories.js +51 -0
  49. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/PausedTasksCard.test.js +11 -0
  50. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/__snapshots__/PausedTasksCard.test.js.snap +36 -0
  51. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/RunningTasksCard.js +20 -0
  52. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/RunningTasksCard.stories.js +51 -0
  53. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/RunningTasksCard.test.js +11 -0
  54. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/__snapshots__/RunningTasksCard.test.js.snap +36 -0
  55. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.js +64 -0
  56. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.scss +25 -0
  57. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.stories.js +28 -0
  58. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.test.js +18 -0
  59. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/__snapshots__/ScheduledTasksCard.test.js.snap +94 -0
  60. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +89 -0
  61. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.scss +46 -0
  62. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.stories.js +72 -0
  63. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.test.js +48 -0
  64. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCardHelper.js +63 -0
  65. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCard.test.js.snap +973 -0
  66. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.js +96 -0
  67. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.scss +17 -0
  68. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.stories.js +46 -0
  69. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.test.js +43 -0
  70. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/__snapshots__/TasksDonutCard.test.js.snap +183 -0
  71. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart.js +166 -0
  72. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart.scss +24 -0
  73. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart.stories.js +25 -0
  74. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart.test.js +40 -0
  75. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChartConstants.js +13 -0
  76. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChartHelper.js +94 -0
  77. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChartHelper.test.js +152 -0
  78. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/__snapshots__/TasksDonutChart.test.js.snap +302 -0
  79. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/__snapshots__/TasksDonutChartHelper.test.js.snap +21 -0
  80. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.fixtures.js +25 -0
  81. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.js +72 -0
  82. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.stories.js +52 -0
  83. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.test.js +21 -0
  84. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/__snapshots__/TasksCardsGrid.test.js.snap +223 -0
  85. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksLabelsRow/TasksLabelsRow.js +57 -0
  86. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksLabelsRow/TasksLabelsRow.scss +26 -0
  87. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksLabelsRow/TasksLabelsRow.stories.js +22 -0
  88. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksLabelsRow/TasksLabelsRow.test.js +57 -0
  89. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksLabelsRow/__snapshots__/TasksLabelsRow.test.js.snap +47 -0
  90. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/TimeDropDown.js +51 -0
  91. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/TimeDropDown.stories.js +23 -0
  92. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/TimeDropDown.test.js +19 -0
  93. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/__snapshots__/TimeDropDown.test.js.snap +85 -0
  94. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/TasksTimeRow.js +33 -0
  95. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/TasksTimeRow.scss +11 -0
  96. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/TasksTimeRow.stories.js +22 -0
  97. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/TasksTimeRow.test.js +15 -0
  98. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/__snapshots__/TasksTimeRow.test.js.snap +41 -0
  99. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboard.js +77 -0
  100. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboard.scss +6 -0
  101. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +62 -0
  102. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardConstants.js +94 -0
  103. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardHelper.js +78 -0
  104. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardPropTypes.js +13 -0
  105. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardReducer.js +50 -0
  106. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardSelectors.js +44 -0
  107. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboard.test.js +13 -0
  108. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +37 -0
  109. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardHelper.test.js +36 -0
  110. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardReducer.test.js +58 -0
  111. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardSelectors.test..js +59 -0
  112. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboard.test.js.snap +51 -0
  113. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardActions.test.js.snap +61 -0
  114. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardReducer.test.js.snap +280 -0
  115. data/webpack/ForemanTasks/Components/TasksDashboard/index.js +25 -0
  116. data/webpack/ForemanTasks/ForemanTasksReducers.js +10 -0
  117. data/webpack/ForemanTasks/ForemanTasksSelectors.js +1 -0
  118. data/webpack/__mocks__/foremanReact/API.js +7 -0
  119. data/webpack/__mocks__/foremanReact/common/I18n.js +5 -0
  120. data/webpack/__mocks__/foremanReact/common/helpers.js +3 -0
  121. data/webpack/index.js +13 -1
  122. data/webpack/stories/decorators/index.js +1 -0
  123. data/webpack/stories/decorators/withCardsDecorator.js +14 -0
  124. data/webpack/stories/index.js +1 -3
  125. data/webpack/stories/index.scss +6 -0
  126. metadata +101 -8
  127. data/webpack/ForemanTasks/components/Hello/Hello.stories.js +0 -5
  128. data/webpack/ForemanTasks/components/Hello/__tests__/Hello.test.js +0 -11
  129. data/webpack/ForemanTasks/components/Hello/__tests__/__snapshots__/Hello.test.js.snap +0 -7
  130. data/webpack/ForemanTasks/components/Hello/index.js +0 -5
@@ -0,0 +1,96 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import classNames from 'classnames';
4
+ import { Card } from 'patternfly-react';
5
+ import { noop } from 'foremanReact/common/helpers';
6
+
7
+ import {
8
+ TASKS_DASHBOARD_AVAILABLE_QUERY_MODES,
9
+ TASKS_DASHBOARD_AVAILABLE_TIMES,
10
+ TASKS_DASHBOARD_CURRENT_TIME,
11
+ } from '../../../../TasksDashboardConstants';
12
+ import { getQueryValueText } from '../../../../TasksDashboardHelper';
13
+ import {
14
+ timePropType,
15
+ queryPropType,
16
+ } from '../../../../TasksDashboardPropTypes';
17
+ import { TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS } from '../TasksDonutChart/TasksDonutChartConstants';
18
+ import { getFocusedOn } from '../TasksDonutChart/TasksDonutChartHelper';
19
+ import TasksDonutChart from '../TasksDonutChart/TasksDonutChart';
20
+ import './TasksDonutCard.scss';
21
+
22
+ const TasksDonutCard = ({
23
+ title,
24
+ data,
25
+ query,
26
+ wantedQueryState,
27
+ className,
28
+ time,
29
+ updateQuery,
30
+ ...props
31
+ }) => {
32
+ const { LAST, OLDER } = TASKS_DASHBOARD_AVAILABLE_QUERY_MODES;
33
+ const focusedOn = getFocusedOn(query, wantedQueryState, time);
34
+ const onTotalClick = () => updateQuery({ state: wantedQueryState });
35
+
36
+ return (
37
+ <Card
38
+ className={classNames('tasks-donut-card', className, {
39
+ 'selected-tasks-card':
40
+ focusedOn !== TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS.NORMAL &&
41
+ focusedOn !== TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS.NONE,
42
+ })}
43
+ {...props}
44
+ >
45
+ <Card.Title onClick={onTotalClick}>{title}</Card.Title>
46
+ <Card.Body>
47
+ <TasksDonutChart
48
+ last={data.last}
49
+ older={data.older}
50
+ time={getQueryValueText(time)}
51
+ focusedOn={focusedOn}
52
+ onTotalClick={onTotalClick}
53
+ onLastClick={() =>
54
+ updateQuery({
55
+ state: wantedQueryState,
56
+ mode: LAST,
57
+ time: TASKS_DASHBOARD_CURRENT_TIME,
58
+ })
59
+ }
60
+ onOlderClick={() =>
61
+ updateQuery({
62
+ state: wantedQueryState,
63
+ mode: OLDER,
64
+ time: TASKS_DASHBOARD_CURRENT_TIME,
65
+ })
66
+ }
67
+ />
68
+ </Card.Body>
69
+ </Card>
70
+ );
71
+ };
72
+
73
+ TasksDonutCard.propTypes = {
74
+ title: PropTypes.string,
75
+ data: PropTypes.shape({
76
+ last: PropTypes.number.isRequired,
77
+ older: PropTypes.number.isRequired,
78
+ }),
79
+ time: timePropType,
80
+ query: queryPropType,
81
+ wantedQueryState: PropTypes.string,
82
+ className: PropTypes.string,
83
+ updateQuery: PropTypes.func,
84
+ };
85
+
86
+ TasksDonutCard.defaultProps = {
87
+ title: '',
88
+ data: { last: 0, older: 0 },
89
+ query: {},
90
+ wantedQueryState: '',
91
+ time: TASKS_DASHBOARD_AVAILABLE_TIMES.H24,
92
+ className: '',
93
+ updateQuery: noop,
94
+ };
95
+
96
+ export default TasksDonutCard;
@@ -0,0 +1,17 @@
1
+ .tasks-donut-card {
2
+ .card-pf-title {
3
+ text-align: center;
4
+ font-size: 180%;
5
+ cursor: pointer;
6
+ }
7
+
8
+ .card-pf-body {
9
+ padding-left: 15px;
10
+ }
11
+
12
+ &.selected-tasks-card {
13
+ .card-pf-title {
14
+ font-weight: bold;
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import { storiesOf } from '@storybook/react';
3
+ import { withKnobs, number, text, select } from '@storybook/addon-knobs';
4
+ import { action } from '@storybook/addon-actions';
5
+ import { withCardsDecorator } from '../../../../../../../stories/decorators';
6
+
7
+ import {
8
+ TASKS_DASHBOARD_AVAILABLE_QUERY_MODES,
9
+ TASKS_DASHBOARD_AVAILABLE_TIMES,
10
+ } from '../../../../TasksDashboardConstants';
11
+ import TasksDonutCard from './TasksDonutCard';
12
+
13
+ storiesOf('TasksDashboard/TasksCardsGrid', module)
14
+ .addDecorator(withKnobs)
15
+ .addDecorator(withCardsDecorator)
16
+ .add('TasksDonutCard', () => {
17
+ const selectTime = select(
18
+ 'time',
19
+ TASKS_DASHBOARD_AVAILABLE_TIMES,
20
+ TasksDonutCard.defaultProps.time
21
+ );
22
+
23
+ const selectMode = select(
24
+ 'mode',
25
+ { ...TASKS_DASHBOARD_AVAILABLE_QUERY_MODES, NONE: 'none' },
26
+ 'none'
27
+ );
28
+
29
+ return (
30
+ <TasksDonutCard
31
+ title={text('title', 'Some Title')}
32
+ data={{
33
+ last: number('data.last', 3),
34
+ older: number('data.older', 5),
35
+ }}
36
+ time={selectTime}
37
+ query={{
38
+ state: text('query.state', 'some-state'),
39
+ mode: selectMode,
40
+ time: selectTime,
41
+ }}
42
+ wantedQueryState={text('wantedQueryState', 'wanted-state')}
43
+ updateQuery={action('updateQuery')}
44
+ />
45
+ );
46
+ });
@@ -0,0 +1,43 @@
1
+ import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
2
+
3
+ import {
4
+ TASKS_DASHBOARD_AVAILABLE_TIMES,
5
+ TASKS_DASHBOARD_AVAILABLE_QUERY_MODES,
6
+ } from '../../../../TasksDashboardConstants';
7
+ import TasksDonutCard from './TasksDonutCard';
8
+
9
+ const fixtures = {
10
+ 'render with minimal props': {},
11
+ 'render with props': {
12
+ title: 'some title',
13
+ time: TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK,
14
+ wantedQueryState: 'some-state',
15
+ className: 'some-classname',
16
+ data: { last: 3, older: 5 },
17
+ },
18
+ 'render with total selected': {
19
+ wantedQueryState: 'some-state',
20
+ query: { state: 'some-state' },
21
+ },
22
+ 'render with last selected': {
23
+ wantedQueryState: 'some-state',
24
+ time: TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK,
25
+ query: {
26
+ state: 'some-state',
27
+ mode: TASKS_DASHBOARD_AVAILABLE_QUERY_MODES.LAST,
28
+ time: TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK,
29
+ },
30
+ },
31
+ 'render with older selected': {
32
+ wantedQueryState: 'some-state',
33
+ time: TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK,
34
+ query: {
35
+ state: 'some-state',
36
+ mode: TASKS_DASHBOARD_AVAILABLE_QUERY_MODES.OLDER,
37
+ time: TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK,
38
+ },
39
+ },
40
+ };
41
+
42
+ describe('TasksDonutCard', () =>
43
+ testComponentSnapshotsWithFixtures(TasksDonutCard, fixtures));
@@ -0,0 +1,183 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TasksDonutCard render with last selected 1`] = `
4
+ <Card
5
+ accented={false}
6
+ aggregated={false}
7
+ aggregatedMini={false}
8
+ cardRef={null}
9
+ className="tasks-donut-card selected-tasks-card"
10
+ matchHeight={false}
11
+ >
12
+ <CardTitle
13
+ className=""
14
+ onClick={[Function]}
15
+ />
16
+ <CardBody
17
+ className=""
18
+ >
19
+ <TasksDonutChart
20
+ className=""
21
+ colorsPattern={
22
+ Array [
23
+ "#C315C7",
24
+ "#0089C9",
25
+ ]
26
+ }
27
+ focusedOn="last"
28
+ last={0}
29
+ older={0}
30
+ onLastClick={[Function]}
31
+ onOlderClick={[Function]}
32
+ onTotalClick={[Function]}
33
+ time="week"
34
+ />
35
+ </CardBody>
36
+ </Card>
37
+ `;
38
+
39
+ exports[`TasksDonutCard render with minimal props 1`] = `
40
+ <Card
41
+ accented={false}
42
+ aggregated={false}
43
+ aggregatedMini={false}
44
+ cardRef={null}
45
+ className="tasks-donut-card"
46
+ matchHeight={false}
47
+ >
48
+ <CardTitle
49
+ className=""
50
+ onClick={[Function]}
51
+ />
52
+ <CardBody
53
+ className=""
54
+ >
55
+ <TasksDonutChart
56
+ className=""
57
+ colorsPattern={
58
+ Array [
59
+ "#C315C7",
60
+ "#0089C9",
61
+ ]
62
+ }
63
+ focusedOn="normal"
64
+ last={0}
65
+ older={0}
66
+ onLastClick={[Function]}
67
+ onOlderClick={[Function]}
68
+ onTotalClick={[Function]}
69
+ time="24h"
70
+ />
71
+ </CardBody>
72
+ </Card>
73
+ `;
74
+
75
+ exports[`TasksDonutCard render with older selected 1`] = `
76
+ <Card
77
+ accented={false}
78
+ aggregated={false}
79
+ aggregatedMini={false}
80
+ cardRef={null}
81
+ className="tasks-donut-card selected-tasks-card"
82
+ matchHeight={false}
83
+ >
84
+ <CardTitle
85
+ className=""
86
+ onClick={[Function]}
87
+ />
88
+ <CardBody
89
+ className=""
90
+ >
91
+ <TasksDonutChart
92
+ className=""
93
+ colorsPattern={
94
+ Array [
95
+ "#C315C7",
96
+ "#0089C9",
97
+ ]
98
+ }
99
+ focusedOn="older"
100
+ last={0}
101
+ older={0}
102
+ onLastClick={[Function]}
103
+ onOlderClick={[Function]}
104
+ onTotalClick={[Function]}
105
+ time="week"
106
+ />
107
+ </CardBody>
108
+ </Card>
109
+ `;
110
+
111
+ exports[`TasksDonutCard render with props 1`] = `
112
+ <Card
113
+ accented={false}
114
+ aggregated={false}
115
+ aggregatedMini={false}
116
+ cardRef={null}
117
+ className="tasks-donut-card some-classname"
118
+ matchHeight={false}
119
+ >
120
+ <CardTitle
121
+ className=""
122
+ onClick={[Function]}
123
+ >
124
+ some title
125
+ </CardTitle>
126
+ <CardBody
127
+ className=""
128
+ >
129
+ <TasksDonutChart
130
+ className=""
131
+ colorsPattern={
132
+ Array [
133
+ "#C315C7",
134
+ "#0089C9",
135
+ ]
136
+ }
137
+ focusedOn="normal"
138
+ last={3}
139
+ older={5}
140
+ onLastClick={[Function]}
141
+ onOlderClick={[Function]}
142
+ onTotalClick={[Function]}
143
+ time="week"
144
+ />
145
+ </CardBody>
146
+ </Card>
147
+ `;
148
+
149
+ exports[`TasksDonutCard render with total selected 1`] = `
150
+ <Card
151
+ accented={false}
152
+ aggregated={false}
153
+ aggregatedMini={false}
154
+ cardRef={null}
155
+ className="tasks-donut-card selected-tasks-card"
156
+ matchHeight={false}
157
+ >
158
+ <CardTitle
159
+ className=""
160
+ onClick={[Function]}
161
+ />
162
+ <CardBody
163
+ className=""
164
+ >
165
+ <TasksDonutChart
166
+ className=""
167
+ colorsPattern={
168
+ Array [
169
+ "#C315C7",
170
+ "#0089C9",
171
+ ]
172
+ }
173
+ focusedOn="total"
174
+ last={0}
175
+ older={0}
176
+ onLastClick={[Function]}
177
+ onOlderClick={[Function]}
178
+ onTotalClick={[Function]}
179
+ time="24h"
180
+ />
181
+ </CardBody>
182
+ </Card>
183
+ `;
@@ -0,0 +1,166 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import classNames from 'classnames';
4
+ import { noop } from 'foremanReact/common/helpers';
5
+
6
+ import Chart from '../../../../../../Components/Chart/Chart';
7
+
8
+ import {
9
+ TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS,
10
+ TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS_ARRAY,
11
+ COLLOR_PATTERN,
12
+ } from './TasksDonutChartConstants';
13
+ import {
14
+ getBaseChartConfig,
15
+ shouleBeSelected,
16
+ createChartData,
17
+ updateChartTitle,
18
+ assignExtraChartEvents,
19
+ clearExtraChartEvents,
20
+ } from './TasksDonutChartHelper';
21
+ import './TasksDonutChart.scss';
22
+
23
+ class TasksDonutChart extends React.Component {
24
+ componentDidUpdate() {
25
+ this.updateChart();
26
+ }
27
+
28
+ componentWillUnmount() {
29
+ clearExtraChartEvents(this.chart.element);
30
+ }
31
+
32
+ onChartCreate(chart) {
33
+ this.chart = chart;
34
+
35
+ this.updateChart();
36
+ this.assignExtraChartEvents();
37
+ }
38
+
39
+ updateChart() {
40
+ this.updateChartTitle();
41
+ this.updateChartFocus();
42
+ }
43
+
44
+ updateChartTitle() {
45
+ const { last, older } = this.props;
46
+
47
+ updateChartTitle({
48
+ chartElement: this.chart.element,
49
+ value: last + older,
50
+ });
51
+ }
52
+
53
+ updateChartFocus() {
54
+ this.setChartFocus(this.props.focusedOn);
55
+ }
56
+
57
+ assignExtraChartEvents() {
58
+ assignExtraChartEvents({
59
+ chartElement: this.chart.element,
60
+ onClick: () => this.props.onTotalClick(),
61
+ onMouseOver: () =>
62
+ this.setChartFocus(TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS.TOTAL),
63
+ onMouseOut: () => this.updateChartFocus(),
64
+ });
65
+ }
66
+
67
+ setChartFocus(focusedOn) {
68
+ switch (focusedOn) {
69
+ case TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS.TOTAL:
70
+ this.chart.focus([
71
+ TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS.LAST,
72
+ TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS.OLDER,
73
+ ]);
74
+ break;
75
+ case TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS.LAST:
76
+ case TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS.OLDER:
77
+ this.chart.focus(focusedOn);
78
+ break;
79
+ case TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS.NONE:
80
+ this.chart.focus([]);
81
+ break;
82
+ default:
83
+ this.chart.revert();
84
+ }
85
+ }
86
+
87
+ render() {
88
+ const {
89
+ className,
90
+ last,
91
+ older,
92
+ time,
93
+ focusedOn,
94
+ colorsPattern,
95
+ onLastClick,
96
+ onOlderClick,
97
+ } = this.props;
98
+
99
+ const { columns, names, onItemClick } = createChartData({
100
+ last,
101
+ older,
102
+ time,
103
+ onLastClick,
104
+ onOlderClick,
105
+ });
106
+
107
+ const classes = classNames(
108
+ 'donut-chart-pf',
109
+ 'tasks-donut-chart',
110
+ className,
111
+ { 'tasks-donut-selected': shouleBeSelected(focusedOn) }
112
+ );
113
+
114
+ return (
115
+ <Chart
116
+ {...getBaseChartConfig()}
117
+ type="donut"
118
+ className={classes}
119
+ size={{ height: 120 }}
120
+ color={{ pattern: colorsPattern }}
121
+ onChartCreate={chart => this.onChartCreate(chart)}
122
+ data={{
123
+ columns,
124
+ names,
125
+ onclick: ({ id }) => onItemClick(id),
126
+ onmouseover: ({ id }) => this.setChartFocus(id),
127
+ onmouseout: () => this.updateChartFocus(),
128
+ type: 'donut',
129
+ }}
130
+ legend={{
131
+ show: true,
132
+ position: 'right',
133
+ item: {
134
+ onclick: id => onItemClick(id),
135
+ onmouseover: id => this.setChartFocus(id),
136
+ onmouseout: () => this.updateChartFocus(),
137
+ },
138
+ }}
139
+ />
140
+ );
141
+ }
142
+ }
143
+
144
+ TasksDonutChart.propTypes = {
145
+ last: PropTypes.number.isRequired,
146
+ older: PropTypes.number.isRequired,
147
+ className: PropTypes.string,
148
+ time: PropTypes.string,
149
+ colorsPattern: PropTypes.arrayOf(PropTypes.string),
150
+ focusedOn: PropTypes.oneOf(TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS_ARRAY),
151
+ onTotalClick: PropTypes.func,
152
+ onLastClick: PropTypes.func,
153
+ onOlderClick: PropTypes.func,
154
+ };
155
+
156
+ TasksDonutChart.defaultProps = {
157
+ className: '',
158
+ time: '24h',
159
+ colorsPattern: COLLOR_PATTERN,
160
+ focusedOn: TASKS_DONUT_CHART_FOCUSED_ON_OPTIONS.NORMAL,
161
+ onTotalClick: noop,
162
+ onLastClick: noop,
163
+ onOlderClick: noop,
164
+ };
165
+
166
+ export default TasksDonutChart;