foreman-tasks 0.16.0 → 0.16.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.babelrc +4 -1
  3. data/.eslintrc +4 -13
  4. data/app/assets/stylesheets/foreman_tasks/application.css.scss +0 -37
  5. data/app/controllers/foreman_tasks/api/tasks_controller.rb +9 -5
  6. data/app/controllers/foreman_tasks/tasks_controller.rb +23 -19
  7. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +28 -29
  8. data/app/lib/actions/bulk_action.rb +1 -1
  9. data/app/models/foreman_tasks/task.rb +1 -1
  10. data/app/models/foreman_tasks/task/dynflow_task.rb +30 -0
  11. data/app/services/foreman_tasks/troubleshooting_help_generator.rb +4 -0
  12. data/app/views/foreman_tasks/api/tasks/details.json.rabl +18 -0
  13. data/app/views/foreman_tasks/layouts/react.html.erb +1 -1
  14. data/app/views/foreman_tasks/tasks/index.html.erb +3 -0
  15. data/app/views/foreman_tasks/tasks/show.html.erb +10 -134
  16. data/config/routes.rb +3 -0
  17. data/lib/foreman_tasks/engine.rb +1 -1
  18. data/lib/foreman_tasks/tasks/export_tasks.rake +1 -2
  19. data/lib/foreman_tasks/version.rb +1 -1
  20. data/package.json +6 -20
  21. data/test/controllers/tasks_controller_test.rb +11 -0
  22. data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +39 -0
  23. data/test/unit/actions/bulk_action_test.rb +2 -0
  24. data/test/unit/task_test.rb +4 -0
  25. data/webpack/ForemanTasks/Components/TaskDetails/Components/Errors.js +60 -0
  26. data/webpack/ForemanTasks/Components/TaskDetails/Components/Locks.js +46 -0
  27. data/webpack/ForemanTasks/Components/TaskDetails/Components/Raw.js +73 -0
  28. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +55 -0
  29. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +202 -0
  30. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskHelper.js +38 -0
  31. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +238 -0
  32. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Errors.test.js +36 -0
  33. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Locks.test.js +28 -0
  34. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Raw.test.js +27 -0
  35. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +29 -0
  36. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +18 -0
  37. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskHelper.test.js +77 -0
  38. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskInfo.test.js +60 -0
  39. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Errors.test.js.snap +77 -0
  40. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Locks.test.js.snap +108 -0
  41. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Raw.test.js.snap +174 -0
  42. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +62 -0
  43. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +282 -0
  44. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskHelper.test.js.snap +37 -0
  45. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +568 -0
  46. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +87 -0
  47. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +63 -0
  48. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.stories.js +5 -0
  49. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +109 -0
  50. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +18 -0
  51. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +44 -0
  52. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +83 -0
  53. data/webpack/ForemanTasks/Components/TaskDetails/TasksDetailsHelper.js +1 -0
  54. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +12 -0
  55. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +20 -0
  56. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +33 -0
  57. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +97 -0
  58. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +43 -0
  59. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsReducer.test.js.snap +26 -0
  60. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/integration.test.js.snap +122 -0
  61. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +63 -0
  62. data/webpack/ForemanTasks/Components/TaskDetails/index.js +77 -0
  63. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/PausedTasksCard.js +6 -1
  64. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/__snapshots__/PausedTasksCard.test.js.snap +2 -0
  65. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/RunningTasksCard.js +6 -1
  66. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/__snapshots__/RunningTasksCard.test.js.snap +2 -0
  67. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.js +3 -6
  68. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.scss +0 -3
  69. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/__snapshots__/ScheduledTasksCard.test.js.snap +3 -0
  70. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +2 -0
  71. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.scss +0 -4
  72. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCardHelper.js +3 -3
  73. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCard.test.js.snap +495 -54
  74. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.js +1 -0
  75. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.scss +6 -0
  76. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart.scss +0 -3
  77. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksLabelsRow/TasksLabelsRow.scss +1 -1
  78. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboard.scss +2 -2
  79. data/webpack/ForemanTasks/Components/common/ClickConfirmation/index.js +83 -0
  80. data/webpack/ForemanTasks/ForemanTasksReducers.js +2 -0
  81. data/webpack/__mocks__/foremanReact/common/I18n.js +2 -0
  82. data/webpack/__mocks__/foremanReact/components/Layout/LayoutActions.js +2 -0
  83. data/webpack/index.js +5 -0
  84. metadata +46 -9
  85. data/app/views/foreman_tasks/tasks/_details.html.erb +0 -195
  86. data/app/views/foreman_tasks/tasks/_errors.html.erb +0 -42
  87. data/app/views/foreman_tasks/tasks/_locks.html.erb +0 -19
  88. data/app/views/foreman_tasks/tasks/_raw.html.erb +0 -28
  89. data/app/views/foreman_tasks/tasks/_running_steps.html.erb +0 -40
