foreman_patch 1.1.1 → 1.1.3
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/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;
|