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,77 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Grid } from 'patternfly-react';
4
+ import { noop } from 'foremanReact/common/helpers';
5
+
6
+ import TasksTimeRow from './Components/TasksTimeRow/TasksTimeRow';
7
+ import TasksCardsGrid from './Components/TasksCardsGrid/TasksCardsGrid';
8
+ import TasksLabelsRow from './Components/TasksLabelsRow/TasksLabelsRow';
9
+
10
+ import { TASKS_DASHBOARD_AVAILABLE_TIMES } from './TasksDashboardConstants';
11
+ import { getQueryFromUrl } from './TasksDashboardHelper';
12
+ import { timePropType, queryPropType } from './TasksDashboardPropTypes';
13
+ import './TasksDashboard.scss';
14
+
15
+ class TasksDashboard extends React.Component {
16
+ componentDidMount() {
17
+ const { time, initializeDashboard, fetchTasksSummary } = this.props;
18
+ const query = getQueryFromUrl();
19
+
20
+ initializeDashboard({
21
+ time: query.time,
22
+ query,
23
+ });
24
+
25
+ // dont fetch if time is going to be changed
26
+ if (!query.time || query.time === time) {
27
+ fetchTasksSummary(time);
28
+ }
29
+ }
30
+
31
+ componentDidUpdate(prevProps) {
32
+ const { time, fetchTasksSummary } = this.props;
33
+
34
+ if (time !== prevProps.time) {
35
+ fetchTasksSummary(time);
36
+ }
37
+ }
38
+
39
+ render() {
40
+ const { time, query, tasksSummary, updateTime, updateQuery } = this.props;
41
+
42
+ return (
43
+ <Grid fluid className="tasks-dashboard-grid">
44
+ <TasksTimeRow time={time} updateTime={updateTime} />
45
+ <TasksCardsGrid
46
+ time={time}
47
+ query={query}
48
+ data={tasksSummary}
49
+ updateQuery={updateQuery}
50
+ />
51
+ <TasksLabelsRow query={query} updateQuery={updateQuery} />
52
+ </Grid>
53
+ );
54
+ }
55
+ }
56
+
57
+ TasksDashboard.propTypes = {
58
+ time: timePropType,
59
+ query: queryPropType,
60
+ tasksSummary: TasksCardsGrid.propTypes.data,
61
+ initializeDashboard: PropTypes.func,
62
+ updateTime: PropTypes.func,
63
+ updateQuery: PropTypes.func,
64
+ fetchTasksSummary: PropTypes.func,
65
+ };
66
+
67
+ TasksDashboard.defaultProps = {
68
+ time: TASKS_DASHBOARD_AVAILABLE_TIMES.H24,
69
+ query: {},
70
+ tasksSummary: TasksCardsGrid.defaultProps.data,
71
+ initializeDashboard: noop,
72
+ updateTime: noop,
73
+ updateQuery: noop,
74
+ fetchTasksSummary: noop,
75
+ };
76
+
77
+ export default TasksDashboard;
@@ -0,0 +1,6 @@
1
+ .tasks-dashboard-grid {
2
+ min-height: 200px;
3
+ background-color: #F5F5F5;
4
+ margin: 5px -60px 20px -60px;
5
+ padding: 20px 50px;
6
+ }
@@ -0,0 +1,62 @@
1
+ import API from 'foremanReact/API';
2
+ import { timeToHoursNumber, resolveQuery } from './TasksDashboardHelper';
3
+ import {
4
+ FOREMAN_TASKS_DASHBOARD_INIT,
5
+ FOREMAN_TASKS_DASHBOARD_UPDATE_TIME,
6
+ FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY,
7
+ TASKS_DASHBOARD_CURRENT_TIME,
8
+ FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST,
9
+ FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS,
10
+ FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE,
11
+ } from './TasksDashboardConstants';
12
+ import { selectTime } from './TasksDashboardSelectors';
13
+
14
+ export const initializeDashboard = ({ time, query }) => ({
15
+ type: FOREMAN_TASKS_DASHBOARD_INIT,
16
+ payload: { time, query },
17
+ });
18
+
19
+ export const updateTime = time => ({
20
+ type: FOREMAN_TASKS_DASHBOARD_UPDATE_TIME,
21
+ payload: time,
22
+ });
23
+
24
+ export const updateQuery = query => (dispatch, getState) => {
25
+ if (query.time === TASKS_DASHBOARD_CURRENT_TIME)
26
+ query.time = selectTime(getState());
27
+
28
+ dispatch({
29
+ type: FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY,
30
+ payload: query,
31
+ });
32
+
33
+ resolveQuery(query);
34
+ };
35
+
36
+ export const fetchTasksSummary = time => async dispatch => {
37
+ try {
38
+ dispatch(startRequest());
39
+
40
+ const hours = timeToHoursNumber(time);
41
+
42
+ const { data } = await API.get(`/foreman_tasks/tasks/summary/${hours}`);
43
+
44
+ return dispatch(requestSuccess(data));
45
+ } catch (error) {
46
+ return dispatch(requestFailure(error));
47
+ }
48
+ };
49
+
50
+ const startRequest = () => ({
51
+ type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST,
52
+ });
53
+
54
+ const requestSuccess = data => ({
55
+ type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS,
56
+ payload: data,
57
+ });
58
+
59
+ const requestFailure = error => ({
60
+ type: FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE,
61
+ payload: error,
62
+ });
@@ -0,0 +1,94 @@
1
+ import { translate as __ } from 'foremanReact/common/I18n';
2
+
3
+ export const TASKS_DASHBOARD_AVAILABLE_QUERY_STATES = {
4
+ RUNNING: 'running',
5
+ PAUSED: 'paused',
6
+ STOPPED: 'stopped',
7
+ SCHEDULED: 'scheduled',
8
+ };
9
+
10
+ export const TASKS_DASHBOARD_AVAILABLE_QUERY_RESULTS = {
11
+ ERROR: 'error',
12
+ WARNING: 'warning',
13
+ SUCCESS: 'success',
14
+ };
15
+
16
+ export const TASKS_DASHBOARD_AVAILABLE_QUERY_MODES = {
17
+ LAST: 'last',
18
+ OLDER: 'older',
19
+ };
20
+
21
+ export const TASKS_DASHBOARD_AVAILABLE_TIMES = {
22
+ H24: 'H24',
23
+ H12: 'H12',
24
+ WEEK: 'WEEK',
25
+ };
26
+
27
+ export const TASKS_DASHBOARD_QUERY_KEYS_TEXT = {
28
+ state: __('state'),
29
+ result: __('result'),
30
+ mode: __('mode'),
31
+ time: __('time'),
32
+ };
33
+
34
+ export const TASKS_DASHBOARD_QUERY_VALUES_TEXT = {
35
+ [TASKS_DASHBOARD_AVAILABLE_QUERY_STATES.RUNNING]: __('running'),
36
+ [TASKS_DASHBOARD_AVAILABLE_QUERY_STATES.PAUSED]: __('paused'),
37
+ [TASKS_DASHBOARD_AVAILABLE_QUERY_STATES.STOPPED]: __('stopped'),
38
+ [TASKS_DASHBOARD_AVAILABLE_QUERY_STATES.SCHEDULED]: __('scheduled'),
39
+ [TASKS_DASHBOARD_AVAILABLE_QUERY_RESULTS.ERROR]: __('error'),
40
+ [TASKS_DASHBOARD_AVAILABLE_QUERY_RESULTS.WARNING]: __('warning'),
41
+ [TASKS_DASHBOARD_AVAILABLE_QUERY_RESULTS.SUCCESS]: __('success'),
42
+ [TASKS_DASHBOARD_AVAILABLE_QUERY_MODES.LAST]: __('last'),
43
+ [TASKS_DASHBOARD_AVAILABLE_QUERY_MODES.OLDER]: __('older'),
44
+ [TASKS_DASHBOARD_AVAILABLE_TIMES.H24]: __('24h'),
45
+ [TASKS_DASHBOARD_AVAILABLE_TIMES.H12]: __('12h'),
46
+ [TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK]: __('week'),
47
+ };
48
+
49
+ export const TASKS_DASHBOARD_CURRENT_TIME = 'TASKS_DASHBOARD_CURRENT_TIME';
50
+
51
+ export const FOREMAN_TASKS_DASHBOARD_INIT = 'FOREMAN_TASKS_DASHBOARD_INIT';
52
+
53
+ export const FOREMAN_TASKS_DASHBOARD_UPDATE_TIME =
54
+ 'FOREMAN_TASKS_DASHBOARD_UPDATE_TIME';
55
+
56
+ export const FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY =
57
+ 'FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY';
58
+
59
+ export const FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST =
60
+ 'FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST';
61
+ export const FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS =
62
+ 'FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS';
63
+ export const FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE =
64
+ 'FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE';
65
+
66
+ export const TASKS_SUMMARY_ZERO = {
67
+ running: {
68
+ recent: 0,
69
+ total: 0,
70
+ },
71
+ paused: {
72
+ recent: 0,
73
+ total: 0,
74
+ },
75
+ stopped: {
76
+ by_result: {
77
+ error: {
78
+ total: 0,
79
+ recent: 0,
80
+ },
81
+ warning: {
82
+ total: 0,
83
+ recent: 0,
84
+ },
85
+ success: {
86
+ total: 0,
87
+ recent: 0,
88
+ },
89
+ },
90
+ },
91
+ scheduled: {
92
+ total: 0,
93
+ },
94
+ };
@@ -0,0 +1,78 @@
1
+ import URI from 'urijs';
2
+ import { getURIQuery } from 'foremanReact/common/helpers';
3
+
4
+ import {
5
+ TASKS_DASHBOARD_AVAILABLE_TIMES,
6
+ TASKS_DASHBOARD_QUERY_KEYS_TEXT,
7
+ TASKS_DASHBOARD_QUERY_VALUES_TEXT,
8
+ } from './TasksDashboardConstants';
9
+
10
+ export const getQueryKeyText = key => TASKS_DASHBOARD_QUERY_KEYS_TEXT[key];
11
+
12
+ export const getQueryValueText = value =>
13
+ TASKS_DASHBOARD_QUERY_VALUES_TEXT[value];
14
+
15
+ export const timeToHoursNumber = time => {
16
+ switch (time) {
17
+ case TASKS_DASHBOARD_AVAILABLE_TIMES.H12:
18
+ return 12;
19
+ case TASKS_DASHBOARD_AVAILABLE_TIMES.H24:
20
+ return 24;
21
+ case TASKS_DASHBOARD_AVAILABLE_TIMES.WEEK:
22
+ return 24 * 7;
23
+ default:
24
+ return 24;
25
+ }
26
+ };
27
+
28
+ const uriToQueryMap = {
29
+ state: 'state',
30
+ result: 'result',
31
+ time_mode: 'mode',
32
+ time_horizon: 'time',
33
+ };
34
+
35
+ const queryFromUriQuery = uriQuery => {
36
+ const query = {};
37
+
38
+ Object.entries(uriToQueryMap).forEach(([uriField, queryField]) => {
39
+ if (uriQuery[uriField]) query[queryField] = uriQuery[uriField];
40
+ });
41
+
42
+ if (query.mode === 'recent') {
43
+ query.mode = 'last';
44
+ }
45
+
46
+ return query;
47
+ };
48
+
49
+ const uriQueryFromQuery = query => {
50
+ const uriQuery = {};
51
+
52
+ Object.entries(uriToQueryMap).forEach(([uriField, queryField]) => {
53
+ if (query[queryField]) uriQuery[uriField] = query[queryField];
54
+ });
55
+
56
+ if (uriQuery.time_mode === 'last') {
57
+ uriQuery.time_mode = 'recent';
58
+ }
59
+
60
+ return uriQuery;
61
+ };
62
+
63
+ export const getQueryFromUrl = () => {
64
+ const uriQuery = getURIQuery(window.location.href);
65
+
66
+ return queryFromUriQuery(uriQuery);
67
+ };
68
+
69
+ export const resolveQuery = query => {
70
+ const uriQuery = uriQueryFromQuery(query);
71
+
72
+ const uri = new URI(window.location.href);
73
+ const { search } = uri.query(true);
74
+
75
+ const data = { search, ...uriQuery, page: 1 };
76
+ uri.query(URI.buildQuery(data, true));
77
+ window.location.href = uri.toString();
78
+ };
@@ -0,0 +1,13 @@
1
+ import PropTypes from 'prop-types';
2
+ import { TASKS_DASHBOARD_AVAILABLE_TIMES } from './TasksDashboardConstants';
3
+
4
+ export const timePropType = PropTypes.oneOf(
5
+ Object.values(TASKS_DASHBOARD_AVAILABLE_TIMES)
6
+ );
7
+
8
+ export const queryPropType = PropTypes.shape({
9
+ state: PropTypes.string,
10
+ result: PropTypes.string,
11
+ mode: PropTypes.string,
12
+ time: timePropType,
13
+ });
@@ -0,0 +1,50 @@
1
+ import Immutable from 'seamless-immutable';
2
+ import {
3
+ TASKS_DASHBOARD_AVAILABLE_TIMES,
4
+ FOREMAN_TASKS_DASHBOARD_INIT,
5
+ FOREMAN_TASKS_DASHBOARD_UPDATE_TIME,
6
+ FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY,
7
+ FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST,
8
+ FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS,
9
+ FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE,
10
+ TASKS_SUMMARY_ZERO,
11
+ } from './TasksDashboardConstants';
12
+
13
+ const initialState = Immutable({
14
+ time: TASKS_DASHBOARD_AVAILABLE_TIMES.H24,
15
+ query: {},
16
+ isLoadingTasksSummary: false,
17
+ error: null,
18
+ tasksSummary: TASKS_SUMMARY_ZERO,
19
+ });
20
+
21
+ export default (state = initialState, action) => {
22
+ const { type, payload } = action;
23
+
24
+ switch (type) {
25
+ case FOREMAN_TASKS_DASHBOARD_INIT:
26
+ return state
27
+ .set('time', (payload && payload.time) || initialState.time)
28
+ .set('query', (payload && payload.query) || initialState.query);
29
+ case FOREMAN_TASKS_DASHBOARD_UPDATE_TIME:
30
+ return state.set('time', payload);
31
+ case FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY:
32
+ return state.set('query', payload);
33
+ case FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_REQUEST:
34
+ return state.set('isLoading', true);
35
+ case FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_SUCCESS:
36
+ return state.merge({
37
+ tasksSummary: payload,
38
+ isLoading: false,
39
+ error: null,
40
+ });
41
+ case FOREMAN_TASKS_DASHBOARD_FETCH_TASKS_SUMMARY_FAILURE:
42
+ return state.merge({
43
+ tasksSummary: TASKS_SUMMARY_ZERO,
44
+ isLoading: false,
45
+ error: payload,
46
+ });
47
+ default:
48
+ return state;
49
+ }
50
+ };
@@ -0,0 +1,44 @@
1
+ import { selectForemanTasks } from '../../ForemanTasksSelectors';
2
+ import {
3
+ TASKS_DASHBOARD_AVAILABLE_TIMES,
4
+ TASKS_SUMMARY_ZERO,
5
+ } from './TasksDashboardConstants';
6
+
7
+ export const selectTasksDashboard = state =>
8
+ selectForemanTasks(state).tasksDashboard || {};
9
+
10
+ export const selectTime = state =>
11
+ selectTasksDashboard(state).time || TASKS_DASHBOARD_AVAILABLE_TIMES.H24;
12
+
13
+ export const selectQuery = state => selectTasksDashboard(state).query || {};
14
+
15
+ export const selectTasksSummary = state => {
16
+ const { running, paused, stopped, scheduled } =
17
+ selectTasksDashboard(state).tasksSummary || TASKS_SUMMARY_ZERO;
18
+
19
+ return {
20
+ running: {
21
+ last: running.recent,
22
+ older: running.total - running.recent,
23
+ },
24
+ paused: {
25
+ last: paused.recent,
26
+ older: paused.total - paused.recent,
27
+ },
28
+ stopped: {
29
+ error: {
30
+ total: stopped.by_result.error.total,
31
+ last: stopped.by_result.error.recent,
32
+ },
33
+ warning: {
34
+ total: stopped.by_result.warning.total,
35
+ last: stopped.by_result.warning.recent,
36
+ },
37
+ success: {
38
+ total: stopped.by_result.success.total,
39
+ last: stopped.by_result.success.recent,
40
+ },
41
+ },
42
+ scheduled: scheduled.total,
43
+ };
44
+ };
@@ -0,0 +1,13 @@
1
+ import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
2
+
3
+ import TasksDashboard from '../TasksDashboard';
4
+
5
+ const fixtures = {
6
+ 'render without Props': {},
7
+ /** fixtures, props for the component */
8
+ };
9
+
10
+ describe('TasksDashboard', () => {
11
+ describe('rendering', () =>
12
+ testComponentSnapshotsWithFixtures(TasksDashboard, fixtures));
13
+ });