@@ -0,0 +1,33 @@
1
+ import { testReducerSnapshotWithFixtures } from 'react-redux-test-utils';
2
+
3
+ import {
4
+ FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS,
5
+ FOREMAN_TASK_DETAILS_STOP_POLLING,
6
+ FOREMAN_TASK_DETAILS_START_POLLING,
7
+ } from '../TaskDetailsConstants';
8
+ import reducer from '../TaskDetailsReducer';
9
+
10
+ const fixtures = {
11
+ 'should return the initial state': {},
12
+ 'should handle FOREMAN_TASK_DETAILS_START_POLLING': {
13
+ action: {
14
+ type: FOREMAN_TASK_DETAILS_START_POLLING,
15
+ payload: { timeoutId: 1 },
16
+ },
17
+ },
18
+ 'should handle FOREMAN_TASK_DETAILS_STOP_POLLING': {
19
+ action: {
20
+ type: FOREMAN_TASK_DETAILS_STOP_POLLING,
21
+ payload: { timeoutId: 1 },
22
+ },
23
+ },
24
+ 'should handle FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS': {
25
+ action: {
26
+ type: FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS,
27
+ payload: { data: 'some-payload' },
28
+ },
29
+ },
30
+ };
31
+
32
+ describe('TaskDetails - Reducer', () =>
33
+ testReducerSnapshotWithFixtures(reducer, fixtures));
@@ -0,0 +1,97 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TaskDetails rendering render without Props 1`] = `
4
+ <div
5
+ className="task-details-react well"
6
+ >
7
+ <Uncontrolled(Tabs)
8
+ animation={false}
9
+ defaultActiveKey={1}
10
+ id="task-details-tabs"
11
+ >
12
+ <Tab
13
+ eventKey={1}
14
+ title="Task"
15
+ >
16
+ <Task
17
+ action=""
18
+ allowDangerousActions={false}
19
+ cancellable={false}
20
+ endedAt=""
21
+ error={Array []}
22
+ executionPlan={Object {}}
23
+ externalId=""
24
+ failedSteps={Array []}
25
+ fetchTaskDetails={[Function]}
26
+ hasSubTasks={false}
27
+ help=""
28
+ id=""
29
+ input={Array []}
30
+ label=""
31
+ locks={Array []}
32
+ output={Object {}}
33
+ parentTask=""
34
+ progress={0}
35
+ refetchTaskDetails={[Function]}
36
+ result="error"
37
+ resumable={false}
38
+ runningSteps={Array []}
39
+ showForceUnlockModal={false}
40
+ showUnlockModal={false}
41
+ startAt=""
42
+ startBefore=""
43
+ startedAt=""
44
+ state=""
45
+ taskReload={false}
46
+ taskReloadStart={[Function]}
47
+ taskReloadStop={[Function]}
48
+ timeoutId={null}
49
+ toggleForceUnlockModal={[Function]}
50
+ toggleUnlockModal={[Function]}
51
+ username=""
52
+ usernamePath=""
53
+ />
54
+ </Tab>
55
+ <Tab
56
+ eventKey={2}
57
+ title="Running Steps"
58
+ >
59
+ <RunningSteps
60
+ executionPlan={Object {}}
61
+ runningSteps={Array []}
62
+ />
63
+ </Tab>
64
+ <Tab
65
+ eventKey={3}
66
+ title="Errors"
67
+ >
68
+ <Errors
69
+ executionPlan={Object {}}
70
+ failedSteps={Array []}
71
+ />
72
+ </Tab>
73
+ <Tab
74
+ eventKey={4}
75
+ title="Locks"
76
+ >
77
+ <Locks
78
+ locks={Array []}
79
+ />
80
+ </Tab>
81
+ <Tab
82
+ eventKey={5}
83
+ title="Raw"
84
+ >
85
+ <Raw
86
+ endedAt=""
87
+ externalId=""
88
+ id=""
89
+ input={Array []}
90
+ label=""
91
+ output={Object {}}
92
+ startedAt=""
93
+ />
94
+ </Tab>
95
+ </Uncontrolled(Tabs)>
96
+ </div>
97
+ `;
@@ -0,0 +1,43 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TaskDetails - Actions should fetch-task-details and success 1`] = `
4
+ Array [
5
+ Array [
6
+ Object {
7
+ "type": "FOREMAN_TASK_DETAILS_FETCH_TASK_REQUEST",
8
+ },
9
+ ],
10
+ Array [
11
+ Object {
12
+ "payload": "some-data",
13
+ "type": "FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS",
14
+ },
15
+ ],
16
+ Array [
17
+ Object {
18
+ "payload": Object {
19
+ "timeoutId": 7,
20
+ },
21
+ "type": "FOREMAN_TASK_DETAILS_START_POLLING",
22
+ },
23
+ ],
24
+ ]
25
+ `;
26
+
27
+ exports[`TaskDetails - Actions should start reload 1`] = `
28
+ Object {
29
+ "payload": Object {
30
+ "timeoutId": 1,
31
+ },
32
+ "type": "FOREMAN_TASK_DETAILS_START_POLLING",
33
+ }
34
+ `;
35
+
36
+ exports[`TaskDetails - Actions should stop reload 1`] = `
37
+ Object {
38
+ "payload": Object {
39
+ "timeoutId": 2,
40
+ },
41
+ "type": "FOREMAN_TASK_DETAILS_STOP_POLLING",
42
+ }
43
+ `;
@@ -0,0 +1,26 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TaskDetails - Reducer should handle FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS 1`] = `
4
+ Object {
5
+ "data": "some-payload",
6
+ "loading": false,
7
+ "taskReload": undefined,
8
+ "timeoutId": undefined,
9
+ }
10
+ `;
11
+
12
+ exports[`TaskDetails - Reducer should handle FOREMAN_TASK_DETAILS_START_POLLING 1`] = `
13
+ Object {
14
+ "taskReload": true,
15
+ "timeoutId": 1,
16
+ }
17
+ `;
18
+
19
+ exports[`TaskDetails - Reducer should handle FOREMAN_TASK_DETAILS_STOP_POLLING 1`] = `
20
+ Object {
21
+ "taskReload": false,
22
+ "timeoutId": null,
23
+ }
24
+ `;
25
+
26
+ exports[`TaskDetails - Reducer should return the initial state 1`] = `Object {}`;
@@ -0,0 +1,122 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`TaskDetails integration test should change the data after reload: task details data should change 1`] = `
4
+ Object {
5
+ "action": Array [
6
+ Array [
7
+ Object {
8
+ "payload": Object {
9
+ "timeoutId": 1,
10
+ },
11
+ "type": "FOREMAN_TASK_DETAILS_START_POLLING",
12
+ },
13
+ ],
14
+ ],
15
+ "state": Object {
16
+ "taskDetails": Object {
17
+ "label": "new-label",
18
+ "loading": false,
19
+ "taskReload": true,
20
+ "timeoutId": 1,
21
+ },
22
+ },
23
+ }
24
+ `;
25
+
26
+ exports[`TaskDetails integration test should change the data after reload: task details reload start without error 1`] = `
27
+ Array [
28
+ Array [
29
+ Object {
30
+ "type": "FOREMAN_TASK_DETAILS_FETCH_TASK_REQUEST",
31
+ },
32
+ ],
33
+ Array [
34
+ Object {
35
+ "payload": Object {
36
+ "timeoutId": 1,
37
+ },
38
+ "type": "FOREMAN_TASK_DETAILS_START_POLLING",
39
+ },
40
+ ],
41
+ Array [
42
+ Object {
43
+ "payload": Object {
44
+ "label": "new-label",
45
+ },
46
+ "type": "FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS",
47
+ },
48
+ ],
49
+ Array [
50
+ Object {
51
+ "payload": Object {
52
+ "timeoutId": 1,
53
+ },
54
+ "type": "FOREMAN_TASK_DETAILS_START_POLLING",
55
+ },
56
+ ],
57
+ ]
58
+ `;
59
+
60
+ exports[`TaskDetails integration test should flow: initial state 1`] = `
61
+ Object {
62
+ "taskDetails": Object {
63
+ "loading": true,
64
+ },
65
+ }
66
+ `;
67
+
68
+ exports[`TaskDetails integration test should flow: task details reload start with error 1`] = `
69
+ Array [
70
+ Array [
71
+ Object {
72
+ "type": "FOREMAN_TASK_DETAILS_FETCH_TASK_REQUEST",
73
+ },
74
+ ],
75
+ Array [
76
+ Object {
77
+ "payload": Object {
78
+ "timeoutId": 1,
79
+ },
80
+ "type": "FOREMAN_TASK_DETAILS_START_POLLING",
81
+ },
82
+ ],
83
+ Array [
84
+ Object {
85
+ "payload": [TypeError: Cannot read property 'data' of undefined],
86
+ "type": "FOREMAN_TASK_DETAILS_FETCH_TASK_FAILURE",
87
+ },
88
+ ],
89
+ ]
90
+ `;
91
+
92
+ exports[`TaskDetails integration test should flow: task details reload stop 1`] = `
93
+ Array [
94
+ Array [
95
+ Object {
96
+ "type": "FOREMAN_TASK_DETAILS_FETCH_TASK_REQUEST",
97
+ },
98
+ ],
99
+ Array [
100
+ Object {
101
+ "payload": Object {
102
+ "timeoutId": 1,
103
+ },
104
+ "type": "FOREMAN_TASK_DETAILS_START_POLLING",
105
+ },
106
+ ],
107
+ Array [
108
+ Object {
109
+ "payload": [TypeError: Cannot read property 'data' of undefined],
110
+ "type": "FOREMAN_TASK_DETAILS_FETCH_TASK_FAILURE",
111
+ },
112
+ ],
113
+ Array [
114
+ Object {
115
+ "payload": Object {
116
+ "timeoutId": 1,
117
+ },
118
+ "type": "FOREMAN_TASK_DETAILS_STOP_POLLING",
119
+ },
120
+ ],
121
+ ]
122
+ `;
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+
3
+ import API from 'foremanReact/API';
4
+ import { IntegrationTestHelper } from 'react-redux-test-utils';
5
+
6
+ import TaskDetails, { reducers } from '../index';
7
+ import { selectForemanTasks } from '../../../ForemanTasksSelectors';
8
+
9
+ jest.mock('../../../ForemanTasksSelectors');
10
+ jest.mock('foremanReact/API');
11
+ selectForemanTasks.mockImplementation(state => state);
12
+ describe('TaskDetails integration test', () => {
13
+ beforeEach(() => {
14
+ jest.useFakeTimers();
15
+ const expectedIntervalId = 1;
16
+ jest.useFakeTimers();
17
+ setInterval.mockImplementation(() => expectedIntervalId);
18
+ });
19
+ it('should flow', async () => {
20
+ window.location.reload = jest.fn();
21
+
22
+ API.get.mockImplementationOnce();
23
+ const integrationTestHelper = new IntegrationTestHelper(reducers);
24
+
25
+ const component = integrationTestHelper.mount(<TaskDetails id="test" />);
26
+ integrationTestHelper.takeStoreSnapshot('initial state');
27
+
28
+ const reloadButton = component.find('.reload-button').at(0);
29
+ reloadButton.simulate('click');
30
+ await IntegrationTestHelper.flushAllPromises();
31
+
32
+ integrationTestHelper.takeActionsSnapshot(
33
+ 'task details reload start with error'
34
+ );
35
+
36
+ reloadButton.simulate('click');
37
+ await IntegrationTestHelper.flushAllPromises();
38
+ jest.advanceTimersByTime(1);
39
+ integrationTestHelper.takeActionsSnapshot('task details reload stop');
40
+ jest.useRealTimers();
41
+ });
42
+
43
+ it('should change the data after reload', async () => {
44
+ API.get.mockImplementationOnce(() => ({
45
+ data: { label: 'new-label' },
46
+ }));
47
+ const integrationTestHelper = new IntegrationTestHelper(reducers);
48
+
49
+ const component = integrationTestHelper.mount(<TaskDetails id="test" />);
50
+
51
+ const reloadButton = component.find('.reload-button').at(0);
52
+ reloadButton.simulate('click');
53
+
54
+ await IntegrationTestHelper.flushAllPromises();
55
+ integrationTestHelper.takeActionsSnapshot(
56
+ 'task details reload start without error'
57
+ );
58
+ integrationTestHelper.takeStoreAndLastActionSnapshot(
59
+ 'task details data should change'
60
+ );
61
+ jest.useRealTimers();
62
+ });
63
+ });
@@ -0,0 +1,77 @@
1
+ import { bindActionCreators } from 'redux';
2
+ import { connect } from 'react-redux';
3
+ import TaskDetails from './TaskDetails';
4
+ import * as actions from './TaskDetailsActions';
5
+ import reducer from './TaskDetailsReducer';
6
+ import {
7
+ selectEndedAt,
8
+ selectStartAt,
9
+ selectStartBefore,
10
+ selectStartedAt,
11
+ selectLocks,
12
+ selectInput,
13
+ selectOutput,
14
+ selectResumable,
15
+ selectCancellable,
16
+ selectHelp,
17
+ selectErrors,
18
+ selectProgress,
19
+ selectUsername,
20
+ selectLabel,
21
+ selectExecutionPlan,
22
+ selectFailedSteps,
23
+ selectRunningSteps,
24
+ selectHasSubTasks,
25
+ selectAllowDangerousActions,
26
+ selectUsernamePath,
27
+ selectAction,
28
+ selectState,
29
+ selectResult,
30
+ selectTimeoutId,
31
+ selectTaskReload,
32
+ selectParentTask,
33
+ selectShowUnlockModal,
34
+ selectShowForceUnlockModal,
35
+ selectExternalId,
36
+ } from './TaskDetailsSelectors';
37
+
38
+ const mapStateToProps = state => ({
39
+ startAt: selectStartAt(state),
40
+ startBefore: selectStartBefore(state),
41
+ startedAt: selectStartedAt(state),
42
+ endedAt: selectEndedAt(state),
43
+ input: selectInput(state),
44
+ output: selectOutput(state),
45
+ resumable: selectResumable(state),
46
+ cancellable: selectCancellable(state),
47
+ errors: selectErrors(state),
48
+ progress: selectProgress(state),
49
+ username: selectUsername(state),
50
+ label: selectLabel(state),
51
+ executionPlan: selectExecutionPlan(state),
52
+ failedSteps: selectFailedSteps(state),
53
+ runningSteps: selectRunningSteps(state),
54
+ help: selectHelp(state),
55
+ hasSubTasks: selectHasSubTasks(state),
56
+ allowDangerousActions: selectAllowDangerousActions(state),
57
+ locks: selectLocks(state),
58
+ usernamePath: selectUsernamePath(state),
59
+ action: selectAction(state),
60
+ state: selectState(state),
61
+ result: selectResult(state),
62
+ timeoutId: selectTimeoutId(state),
63
+ taskReload: selectTaskReload(state),
64
+ parentTask: selectParentTask(state),
65
+ showUnlockModal: selectShowUnlockModal(state),
66
+ showForceUnlockModal: selectShowForceUnlockModal(state),
67
+ externalId: selectExternalId(state),
68
+ });
69
+
70
+ const mapDispatchToProps = dispatch => bindActionCreators(actions, dispatch);
71
+
72
+ export const reducers = { taskDetails: reducer };
73
+
74
+ export default connect(
75
+ mapStateToProps,
76
+ mapDispatchToProps
77
+ )(TaskDetails);