foreman-tasks 12.1.1 → 12.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/app/views/foreman_tasks/api/tasks/show.json.rabl +1 -1
- data/foreman-tasks.gemspec +1 -3
- data/lib/foreman_tasks/version.rb +1 -1
- data/test/controllers/api/tasks_controller_test.rb +2 -2
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Dependencies.js +69 -58
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Errors.js +25 -5
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Locks.js +170 -43
- data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +12 -4
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +217 -201
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskSkeleton.js +30 -34
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Dependencies.test.js +90 -29
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Errors.test.js +50 -27
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Locks.test.js +256 -23
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Raw.test.js +44 -22
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +56 -24
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +42 -22
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskInfo.test.js +45 -54
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +65 -25
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +37 -13
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +53 -8
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/PausedTasksCard.test.js +53 -7
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/RunningTasksCard.test.js +53 -7
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.js +5 -4
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.test.js +44 -14
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +6 -5
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.js +5 -4
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.scss +3 -8
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/TasksDonutCard.test.js +75 -34
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChart.test.js +57 -34
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/TasksDonutChartHelper.test.js +23 -9
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.fixtures.js +14 -11
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.js +19 -21
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/TasksCardsGrid.test.js +63 -14
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/TimeDropDown.js +9 -17
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/TimeDropDown.test.js +49 -13
- metadata +2 -46
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Errors.test.js.snap +0 -77
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Locks.test.js.snap +0 -116
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Raw.test.js.snap +0 -174
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +0 -62
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +0 -127
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +0 -580
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +0 -172
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +0 -52
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/PausedTasksCard/__snapshots__/PausedTasksCard.test.js.snap +0 -38
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/RunningTasksCard/__snapshots__/RunningTasksCard.test.js.snap +0 -38
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/__snapshots__/ScheduledTasksCard.test.js.snap +0 -97
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutCard/__snapshots__/TasksDonutCard.test.js.snap +0 -183
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/__snapshots__/TasksDonutChart.test.js.snap +0 -302
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/TasksDonutChart/__snapshots__/TasksDonutChartHelper.test.js.snap +0 -21
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/__snapshots__/TasksCardsGrid.test.js.snap +0 -210
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/Components/TimeDropDown/__snapshots__/TimeDropDown.test.js.snap +0 -85
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79e3003ee203359edba19b75adac7c38435b94081969faba3ad211601c559345
|
|
4
|
+
data.tar.gz: b3da633082735d6adf5a5d569744d3d5a6fa1d18d05568e7bc048b922205c674
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6614edd5d7578167024f5df26bc5f950862dd9a2411a75cfd3f591b19755acbc40a1ca4321eff752800023923bb574d0095aa8c81ab4fa953e030999cf3d4547
|
|
7
|
+
data.tar.gz: fcdd9f699f2a55d3e27bf014f8dbee0dd0e92e3d4f6b6b6921f0a4ba9841cf2cd8aa2392d0376667fa34a85ec41b53ad6e6ff25dae9443fcee9bd625350e82f2
|
data/Gemfile
CHANGED
|
@@ -6,6 +6,6 @@ attributes :id, :label, :pending, :action
|
|
|
6
6
|
attributes :username, :started_at, :ended_at, :state, :result, :progress
|
|
7
7
|
|
|
8
8
|
# A workaround for https://github.com/ruby/json/issues/957
|
|
9
|
-
node(:duration) { |t| t.duration&.
|
|
9
|
+
node(:duration) { |t| t.duration&.to_f&.to_s if t.respond_to?(:duration) }
|
|
10
10
|
attributes :input, :output, :humanized, :cli_example, :start_at
|
|
11
11
|
node(:available_actions) { |t| { cancellable: t.execution_plan&.cancellable?, resumable: t.resumable? } }
|
data/foreman-tasks.gemspec
CHANGED
|
@@ -33,7 +33,5 @@ same resource. It also optionally provides Dynflow infrastructure for using it f
|
|
|
33
33
|
s.add_dependency "get_process_mem" # for memory polling
|
|
34
34
|
s.add_dependency "sinatra" # for Dynflow web console
|
|
35
35
|
|
|
36
|
-
s.add_development_dependency
|
|
37
|
-
s.add_development_dependency 'sqlite3'
|
|
38
|
-
s.add_development_dependency 'theforeman-rubocop', '~> 0.1.0'
|
|
36
|
+
s.add_development_dependency "sqlite3"
|
|
39
37
|
end
|
|
@@ -108,7 +108,7 @@ module ForemanTasks
|
|
|
108
108
|
get :show, params: { id: task.id }, session: set_session_user
|
|
109
109
|
assert_response :success
|
|
110
110
|
data = JSON.parse(response.body)
|
|
111
|
-
assert_equal task.duration.
|
|
111
|
+
assert_equal task.duration.to_f.to_s, data['duration']
|
|
112
112
|
end
|
|
113
113
|
end
|
|
114
114
|
|
|
@@ -118,7 +118,7 @@ module ForemanTasks
|
|
|
118
118
|
get :index, session: set_session_user
|
|
119
119
|
assert_response :success
|
|
120
120
|
data = JSON.parse(response.body)
|
|
121
|
-
assert_equal task.duration.
|
|
121
|
+
assert_equal task.duration.to_f.to_s, data['results'][0]['duration']
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
124
|
|
|
@@ -1,55 +1,75 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import { capitalize } from 'lodash';
|
|
3
4
|
import {
|
|
4
|
-
Alert,
|
|
5
|
-
AlertVariant,
|
|
6
5
|
Grid,
|
|
7
6
|
GridItem,
|
|
7
|
+
Text,
|
|
8
|
+
TextVariants,
|
|
8
9
|
Title,
|
|
9
10
|
} from '@patternfly/react-core';
|
|
10
11
|
import { Table, Thead, Tbody, Tr, Th, Td } from '@patternfly/react-table';
|
|
11
12
|
import { translate as __ } from 'foremanReact/common/I18n';
|
|
12
13
|
|
|
13
|
-
const DependencyTable = ({ title, tasks }) =>
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<
|
|
35
|
-
<a href={`/foreman_tasks/tasks/${task.id}`}>
|
|
36
|
-
{task.humanized || task.action}
|
|
37
|
-
</a>
|
|
38
|
-
</Td>
|
|
39
|
-
<Td>{task.state}</Td>
|
|
40
|
-
<Td>{task.result}</Td>
|
|
14
|
+
const DependencyTable = ({ title, tasks, ouiaSectionId }) => (
|
|
15
|
+
<React.Fragment>
|
|
16
|
+
<Title headingLevel="h3" size="lg" ouiaId={`${ouiaSectionId}-title`}>
|
|
17
|
+
{title}
|
|
18
|
+
</Title>
|
|
19
|
+
<Grid hasGutter>
|
|
20
|
+
<GridItem span={12} xl={8}>
|
|
21
|
+
{tasks.length === 0 ? (
|
|
22
|
+
<Text component={TextVariants.small} ouiaId={`${ouiaSectionId}-none`}>
|
|
23
|
+
{__('None')}
|
|
24
|
+
</Text>
|
|
25
|
+
) : (
|
|
26
|
+
<Table
|
|
27
|
+
aria-label={title}
|
|
28
|
+
variant="compact"
|
|
29
|
+
ouiaId={`${ouiaSectionId}-table`}
|
|
30
|
+
>
|
|
31
|
+
<Thead>
|
|
32
|
+
<Tr ouiaId={`${ouiaSectionId}-table-header`}>
|
|
33
|
+
<Th>{__('Name')}</Th>
|
|
34
|
+
<Th>{__('State')}</Th>
|
|
35
|
+
<Th>{__('Result')}</Th>
|
|
41
36
|
</Tr>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
37
|
+
</Thead>
|
|
38
|
+
<Tbody>
|
|
39
|
+
{tasks.map(task => (
|
|
40
|
+
<Tr
|
|
41
|
+
key={task.id}
|
|
42
|
+
ouiaId={`${ouiaSectionId}-table-row-${task.id}`}
|
|
43
|
+
>
|
|
44
|
+
<Td dataLabel={__('Name')}>
|
|
45
|
+
<Text
|
|
46
|
+
component={TextVariants.a}
|
|
47
|
+
href={`/foreman_tasks/tasks/${task.id}`}
|
|
48
|
+
ouiaId={`${ouiaSectionId}-task-link-${task.id}`}
|
|
49
|
+
>
|
|
50
|
+
{task.humanized || task.action}
|
|
51
|
+
</Text>
|
|
52
|
+
</Td>
|
|
53
|
+
<Td dataLabel={__('State')}>
|
|
54
|
+
{capitalize(String(task.state || ''))}
|
|
55
|
+
</Td>
|
|
56
|
+
<Td dataLabel={__('Result')}>
|
|
57
|
+
{capitalize(String(task.result || ''))}
|
|
58
|
+
</Td>
|
|
59
|
+
</Tr>
|
|
60
|
+
))}
|
|
61
|
+
</Tbody>
|
|
62
|
+
</Table>
|
|
63
|
+
)}
|
|
64
|
+
</GridItem>
|
|
65
|
+
</Grid>
|
|
66
|
+
</React.Fragment>
|
|
67
|
+
);
|
|
49
68
|
|
|
50
69
|
DependencyTable.propTypes = {
|
|
51
70
|
title: PropTypes.string.isRequired,
|
|
52
71
|
tasks: PropTypes.array,
|
|
72
|
+
ouiaSectionId: PropTypes.string.isRequired,
|
|
53
73
|
};
|
|
54
74
|
|
|
55
75
|
DependencyTable.defaultProps = {
|
|
@@ -57,27 +77,18 @@ DependencyTable.defaultProps = {
|
|
|
57
77
|
};
|
|
58
78
|
|
|
59
79
|
const Dependencies = ({ dependsOn, blocks }) => (
|
|
60
|
-
<
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
{__(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<Grid hasGutter>
|
|
73
|
-
<GridItem span={6}>
|
|
74
|
-
<DependencyTable title={__('Depends on')} tasks={dependsOn} />
|
|
75
|
-
</GridItem>
|
|
76
|
-
<GridItem span={6}>
|
|
77
|
-
<DependencyTable title={__('Blocks')} tasks={blocks} />
|
|
78
|
-
</GridItem>
|
|
79
|
-
</Grid>
|
|
80
|
-
</div>
|
|
80
|
+
<React.Fragment>
|
|
81
|
+
<DependencyTable
|
|
82
|
+
title={__('Task depends on')}
|
|
83
|
+
tasks={dependsOn}
|
|
84
|
+
ouiaSectionId="task-dependencies-depends-on"
|
|
85
|
+
/>
|
|
86
|
+
<DependencyTable
|
|
87
|
+
title={__('Task blocks')}
|
|
88
|
+
tasks={blocks}
|
|
89
|
+
ouiaSectionId="task-dependencies-blocks"
|
|
90
|
+
/>
|
|
91
|
+
</React.Fragment>
|
|
81
92
|
);
|
|
82
93
|
|
|
83
94
|
Dependencies.propTypes = {
|
|
@@ -1,20 +1,40 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import { Alert } from 'patternfly-
|
|
3
|
+
import { Alert } from '@patternfly/react-core';
|
|
4
4
|
import { translate as __ } from 'foremanReact/common/I18n';
|
|
5
5
|
|
|
6
6
|
const Errors = ({ ...props }) => {
|
|
7
7
|
const { failedSteps, executionPlan } = props;
|
|
8
8
|
if (!executionPlan)
|
|
9
9
|
return (
|
|
10
|
-
<Alert
|
|
10
|
+
<Alert
|
|
11
|
+
variant="danger"
|
|
12
|
+
isInline
|
|
13
|
+
ouiaId="task-errors-plan-missing"
|
|
14
|
+
title={__('Execution plan unavailable')}
|
|
15
|
+
>
|
|
16
|
+
{__('Execution plan data not available ')}
|
|
17
|
+
</Alert>
|
|
11
18
|
);
|
|
12
19
|
if (!failedSteps.length)
|
|
13
|
-
return
|
|
20
|
+
return (
|
|
21
|
+
<Alert
|
|
22
|
+
variant="success"
|
|
23
|
+
isInline
|
|
24
|
+
ouiaId="task-errors-none"
|
|
25
|
+
title={__('No errors')}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
14
28
|
return (
|
|
15
29
|
<div>
|
|
16
30
|
{failedSteps.map((step, i) => (
|
|
17
|
-
<Alert
|
|
31
|
+
<Alert
|
|
32
|
+
variant="danger"
|
|
33
|
+
isInline
|
|
34
|
+
key={i}
|
|
35
|
+
ouiaId={`task-error-${i}`}
|
|
36
|
+
title={__('Step error')}
|
|
37
|
+
>
|
|
18
38
|
<span>{__('Action')}:</span>
|
|
19
39
|
<span>
|
|
20
40
|
<pre>{step.action_class}</pre>
|
|
@@ -37,7 +57,7 @@ const Errors = ({ ...props }) => {
|
|
|
37
57
|
</span>
|
|
38
58
|
<span>{__('Backtrace')}:</span>
|
|
39
59
|
<span>
|
|
40
|
-
<pre>{step.error.backtrace.join('\n')}</pre>
|
|
60
|
+
<pre>{(step.error.backtrace || []).join('\n')}</pre>
|
|
41
61
|
</span>
|
|
42
62
|
</React.Fragment>
|
|
43
63
|
)}
|
|
@@ -1,56 +1,183 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
EmptyState,
|
|
5
|
+
EmptyStateBody,
|
|
6
|
+
EmptyStateHeader,
|
|
7
|
+
EmptyStateIcon,
|
|
8
|
+
EmptyStateVariant,
|
|
9
|
+
Flex,
|
|
10
|
+
FlexItem,
|
|
11
|
+
Grid,
|
|
12
|
+
GridItem,
|
|
13
|
+
Icon,
|
|
14
|
+
Text,
|
|
15
|
+
TextContent,
|
|
16
|
+
TextVariants,
|
|
17
|
+
Title,
|
|
18
|
+
} from '@patternfly/react-core';
|
|
19
|
+
import { Table, Tbody, Tr, Td } from '@patternfly/react-table';
|
|
20
|
+
import { LockIcon, LockOpenIcon } from '@patternfly/react-icons';
|
|
21
|
+
import { translate as __, sprintf } from 'foremanReact/common/I18n';
|
|
5
22
|
|
|
6
|
-
const
|
|
7
|
-
|
|
23
|
+
const LocksSection = ({
|
|
24
|
+
title,
|
|
25
|
+
description,
|
|
26
|
+
items,
|
|
27
|
+
RowIcon,
|
|
28
|
+
ouiaSectionId,
|
|
29
|
+
}) => (
|
|
30
|
+
<Flex direction={{ default: 'column' }}>
|
|
31
|
+
<FlexItem spacer={{ default: 'spacerSm' }}>
|
|
32
|
+
<Flex
|
|
33
|
+
alignItems={{ default: 'alignItemsCenter' }}
|
|
34
|
+
spaceItems={{ default: 'spaceItemsSm' }}
|
|
35
|
+
>
|
|
36
|
+
<FlexItem>
|
|
37
|
+
<Title
|
|
38
|
+
headingLevel="h3"
|
|
39
|
+
size="lg"
|
|
40
|
+
style={{ margin: '0' }}
|
|
41
|
+
ouiaId={`${ouiaSectionId}-title`}
|
|
42
|
+
>
|
|
43
|
+
{title}
|
|
44
|
+
</Title>
|
|
45
|
+
</FlexItem>
|
|
46
|
+
<FlexItem>
|
|
47
|
+
<RowIcon aria-hidden />
|
|
48
|
+
</FlexItem>
|
|
49
|
+
</Flex>
|
|
50
|
+
</FlexItem>
|
|
51
|
+
<FlexItem>
|
|
52
|
+
<TextContent>
|
|
53
|
+
<Text
|
|
54
|
+
component={TextVariants.p}
|
|
55
|
+
ouiaId={`${ouiaSectionId}-description`}
|
|
56
|
+
>
|
|
57
|
+
{description}
|
|
58
|
+
</Text>
|
|
59
|
+
</TextContent>
|
|
60
|
+
</FlexItem>
|
|
61
|
+
<FlexItem>
|
|
62
|
+
<Grid>
|
|
63
|
+
<GridItem span={5}>
|
|
64
|
+
<Table
|
|
65
|
+
aria-label={title}
|
|
66
|
+
variant="compact"
|
|
67
|
+
ouiaId={`${ouiaSectionId}-table`}
|
|
68
|
+
>
|
|
69
|
+
<Tbody>
|
|
70
|
+
{items.map((lock, index) => (
|
|
71
|
+
<Tr
|
|
72
|
+
key={`${lock.resource_type}-${lock.resource_id}-${index}`}
|
|
73
|
+
ouiaId={`${ouiaSectionId}-row-${index}`}
|
|
74
|
+
>
|
|
75
|
+
<Td>
|
|
76
|
+
<Flex
|
|
77
|
+
alignItems={{ default: 'alignItemsCenter' }}
|
|
78
|
+
spaceItems={{ default: 'spaceItemsSm' }}
|
|
79
|
+
flexWrap={{ default: 'nowrap' }}
|
|
80
|
+
>
|
|
81
|
+
<FlexItem>
|
|
82
|
+
<Icon size="sm">
|
|
83
|
+
<RowIcon />
|
|
84
|
+
</Icon>
|
|
85
|
+
</FlexItem>
|
|
86
|
+
<FlexItem>
|
|
87
|
+
{lock.link ? (
|
|
88
|
+
<a
|
|
89
|
+
href={lock.link}
|
|
90
|
+
data-ouia-component-id={`${ouiaSectionId}-resource-type-link-${index}`}
|
|
91
|
+
>
|
|
92
|
+
{lock.resource_type}
|
|
93
|
+
</a>
|
|
94
|
+
) : (
|
|
95
|
+
lock.resource_type
|
|
96
|
+
)}
|
|
97
|
+
</FlexItem>
|
|
98
|
+
</Flex>
|
|
99
|
+
</Td>
|
|
100
|
+
<Td>{sprintf(__('id: %s'), String(lock.resource_id))}</Td>
|
|
101
|
+
</Tr>
|
|
102
|
+
))}
|
|
103
|
+
</Tbody>
|
|
104
|
+
</Table>
|
|
105
|
+
</GridItem>
|
|
106
|
+
</Grid>
|
|
107
|
+
</FlexItem>
|
|
108
|
+
</Flex>
|
|
109
|
+
);
|
|
8
110
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
111
|
+
LocksSection.propTypes = {
|
|
112
|
+
title: PropTypes.string.isRequired,
|
|
113
|
+
description: PropTypes.string.isRequired,
|
|
114
|
+
items: PropTypes.array.isRequired,
|
|
115
|
+
RowIcon: PropTypes.elementType.isRequired,
|
|
116
|
+
ouiaSectionId: PropTypes.string.isRequired,
|
|
12
117
|
};
|
|
13
118
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
119
|
+
const Locks = ({ locks }) => {
|
|
120
|
+
const nonExclusive = locks.filter(l => !l.exclusive);
|
|
121
|
+
const exclusive = locks.filter(l => l.exclusive);
|
|
17
122
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
123
|
+
if (locks.length === 0) {
|
|
124
|
+
return (
|
|
125
|
+
<EmptyState variant={EmptyStateVariant.lg}>
|
|
126
|
+
<EmptyStateHeader
|
|
127
|
+
headingLevel="h3"
|
|
128
|
+
titleText={__('No resources')}
|
|
129
|
+
icon={<EmptyStateIcon icon={LockOpenIcon} />}
|
|
130
|
+
/>
|
|
131
|
+
<EmptyStateBody>
|
|
132
|
+
{__(
|
|
133
|
+
'No resources currently associated with this task. Locking resources prevents conflicting tasks from running simultaneously. Other tasks must wait until this process completes.'
|
|
134
|
+
)}
|
|
135
|
+
</EmptyStateBody>
|
|
136
|
+
</EmptyState>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<Flex
|
|
142
|
+
direction={{ default: 'column' }}
|
|
143
|
+
gap={{ default: 'gap2xl' }}
|
|
144
|
+
data-ouia-component-id="task-locks-populated"
|
|
145
|
+
>
|
|
146
|
+
{nonExclusive.length > 0 && (
|
|
147
|
+
<LocksSection
|
|
148
|
+
title={__('Non-exclusive resources')}
|
|
149
|
+
description={__(
|
|
150
|
+
"Other tasks can access the resource simultaneously. This lock tracks the task's relationship to the resource without blocking others."
|
|
151
|
+
)}
|
|
152
|
+
items={nonExclusive}
|
|
153
|
+
RowIcon={LockOpenIcon}
|
|
154
|
+
ouiaSectionId="task-locks-non-exclusive"
|
|
155
|
+
/>
|
|
23
156
|
)}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
</Col>
|
|
46
|
-
))}
|
|
47
|
-
</Row>
|
|
48
|
-
</Card.Grid>
|
|
49
|
-
</div>
|
|
50
|
-
);
|
|
157
|
+
{exclusive.length > 0 && (
|
|
158
|
+
<LocksSection
|
|
159
|
+
title={__('Exclusive resources')}
|
|
160
|
+
description={__(
|
|
161
|
+
'Only this task can access the resource. Other tasks must wait until this process completes.'
|
|
162
|
+
)}
|
|
163
|
+
items={exclusive}
|
|
164
|
+
RowIcon={LockIcon}
|
|
165
|
+
ouiaSectionId="task-locks-exclusive"
|
|
166
|
+
/>
|
|
167
|
+
)}
|
|
168
|
+
</Flex>
|
|
169
|
+
);
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const lockShape = PropTypes.shape({
|
|
173
|
+
exclusive: PropTypes.bool,
|
|
174
|
+
resource_type: PropTypes.string,
|
|
175
|
+
resource_id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
176
|
+
link: PropTypes.string,
|
|
177
|
+
});
|
|
51
178
|
|
|
52
179
|
Locks.propTypes = {
|
|
53
|
-
locks: PropTypes.
|
|
180
|
+
locks: PropTypes.arrayOf(lockShape),
|
|
54
181
|
};
|
|
55
182
|
|
|
56
183
|
Locks.defaultProps = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import { Alert, Button } from 'patternfly-
|
|
4
|
-
import { translate as __ } from 'foremanReact/common/I18n';
|
|
3
|
+
import { Alert, AlertVariant, Button } from '@patternfly/react-core';
|
|
4
|
+
import { translate as __, sprintf } from 'foremanReact/common/I18n';
|
|
5
5
|
|
|
6
6
|
const RunningSteps = ({
|
|
7
7
|
runningSteps,
|
|
@@ -14,11 +14,19 @@ const RunningSteps = ({
|
|
|
14
14
|
return (
|
|
15
15
|
<div>
|
|
16
16
|
{runningSteps.map((step, i) => (
|
|
17
|
-
<Alert
|
|
17
|
+
<Alert
|
|
18
|
+
variant={AlertVariant.warning}
|
|
19
|
+
isInline
|
|
20
|
+
key={step.id || i}
|
|
21
|
+
ouiaId={`running-step-${i}`}
|
|
22
|
+
title={sprintf(__('Running step %s'), i + 1)}
|
|
23
|
+
>
|
|
18
24
|
{step.cancellable && (
|
|
19
25
|
<p>
|
|
20
26
|
<Button
|
|
21
|
-
|
|
27
|
+
variant="danger"
|
|
28
|
+
size="sm"
|
|
29
|
+
ouiaId={`running-step-cancel-button-${i}`}
|
|
22
30
|
onClick={() => {
|
|
23
31
|
if (!taskReload) {
|
|
24
32
|
taskReloadStart(id);
|