foreman_patch 1.1.1 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +0 -6
- data/app/controllers/foreman_patch/api/v2/invocations_controller.rb +23 -1
- data/app/lib/actions/foreman_patch/cycle/initiate.rb +6 -1
- data/app/lib/actions/foreman_patch/invocation/patch.rb +6 -2
- data/app/lib/actions/foreman_patch/invocation/wait_for_host.rb +9 -16
- data/app/lib/actions/foreman_patch/window/patch.rb +4 -4
- data/app/models/foreman_patch/invocation.rb +6 -0
- data/app/models/foreman_patch/plan.rb +1 -1
- data/app/models/foreman_patch/round.rb +9 -26
- data/app/models/foreman_patch/window.rb +1 -1
- data/app/views/foreman_patch/api/v2/rounds/base.json.rabl +1 -1
- data/app/views/foreman_patch/api/v2/rounds/status.json.rabl +2 -8
- data/app/views/templates/ensure_services.erb +7 -4
- data/config/api_routes.rb +7 -1
- data/lib/foreman_patch/version.rb +1 -1
- data/webpack/components/Invocations/Invocations.js +48 -16
- data/webpack/components/Invocations/InvocationsPage.js +24 -1
- data/webpack/components/Invocations/InvocationsSelectors.js +1 -1
- data/webpack/components/Invocations/components/{InvocationItem.js → InvocationActions.js} +4 -16
- data/webpack/components/Invocations/index.js +93 -10
- data/webpack/components/RoundProgress/AggregateStatus.js +6 -5
- data/webpack/components/RoundProgress/RoundProgress.js +7 -6
- data/webpack/components/RoundProgress/RoundProgressSelectors.js +3 -2
- metadata +7 -56
- data/app/lib/actions/foreman_patch/invocation/ensure_services.rb +0 -47
- data/app/lib/actions/foreman_patch/invocation/restart.rb +0 -101
- data/app/lib/actions/foreman_patch/invocation/update_packages.rb +0 -52
- data/app/lib/actions/helpers/failure_notification.rb +0 -20
- data/app/lib/actions/helpers/with_feature_action.rb +0 -102
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.css +0 -1
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.css.gz +0 -0
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js +0 -6
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.gz +0 -0
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.map +0 -1
- data/public/webpack/foreman_patch/bundle-200e97f4e2ad9ed413ea.js.map.gz +0 -0
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.css +0 -1
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.css.gz +0 -0
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js +0 -6
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.gz +0 -0
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.map +0 -1
- data/public/webpack/foreman_patch/foreman_patch-1e4f2d5e6f040a27aa7a.js.map.gz +0 -0
- data/public/webpack/foreman_patch/manifest.json +0 -26
- data/public/webpack/foreman_patch/manifest.json.gz +0 -0
- data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js +0 -2
- data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.gz +0 -0
- data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.map +0 -1
- data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.map.gz +0 -0
- /data/webpack/components/Invocations/{InvocationsPage.scss → Invocations.scss} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27d079801bd3872a195833f96d46a8981a987ebf89bedef56b44e88bb15c12cb
|
4
|
+
data.tar.gz: 85325d642dc887c8c768d94f44d0b4746ff6d5edb6e1eb4691ca6530f986a964
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c42a3ef7b9332cf57121655ddcadceb850fa18c76ea03b8bc6dc6b351e3a3c96988fce9bdf906048f65c0b7f5f8956f6807f9a4b67e04afdc1b533a1cd692685
|
7
|
+
data.tar.gz: 85de82b6fb076e463d3d793525f192a423a619f315a08d7d9af4d1550dbfb6f3ecfcd2b947b2b3de80fbdc4814b9774fdaaec17c34ff82dcbfb885a2d7d60b7e
|
data/Rakefile
CHANGED
@@ -12,12 +12,6 @@ rescue LoadError
|
|
12
12
|
RDoc::Task = Rake::RDocTask
|
13
13
|
end
|
14
14
|
|
15
|
-
require 'rake-version'
|
16
|
-
|
17
|
-
RakeVersion::Tasks.new do |version|
|
18
|
-
version.copy 'lib/foreman_patch/version.rb'
|
19
|
-
end
|
20
|
-
|
21
15
|
RDoc::Task.new(:rdoc) do |rdoc|
|
22
16
|
rdoc.rdoc_dir = 'rdoc'
|
23
17
|
rdoc.title = 'ForemanPatch'
|
@@ -23,7 +23,6 @@ module ForemanPatch
|
|
23
23
|
api :GET, '/invocations/:id', N_('Get details of an invocation')
|
24
24
|
param :id, :identifier, required: true
|
25
25
|
def show
|
26
|
-
@invocation = ForemanPatch::Invocation.find(params[:id])
|
27
26
|
end
|
28
27
|
|
29
28
|
api :PUT, '/invocations/:id', N_('Move the invocation to another round')
|
@@ -35,6 +34,29 @@ module ForemanPatch
|
|
35
34
|
process_response @invocation.update(invocation_params)
|
36
35
|
end
|
37
36
|
|
37
|
+
api :PUT, '/invocations/move', N_('Move invocations to another round')
|
38
|
+
param :ids, Array, required: true, desc: N_('List of invocation ids')
|
39
|
+
param :round_id, Integer, required: true, desc: N_('Id of the destination round')
|
40
|
+
def move
|
41
|
+
@invocations = ForemanPatch::Invocation.where(id: params[:ids])
|
42
|
+
|
43
|
+
@errors = []
|
44
|
+
@invocations.each do |invocation|
|
45
|
+
round = invocation.round.cycle.rounds.find(params[:round_id])
|
46
|
+
invocation.update(round: round)
|
47
|
+
rescue
|
48
|
+
end
|
49
|
+
|
50
|
+
@invocations = ForemanPatch::Invocation.where(id: params[:ids], round_id: params[:round_id])
|
51
|
+
end
|
52
|
+
|
53
|
+
api :PUT, '/invocations/cancel', N_('Cancel invocations')
|
54
|
+
param :ids, Array, required: true, desc: N_('List of invocation ids')
|
55
|
+
def cancel
|
56
|
+
@invocations = ForemanPatch::Invocation.where(id: params[:ids])
|
57
|
+
@invocations.update_all(status: 'cancelled')
|
58
|
+
end
|
59
|
+
|
38
60
|
api :DELETE, 'invocations/:id', N_('Delete the patch invocation')
|
39
61
|
param :id, :identifier, required: true
|
40
62
|
def destroy
|
@@ -35,7 +35,8 @@ module Actions
|
|
35
35
|
def finalize
|
36
36
|
cycle.windows.each(&:schedule)
|
37
37
|
|
38
|
-
|
38
|
+
plan = find_plan
|
39
|
+
plan.iterate if plan.present?
|
39
40
|
end
|
40
41
|
|
41
42
|
def humanized_name
|
@@ -62,6 +63,10 @@ module Actions
|
|
62
63
|
task.add_missing_task_groups(plan.task_group)
|
63
64
|
end
|
64
65
|
|
66
|
+
def find_plan
|
67
|
+
task.task_groups.find_by(type: 'ForemanPatch::PlanTaskGroup')&.plan
|
68
|
+
end
|
69
|
+
|
65
70
|
end
|
66
71
|
end
|
67
72
|
end
|
@@ -32,9 +32,9 @@ module Actions
|
|
32
32
|
return unless root_action?
|
33
33
|
|
34
34
|
case execution_plan.state
|
35
|
-
when
|
35
|
+
when :scheduled, :pending, :planning, :planned
|
36
36
|
invocation.update!(status: 'pending')
|
37
|
-
when
|
37
|
+
when :running
|
38
38
|
invocation.update!(status: 'running')
|
39
39
|
else
|
40
40
|
action = failed_action
|
@@ -70,6 +70,10 @@ module Actions
|
|
70
70
|
::Dynflow::Action::Rescue::Fail
|
71
71
|
end
|
72
72
|
|
73
|
+
def humanized_name
|
74
|
+
_('Patch %s') % host.name
|
75
|
+
end
|
76
|
+
|
73
77
|
private
|
74
78
|
|
75
79
|
def host
|
@@ -3,7 +3,6 @@ module Actions
|
|
3
3
|
module Invocation
|
4
4
|
class WaitForHost < Actions::EntryAction
|
5
5
|
include Actions::Helpers::WithContinuousOutput
|
6
|
-
include Actions::Helpers::FailureNotification
|
7
6
|
include Dynflow::Action::Polling
|
8
7
|
|
9
8
|
def plan(host)
|
@@ -13,34 +12,32 @@ module Actions
|
|
13
12
|
end
|
14
13
|
|
15
14
|
def done?
|
16
|
-
|
15
|
+
['available', 'timeout'].include? external_task
|
17
16
|
end
|
18
17
|
|
19
18
|
def invoke_external_task
|
20
19
|
schedule_timeout(Setting[:host_max_wait_for_up]) if Setting[:host_max_wait_for_up]
|
21
20
|
|
22
|
-
|
21
|
+
'waiting'
|
23
22
|
end
|
24
23
|
|
25
24
|
def poll_external_task
|
25
|
+
return status = external_task if external_task == 'timeout'
|
26
|
+
|
26
27
|
socket = TCPSocket.new(host.ip, Setting[:remote_execution_ssh_port])
|
27
28
|
|
28
29
|
status = starting? ? 'available' : 'waiting'
|
29
|
-
|
30
|
-
{ status: status }
|
31
30
|
rescue
|
32
31
|
status = 'starting'
|
33
|
-
|
34
|
-
{ status: status }
|
35
32
|
ensure
|
36
33
|
socket.close if socket
|
37
34
|
add_output("Poll result: #{status}")
|
38
35
|
end
|
39
36
|
|
40
37
|
def poll_intervals
|
41
|
-
case external_task
|
38
|
+
case external_task
|
42
39
|
when 'waiting'
|
43
|
-
[
|
40
|
+
[1]
|
44
41
|
when 'starting'
|
45
42
|
[10]
|
46
43
|
else
|
@@ -49,17 +46,13 @@ module Actions
|
|
49
46
|
end
|
50
47
|
|
51
48
|
def on_finish
|
52
|
-
add_output(_('Host is up'), 'stdout')
|
49
|
+
add_output(_('Host is up'), 'stdout') if external_task == 'available'
|
53
50
|
end
|
54
51
|
|
55
52
|
def process_timeout
|
56
53
|
add_output(_('Server did not respond withing alloted time after restart.'), 'stderr')
|
57
|
-
send_failure_notification
|
58
|
-
fail('Timeout exceeded.')
|
59
|
-
end
|
60
54
|
|
61
|
-
|
62
|
-
::Dynflow::Action::Rescue::Fail
|
55
|
+
self.external_task = 'timeout'
|
63
56
|
end
|
64
57
|
|
65
58
|
def live_output
|
@@ -84,7 +77,7 @@ module Actions
|
|
84
77
|
end
|
85
78
|
|
86
79
|
def starting?
|
87
|
-
external_task
|
80
|
+
external_task == 'starting'
|
88
81
|
end
|
89
82
|
|
90
83
|
def add_output(message, type = 'debug', timestamp = Time.now.getlocal)
|
@@ -55,11 +55,11 @@ module Actions
|
|
55
55
|
return unless root_action?
|
56
56
|
|
57
57
|
case execution_plan.state
|
58
|
-
when
|
59
|
-
window.status =
|
60
|
-
when
|
58
|
+
when :scheduled
|
59
|
+
window.status = 'scheduled'
|
60
|
+
when :pending, :planning, :planned, :running
|
61
61
|
window.status = 'running'
|
62
|
-
when
|
62
|
+
when :stopped
|
63
63
|
window.status = 'completed'
|
64
64
|
else
|
65
65
|
window.status = execution_plan.state
|
@@ -2,6 +2,8 @@ module ForemanPatch
|
|
2
2
|
class Invocation < ::ApplicationRecord
|
3
3
|
include ForemanTasks::Concerns::ActionSubject
|
4
4
|
|
5
|
+
STATUSES = %w(planned pending running success warning error cancelled)
|
6
|
+
|
5
7
|
belongs_to :round, class_name: 'ForemanPatch::Round', inverse_of: :invocations
|
6
8
|
has_one :window, through: :round
|
7
9
|
has_one :cycle, through: :window
|
@@ -30,6 +32,10 @@ module ForemanPatch
|
|
30
32
|
task&.main_action&.planned_actions || []
|
31
33
|
end
|
32
34
|
|
35
|
+
def events
|
36
|
+
task&.main_action&.live_output || []
|
37
|
+
end
|
38
|
+
|
33
39
|
def complete?
|
34
40
|
['success', 'warning', 'failed', 'cancelled'].include? status
|
35
41
|
end
|
@@ -50,7 +50,7 @@ module ForemanPatch
|
|
50
50
|
def iterate
|
51
51
|
count = tasks.where(state: 'scheduled').count
|
52
52
|
|
53
|
-
if count < active_count or active_count == 0
|
53
|
+
if (count < active_count - 1) or active_count == 0
|
54
54
|
ForemanTasks.async_task(Actions::ForemanPatch::Cycle::Create, self)
|
55
55
|
end
|
56
56
|
end
|
@@ -2,6 +2,8 @@ module ForemanPatch
|
|
2
2
|
class Round < ::ApplicationRecord
|
3
3
|
include ForemanTasks::Concerns::ActionSubject
|
4
4
|
|
5
|
+
STATUSES = %w(planned pending running complete).freeze
|
6
|
+
|
5
7
|
belongs_to :window, class_name: 'ForemanPatch::Window'
|
6
8
|
has_one :cycle, class_name: 'ForemanPatch::Cycle', through: :window
|
7
9
|
belongs_to :group, class_name: 'ForemanPatch::Group'
|
@@ -21,38 +23,19 @@ module ForemanPatch
|
|
21
23
|
|
22
24
|
scope :in_windows, -> (*args) { where(window: args.flatten) }
|
23
25
|
scope :missing_hosts, -> (*args) do
|
24
|
-
left_joins(
|
25
|
-
where(foreman_patch_group_facets: { host_id: args.flatten }
|
26
|
-
|
26
|
+
left_joins(group: :group_facets).scoping do
|
27
|
+
where(foreman_patch_group_facets: { host_id: args.flatten })
|
28
|
+
.where('NOT EXISTS (:invocations)',
|
29
|
+
invocations: ForemanPatch::Invocation.where(host_id: args.flatten)
|
30
|
+
.where('foreman_patch_rounds.id = foreman_patch_invocations.round_id'))
|
27
31
|
end
|
28
32
|
end
|
29
33
|
|
30
34
|
scoped_search on: :name, complete_value: true
|
31
35
|
scoped_search on: :status, complete_value: true
|
32
36
|
|
33
|
-
def progress
|
34
|
-
|
35
|
-
0
|
36
|
-
else
|
37
|
-
total ||= invocations.count
|
38
|
-
done ||= sub_tasks.where(result: %w(success warning error)).count
|
39
|
-
((done.to_f / total) * 100).round
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def progress_report
|
44
|
-
invocations.reduce({
|
45
|
-
pending: 0,
|
46
|
-
running: 0,
|
47
|
-
success: 0,
|
48
|
-
warning: 0,
|
49
|
-
failed: 0,
|
50
|
-
cancelled: 0,
|
51
|
-
}) do |report, invocation|
|
52
|
-
status = (invocation.status == 'planned' ? 'pending' : invocation.status)
|
53
|
-
report[status.to_sym] += 1
|
54
|
-
report
|
55
|
-
end
|
37
|
+
def progress
|
38
|
+
ForemanPatch::Invocation::STATUSES.product([0]).to_h.merge(invocations.unscope(:order).group(:status).count)
|
56
39
|
end
|
57
40
|
|
58
41
|
def finished?
|
@@ -27,7 +27,7 @@ module ForemanPatch
|
|
27
27
|
left_joins(rounds: [:invocations, {group: :group_facets}]).scoping do
|
28
28
|
where(foreman_patch_group_facets: { host_id: args.flatten })
|
29
29
|
.or(where(foreman_patch_invocations: { host_id: args.flatten }))
|
30
|
-
end
|
30
|
+
end.distinct
|
31
31
|
end
|
32
32
|
|
33
33
|
scoped_search on: :name, complete_value: true
|
@@ -7,17 +7,20 @@ feature: ensure_services
|
|
7
7
|
provider_type: SSH
|
8
8
|
%>
|
9
9
|
<% if @host.operatingsystem.family == "Redhat" && @host.operatingsystem.major.to_i > 6 %>
|
10
|
-
|
11
|
-
|
10
|
+
while true; do
|
11
|
+
state=$(systemctl is-system-running)
|
12
12
|
case $state in
|
13
13
|
initializing | starting)
|
14
14
|
sleep 5
|
15
|
-
state=$(systemctl is-system-running)
|
16
15
|
;;
|
17
16
|
maintenance | stopping | offline)
|
18
|
-
echo $state
|
17
|
+
echo "System is $state"
|
19
18
|
exit 1
|
20
19
|
;;
|
20
|
+
running)
|
21
|
+
echo "All services running."
|
22
|
+
exit 0
|
23
|
+
;;
|
21
24
|
*)
|
22
25
|
systemctl list-units --failed
|
23
26
|
exit 1
|
data/config/api_routes.rb
CHANGED
@@ -24,12 +24,18 @@ ForemanPatch::Engine.routes.draw do
|
|
24
24
|
|
25
25
|
resources :rounds, only: [:show, :create, :update, :destroy] do
|
26
26
|
resources :invocations, only: [:index]
|
27
|
+
|
27
28
|
member do
|
28
29
|
get :status
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
32
|
-
resources :invocations, only: [:show]
|
33
|
+
resources :invocations, only: [:show] do
|
34
|
+
collection do
|
35
|
+
put 'move'
|
36
|
+
put 'cancel'
|
37
|
+
end
|
38
|
+
end
|
33
39
|
|
34
40
|
end
|
35
41
|
end
|
@@ -2,11 +2,13 @@ import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
3
3
|
import { translate as __ } from 'foremanReact/common/I18n';
|
4
4
|
import { LoadingState, Alert } from 'patternfly-react';
|
5
|
+
import { TableComposable, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
|
5
6
|
import { STATUS } from 'foremanReact/constants';
|
6
7
|
|
7
|
-
import
|
8
|
+
import InvocationStatus from './components/InvocationStatus';
|
9
|
+
import InvocationActions from './components/InvocationActions';
|
8
10
|
|
9
|
-
const Invocations = ({ status, items }) => {
|
11
|
+
const Invocations = ({ status, items, selectAll, areAllSelected, onSelect, isSelected }) => {
|
10
12
|
if (status === STATUS.ERROR) {
|
11
13
|
return (
|
12
14
|
<Alert type="error">
|
@@ -18,26 +20,51 @@ const Invocations = ({ status, items }) => {
|
|
18
20
|
}
|
19
21
|
|
20
22
|
const rows = items.length ? (
|
21
|
-
items.map(item => (
|
23
|
+
items.map((item, rowIndex) => (
|
24
|
+
<Tr key={`invocation-${item.id}`}>
|
25
|
+
<Td
|
26
|
+
select={{
|
27
|
+
rowIndex,
|
28
|
+
onSelect: (_event, isSelecting) => onSelect(item, rowIndex, isSelecting),
|
29
|
+
isSelected: isSelected(item)
|
30
|
+
}}
|
31
|
+
/>
|
32
|
+
<Td className="invocation_name">
|
33
|
+
<a href={`/foreman_patch/invocations/${item.id}`}>{item.name}</a>
|
34
|
+
</Td>
|
35
|
+
<Td>
|
36
|
+
<InvocationStatus status={item.status}/>
|
37
|
+
</Td>
|
38
|
+
<Td>
|
39
|
+
<InvocationActions {...item}/>
|
40
|
+
</Td>
|
41
|
+
</Tr>
|
42
|
+
))
|
22
43
|
) : (
|
23
|
-
<
|
24
|
-
<
|
25
|
-
</
|
44
|
+
<Tr>
|
45
|
+
<Td colSpan="4">{__('No hosts found.')}</Td>
|
46
|
+
</Tr>
|
26
47
|
);
|
27
48
|
|
28
49
|
return (
|
29
50
|
<LoadingState loading={!items.length && status === STATUS.PENDING}>
|
30
51
|
<div>
|
31
|
-
<
|
32
|
-
<
|
33
|
-
<
|
34
|
-
<
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
52
|
+
<TableComposable className="table table-bordered table-striped table-hover">
|
53
|
+
<Thead>
|
54
|
+
<Tr>
|
55
|
+
<Th
|
56
|
+
select={{
|
57
|
+
onSelect: (_event, isSelecting) => selectAll(isSelecting),
|
58
|
+
isSelected: areAllSelected
|
59
|
+
}}
|
60
|
+
/>
|
61
|
+
<Th>{__('Host')}</Th>
|
62
|
+
<Th className="col-md-2">{__('Status')}</Th>
|
63
|
+
<Th className="col-md-1">{__('Actions')}</Th>
|
64
|
+
</Tr>
|
65
|
+
</Thead>
|
66
|
+
<Tbody>{rows}</Tbody>
|
67
|
+
</TableComposable>
|
41
68
|
</div>
|
42
69
|
</LoadingState>
|
43
70
|
);
|
@@ -46,10 +73,15 @@ const Invocations = ({ status, items }) => {
|
|
46
73
|
Invocations.propTypes = {
|
47
74
|
status: PropTypes.string,
|
48
75
|
items: PropTypes.array.isRequired,
|
76
|
+
selectAll: PropTypes.func.isRequired,
|
77
|
+
areAllSelected: PropTypes.bool,
|
78
|
+
onSelect: PropTypes.func.isRequired,
|
79
|
+
isSelected: PropTypes.func.isRequired,
|
49
80
|
};
|
50
81
|
|
51
82
|
Invocations.defaultProps = {
|
52
83
|
status: null,
|
84
|
+
areAllSelected: false,
|
53
85
|
};
|
54
86
|
|
55
87
|
export default Invocations;
|
@@ -4,6 +4,7 @@ import { Grid } from 'patternfly-react';
|
|
4
4
|
|
5
5
|
import SearchBar from 'foremanReact/components/SearchBar';
|
6
6
|
import Pagination from 'foremanReact/components/Pagination/PaginationWrapper';
|
7
|
+
import { ActionButtons } form 'foremanReact/components/common/ActionButtons/ActionButtons';
|
7
8
|
import { getControllerSearchProps } from 'foremanReact/constants';
|
8
9
|
|
9
10
|
import Invocations from './Invocations';
|
@@ -17,6 +18,11 @@ const InvocationsPage = ({
|
|
17
18
|
pagination,
|
18
19
|
handleSearch,
|
19
20
|
handlePagination,
|
21
|
+
selectAll,
|
22
|
+
areAllSelected,
|
23
|
+
onSelect,
|
24
|
+
isSelected,
|
25
|
+
actions
|
20
26
|
}) => (
|
21
27
|
<div id="patch_invocations">
|
22
28
|
<Grid.Row>
|
@@ -35,9 +41,19 @@ const InvocationsPage = ({
|
|
35
41
|
}}
|
36
42
|
/>
|
37
43
|
</Grid.Col>
|
44
|
+
<Grid.Col md={6} className="title_action">
|
45
|
+
<ActionButtons buttons={[]} />
|
46
|
+
</Grid.Col>
|
38
47
|
</Grid.Row>
|
39
48
|
<br />
|
40
|
-
<Invocations
|
49
|
+
<Invocations
|
50
|
+
status={status}
|
51
|
+
items={items}
|
52
|
+
selectAll={selectAll}
|
53
|
+
areAllSelected={areAllSelected}
|
54
|
+
onSelect={onSelect}
|
55
|
+
isSelected={isSelected}
|
56
|
+
/>
|
41
57
|
<Pagination
|
42
58
|
viewType="table"
|
43
59
|
itemCount={total}
|
@@ -57,10 +73,17 @@ InvocationsPage.propTypes = {
|
|
57
73
|
pagination: PropTypes.object.isRequired,
|
58
74
|
handleSearch: PropTypes.func.isRequired,
|
59
75
|
handlePagination: PropTypes.func.isRequired,
|
76
|
+
selectAll: PropTypes.func.isRequired,
|
77
|
+
areAllSelected: PropTypes.bool,
|
78
|
+
onSelect: PropTypes.func.isRequired,
|
79
|
+
isSelected: PropTypes.func.isRequired,
|
80
|
+
actions: PropTypes.array,
|
60
81
|
};
|
61
82
|
|
62
83
|
InvocationsPage.defaultProps = {
|
63
84
|
status: null,
|
85
|
+
areAllSelected: false,
|
86
|
+
actions: []
|
64
87
|
};
|
65
88
|
|
66
89
|
export default InvocationsPage;
|
@@ -12,7 +12,7 @@ export const selectTotal = state =>
|
|
12
12
|
selectAPIResponse(state, INVOCATIONS).total || 0;
|
13
13
|
|
14
14
|
export const selectAutoRefresh = state =>
|
15
|
-
selectItems(state).some(item => (item.
|
15
|
+
selectItems(state).some(item => (item.status === 'pending' || item.status === 'planned'));
|
16
16
|
|
17
17
|
export const selectStatus = state => selectAPIStatus(state, INVOCATIONS);
|
18
18
|
|
@@ -3,9 +3,7 @@ import PropTypes from 'prop-types';
|
|
3
3
|
import { ActionButtons } from 'foremanReact/components/common/ActionButtons/ActionButtons';
|
4
4
|
import { translate as __ } from 'foremanReact/common/I18n';
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
const InvocationItem = ({ id, name, status, task_id, host_id }) => {
|
6
|
+
const InvocationActions = ({ id, name, status, task_id, host_id }) => {
|
9
7
|
|
10
8
|
const actions = [
|
11
9
|
{
|
@@ -41,21 +39,11 @@ const InvocationItem = ({ id, name, status, task_id, host_id }) => {
|
|
41
39
|
}
|
42
40
|
|
43
41
|
return (
|
44
|
-
<
|
45
|
-
<td className="invocation_name">
|
46
|
-
<a href={`/foreman_patch/invocations/${id}`}>{name}</a>
|
47
|
-
</td>
|
48
|
-
<td className="invocation_status">
|
49
|
-
<InvocationStatus status={status} />
|
50
|
-
</td>
|
51
|
-
<td className="invocation_actions">
|
52
|
-
<ActionButtons buttons={[...actions]} />
|
53
|
-
</td>
|
54
|
-
</tr>
|
42
|
+
<ActionButtons buttons={[...actions]} />
|
55
43
|
);
|
56
44
|
};
|
57
45
|
|
58
|
-
|
46
|
+
InvocationActions.propTypes = {
|
59
47
|
id: PropTypes.number.isRequired,
|
60
48
|
name: PropTypes.string.isRequired,
|
61
49
|
status: PropTypes.string.isRequired,
|
@@ -63,4 +51,4 @@ InvocationItem.propTypes = {
|
|
63
51
|
task_id: PropTypes.number.isRequired,
|
64
52
|
};
|
65
53
|
|
66
|
-
export default
|
54
|
+
export default InvocationActions;
|