rocketjob_mission_control 4.3.0 → 5.0.0.beta1
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 +12 -12
- data/app/controllers/rocket_job_mission_control/application_controller.rb +1 -2
- data/app/controllers/rocket_job_mission_control/dirmon_entries_controller.rb +20 -19
- data/app/controllers/rocket_job_mission_control/jobs_controller.rb +36 -35
- data/app/controllers/rocket_job_mission_control/servers_controller.rb +32 -38
- data/app/datatables/rocket_job_mission_control/abstract_datatable.rb +8 -6
- data/app/datatables/rocket_job_mission_control/active_workers_datatable.rb +5 -5
- data/app/datatables/rocket_job_mission_control/dirmon_entries_datatable.rb +4 -4
- data/app/datatables/rocket_job_mission_control/jobs_datatable.rb +55 -62
- data/app/datatables/rocket_job_mission_control/servers_datatable.rb +13 -14
- data/app/helpers/rocket_job_mission_control/application_helper.rb +42 -41
- data/app/helpers/rocket_job_mission_control/jobs_helper.rb +9 -10
- data/app/helpers/rocket_job_mission_control/pagination_helper.rb +1 -1
- data/app/helpers/rocket_job_mission_control/servers_helper.rb +6 -6
- data/app/helpers/rocket_job_mission_control/slices_helper.rb +2 -4
- data/app/models/rocket_job_mission_control/access_policy.rb +1 -2
- data/app/models/rocket_job_mission_control/authorization.rb +3 -2
- data/app/models/rocket_job_mission_control/job_sanitizer.rb +14 -17
- data/app/models/rocket_job_mission_control/query.rb +2 -5
- data/app/views/rocket_job_mission_control/jobs/_exceptions.html.erb +1 -1
- data/app/views/rocket_job_mission_control/jobs/edit_slice.html.erb +1 -1
- data/app/views/rocket_job_mission_control/servers/index.html.erb +2 -2
- data/config/initializers/assets.rb +5 -7
- data/config/locales/en.yml +3 -0
- data/config/routes.rb +20 -21
- data/lib/rocket_job_mission_control/engine.rb +8 -9
- data/lib/rocket_job_mission_control/version.rb +1 -1
- data/lib/rocketjob_mission_control.rb +1 -1
- data/test/compare_hashes.rb +1 -2
- data/test/controllers/rocket_job_mission_control/application_controller_test.rb +13 -13
- data/test/controllers/rocket_job_mission_control/dirmon_entries_controller_test.rb +107 -108
- data/test/controllers/rocket_job_mission_control/jobs_controller_test.rb +89 -93
- data/test/controllers/rocket_job_mission_control/servers_controller_test.rb +66 -103
- data/test/helpers/rocket_job_mission_control/application_helper_test.rb +13 -14
- data/test/helpers/rocket_job_mission_control/jobs_helper_test.rb +31 -31
- data/test/helpers/rocket_job_mission_control/pagination_helper_test.rb +7 -9
- data/test/helpers/rocket_job_mission_control/servers_helper_test.rb +15 -15
- data/test/helpers/rocket_job_mission_control/slices_helper_test.rb +8 -10
- data/test/models/rocket_job_mission_control/job_sanitizer_test.rb +39 -40
- data/test/models/rocket_job_mission_control/query_test.rb +26 -28
- data/test/test_helper.rb +12 -12
- metadata +28 -28
@@ -1,7 +1,7 @@
|
|
1
1
|
module RocketJobMissionControl
|
2
2
|
class AbstractDatatable
|
3
3
|
delegate :params, :link_to, :render, to: :@view
|
4
|
-
delegate :h, to:
|
4
|
+
delegate :h, to: "ERB::Util"
|
5
5
|
|
6
6
|
attr_accessor :view, :query
|
7
7
|
|
@@ -11,7 +11,7 @@ module RocketJobMissionControl
|
|
11
11
|
extract_query_params
|
12
12
|
end
|
13
13
|
|
14
|
-
def as_json(
|
14
|
+
def as_json(_options = {})
|
15
15
|
{
|
16
16
|
draw: params[:draw].to_i,
|
17
17
|
recordsTotal: query.unfiltered_count,
|
@@ -39,7 +39,7 @@ module RocketJobMissionControl
|
|
39
39
|
end
|
40
40
|
|
41
41
|
# Pagination
|
42
|
-
unless params[:length].present? && params[:length] ==
|
42
|
+
unless params[:length].present? && params[:length] == "-1"
|
43
43
|
query.start = params[:start].to_i
|
44
44
|
query.page_size = params.fetch(:length, 10).to_i
|
45
45
|
end
|
@@ -49,13 +49,15 @@ module RocketJobMissionControl
|
|
49
49
|
return nil unless order.present?
|
50
50
|
|
51
51
|
sort_by = {}
|
52
|
-
order.each_pair do |
|
52
|
+
order.each_pair do |_key, value|
|
53
53
|
name = query.display_columns[value[:column].to_i]
|
54
|
-
|
54
|
+
unless name.present?
|
55
|
+
raise(ArgumentError, "Invalid column id: #{value[:column]}. Must fit #{query.display_columns.inspect}")
|
56
|
+
end
|
57
|
+
|
55
58
|
sort_by[name] = value[:dir]
|
56
59
|
end
|
57
60
|
sort_by
|
58
61
|
end
|
59
|
-
|
60
62
|
end
|
61
63
|
end
|
@@ -10,11 +10,11 @@ module RocketJobMissionControl
|
|
10
10
|
|
11
11
|
def map(active_worker)
|
12
12
|
{
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
"0" => worker_name_with_icon(active_worker, active_worker.job),
|
14
|
+
"1" => job_name_with_link(active_worker.job.class.name, active_worker.job.id),
|
15
|
+
"2" => h(active_worker.job.description.try!(:truncate, 50)),
|
16
|
+
"3" => h("#{active_worker.duration} ago"),
|
17
|
+
"DT_RowClass" => "card callout callout-running"
|
18
18
|
}
|
19
19
|
end
|
20
20
|
|
@@ -6,10 +6,10 @@ module RocketJobMissionControl
|
|
6
6
|
|
7
7
|
def map(dirmon)
|
8
8
|
{
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
"0" => name_with_link(dirmon),
|
10
|
+
"1" => h(dirmon.job_class_name),
|
11
|
+
"2" => h(dirmon.pattern.try(:truncate, 80)),
|
12
|
+
"DT_RowClass" => "card callout callout-#{dirmon.state}"
|
13
13
|
}
|
14
14
|
end
|
15
15
|
|
@@ -4,68 +4,68 @@ module RocketJobMissionControl
|
|
4
4
|
:abort_job_path, :job_path, :fail_job_path, :run_now_job_path, :pause_job_path,
|
5
5
|
:resume_job_path, :retry_job_path, :exception_job_path, :job_action_link, :exceptions_job_path, to: :@view
|
6
6
|
|
7
|
-
COMMON_FIELDS = [
|
7
|
+
COMMON_FIELDS = %i[id _type description completed_at created_at started_at state worker_name login].freeze
|
8
8
|
|
9
9
|
ABORTED_COLUMNS = [
|
10
|
-
{display:
|
11
|
-
{display:
|
12
|
-
{display:
|
13
|
-
{display:
|
14
|
-
]
|
10
|
+
{display: "Class", value: :class_with_link, field: "_type", width: "30%"},
|
11
|
+
{display: "Description", value: :description, field: "description", width: "30%"},
|
12
|
+
{display: "Aborted", value: :completed_ago, field: "completed_at"},
|
13
|
+
{display: "Actions", value: :action_buttons, orderable: false}
|
14
|
+
].freeze
|
15
15
|
|
16
16
|
COMPLETED_COLUMNS = [
|
17
|
-
{display:
|
18
|
-
{display:
|
19
|
-
{display:
|
20
|
-
{display:
|
21
|
-
{display:
|
22
|
-
]
|
17
|
+
{display: "Class", value: :class_with_link, field: "_type", width: "30%"},
|
18
|
+
{display: "Description", value: :description, field: "description", width: "30%"},
|
19
|
+
{display: "Duration", value: :duration, field: "duration", orderable: false},
|
20
|
+
{display: "Completed", value: :completed_ago, field: "completed_at"},
|
21
|
+
{display: "Actions", value: :action_buttons, orderable: false}
|
22
|
+
].freeze
|
23
23
|
|
24
24
|
FAILED_COLUMNS = ABORTED_COLUMNS.deep_dup
|
25
|
-
FAILED_COLUMNS[2][:display] =
|
25
|
+
FAILED_COLUMNS[2][:display] = "Failed"
|
26
26
|
|
27
27
|
PAUSED_COLUMNS = ABORTED_COLUMNS.deep_dup
|
28
|
-
PAUSED_COLUMNS[2][:display] =
|
28
|
+
PAUSED_COLUMNS[2][:display] = "Paused"
|
29
29
|
|
30
30
|
QUEUED_COLUMNS = [
|
31
|
-
{display:
|
32
|
-
{display:
|
33
|
-
{display:
|
34
|
-
{display:
|
35
|
-
{display:
|
36
|
-
{display:
|
37
|
-
]
|
38
|
-
QUEUED_FIELDS
|
31
|
+
{display: "Class", value: :class_with_link, field: "_type"},
|
32
|
+
{display: "Description", value: :description, field: "description"},
|
33
|
+
{display: "Record Count", value: :record_count, field: "record_count"},
|
34
|
+
{display: "Priority", value: :priority, field: "priority"},
|
35
|
+
{display: "Queued For", value: :duration, field: "duration", orderable: false},
|
36
|
+
{display: "Actions", value: :action_buttons, orderable: false}
|
37
|
+
].freeze
|
38
|
+
QUEUED_FIELDS = (COMMON_FIELDS + %i[record_count run_at priority]).freeze
|
39
39
|
|
40
40
|
RUNNING_COLUMNS = [
|
41
|
-
{display:
|
42
|
-
{display:
|
43
|
-
{display:
|
44
|
-
{display:
|
45
|
-
{display:
|
46
|
-
{display:
|
47
|
-
{display:
|
48
|
-
{display:
|
49
|
-
]
|
50
|
-
RUNNING_FIELDS
|
41
|
+
{display: "Class", value: :class_with_link, field: "_type"},
|
42
|
+
{display: "Description", value: :description, field: "description"},
|
43
|
+
{display: "Record Count", value: :record_count, field: "record_count"},
|
44
|
+
{display: "Progress", value: :progress, field: "percent_complete", orderable: false},
|
45
|
+
{display: "Workers", value: :worker_count, field: "worker_count", orderable: false},
|
46
|
+
{display: "Priority", value: :priority, field: "priority"},
|
47
|
+
{display: "Started", value: :started, field: "started_at"},
|
48
|
+
{display: "Actions", value: :action_buttons, orderable: false}
|
49
|
+
].freeze
|
50
|
+
RUNNING_FIELDS = (COMMON_FIELDS + %i[record_count collect_output input_categories output_categories encrypt compress slice_size priority sub_state percent_complete]).freeze
|
51
51
|
|
52
52
|
SCHEDULED_COLUMNS = [
|
53
|
-
{display:
|
54
|
-
{display:
|
55
|
-
{display:
|
56
|
-
{display:
|
57
|
-
{display:
|
58
|
-
]
|
59
|
-
SCHEDULED_FIELDS
|
53
|
+
{display: "Class", value: :class_with_link, field: "_type"},
|
54
|
+
{display: "Description", value: :description, field: "description"},
|
55
|
+
{display: "Runs in", value: :time_till_run, field: "run_at"},
|
56
|
+
{display: "Cron Schedule", value: :cron_schedule, field: "cron_schedule"},
|
57
|
+
{display: "Actions", value: :action_buttons, orderable: false}
|
58
|
+
].freeze
|
59
|
+
SCHEDULED_FIELDS = (COMMON_FIELDS + %i[run_at cron_schedule]).freeze
|
60
60
|
|
61
61
|
ALL_COLUMNS = [
|
62
|
-
{display:
|
63
|
-
{display:
|
64
|
-
{display:
|
65
|
-
{display:
|
66
|
-
{display:
|
67
|
-
]
|
68
|
-
ALL_FIELDS
|
62
|
+
{display: "Class", value: :class_with_link, field: "_type"},
|
63
|
+
{display: "Description", value: :description, field: "description"},
|
64
|
+
{display: "Created", value: :created_at, field: "created_at"},
|
65
|
+
{display: "Duration", value: :duration, field: "duration", orderable: false},
|
66
|
+
{display: "Actions", value: :action_buttons, orderable: false}
|
67
|
+
].freeze
|
68
|
+
ALL_FIELDS = (QUEUED_FIELDS + RUNNING_FIELDS + SCHEDULED_FIELDS).uniq.freeze
|
69
69
|
|
70
70
|
def initialize(view, query, columns)
|
71
71
|
@columns = columns
|
@@ -84,9 +84,9 @@ module RocketJobMissionControl
|
|
84
84
|
h = {}
|
85
85
|
@columns.each do |column|
|
86
86
|
h[index.to_s] = send(column[:value], job)
|
87
|
-
index
|
87
|
+
index += 1
|
88
88
|
end
|
89
|
-
h[
|
89
|
+
h["DT_RowClass"] = "card callout callout-#{job_state(job)}"
|
90
90
|
h
|
91
91
|
end
|
92
92
|
|
@@ -121,7 +121,7 @@ module RocketJobMissionControl
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def record_count(job)
|
124
|
-
job.attributes.key?(
|
124
|
+
job.attributes.key?("record_count") ? h(job.record_count) : 0
|
125
125
|
end
|
126
126
|
|
127
127
|
def started(job)
|
@@ -141,7 +141,7 @@ module RocketJobMissionControl
|
|
141
141
|
end
|
142
142
|
|
143
143
|
def progress(job)
|
144
|
-
if (sub_state = job.attributes[
|
144
|
+
if (sub_state = job.attributes["sub_state"]) && %i[before after].include?(sub_state)
|
145
145
|
<<-EOS
|
146
146
|
<div class="job-status">
|
147
147
|
<div class="job-state">
|
@@ -162,27 +162,20 @@ module RocketJobMissionControl
|
|
162
162
|
def action_buttons(job)
|
163
163
|
events = valid_events(job)
|
164
164
|
buttons = "<div class='inline-job-actions'>"
|
165
|
-
if job.scheduled? && view.can?(:run_now, job)
|
166
|
-
buttons += "#{ job_action_link('Run', run_now_job_path(job), :patch) }"
|
167
|
-
end
|
165
|
+
buttons += job_action_link("Run", run_now_job_path(job), :patch).to_s if job.scheduled? && view.can?(:run_now, job)
|
168
166
|
if events.include?(:pause) && job.pausable? && view.can?(:pause, job)
|
169
|
-
buttons +=
|
167
|
+
buttons += job_action_link("Pause", pause_job_path(job), :patch).to_s
|
170
168
|
end
|
171
169
|
if events.include?(:resume) && view.can?(:resume, job)
|
172
|
-
buttons +=
|
173
|
-
end
|
174
|
-
if events.include?(:retry) && view.can?(:retry, job)
|
175
|
-
buttons += "#{ job_action_link('Retry', retry_job_path(job), :patch) }"
|
176
|
-
end
|
177
|
-
if view.can?(:destroy, job)
|
178
|
-
buttons += "#{ job_action_link('Destroy', job_path(job), :delete) }"
|
170
|
+
buttons += job_action_link("Resume", resume_job_path(job), :patch).to_s
|
179
171
|
end
|
172
|
+
buttons += job_action_link("Retry", retry_job_path(job), :patch).to_s if events.include?(:retry) && view.can?(:retry, job)
|
173
|
+
buttons += job_action_link("Destroy", job_path(job), :delete).to_s if view.can?(:destroy, job)
|
180
174
|
buttons += "</div>"
|
181
175
|
end
|
182
176
|
|
183
177
|
def valid_events(job)
|
184
178
|
job.aasm.events.collect(&:name)
|
185
179
|
end
|
186
|
-
|
187
180
|
end
|
188
181
|
end
|
@@ -12,12 +12,12 @@ module RocketJobMissionControl
|
|
12
12
|
|
13
13
|
def map(server)
|
14
14
|
{
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
"0" => name_with_icon(server),
|
16
|
+
"1" => h(threads(server)),
|
17
|
+
"2" => h(started_ago(server)),
|
18
|
+
"3" => h(time_since_heartbeat(server)),
|
19
|
+
"4" => action_links_html(server),
|
20
|
+
"DT_RowClass" => "card callout #{server_card_class(server)}"
|
21
21
|
}
|
22
22
|
end
|
23
23
|
|
@@ -45,33 +45,32 @@ module RocketJobMissionControl
|
|
45
45
|
events = valid_events(server)
|
46
46
|
|
47
47
|
if events.include?(:resume) && view.can?(:resume, server)
|
48
|
-
actions +=
|
48
|
+
actions += (link_to "resume", resume_server_path(server), method: :patch, class: "btn btn-default", data: {confirm: "Resume this server?"}).to_s
|
49
49
|
end
|
50
50
|
|
51
51
|
if events.include?(:pause) && view.can?(:pause, server)
|
52
|
-
actions +=
|
52
|
+
actions += (link_to "pause", pause_server_path(server), method: :patch, class: "btn btn-default", data: {confirm: "Pause this server?"}).to_s
|
53
53
|
end
|
54
54
|
|
55
55
|
if events.include?(:stop) && view.can?(:stop, server)
|
56
|
-
actions +=
|
56
|
+
actions += (link_to "stop", stop_server_path(server), method: :patch, class: "btn btn-danger", data: {confirm: "Stop this server?"}).to_s
|
57
57
|
end
|
58
58
|
|
59
59
|
if server.stopping? && view.can?(:destroy, server)
|
60
|
-
actions
|
61
|
-
confirmation =
|
60
|
+
actions += "Server is stopping..."
|
61
|
+
confirmation = ""
|
62
62
|
unless server.zombie?
|
63
63
|
confirmation << "Warning!\n\nDestroying this server will hard kill its active workers/jobs.\nKilled jobs will be requeued for processing on another worker.\n\n"
|
64
64
|
end
|
65
65
|
confirmation << "Are you sure you want to destroy #{server.name} ?"
|
66
|
-
actions +=
|
66
|
+
actions += (link_to "destroy", server_path(server), method: :delete, class: "btn btn-danger", data: {confirm: confirmation}).to_s
|
67
67
|
end
|
68
68
|
|
69
|
-
actions +=
|
69
|
+
actions += "</div>"
|
70
70
|
end
|
71
71
|
|
72
72
|
def valid_events(server)
|
73
73
|
server.aasm.events.collect(&:name)
|
74
74
|
end
|
75
|
-
|
76
75
|
end
|
77
76
|
end
|
@@ -1,42 +1,43 @@
|
|
1
1
|
module RocketJobMissionControl
|
2
2
|
module ApplicationHelper
|
3
3
|
STATE_ICON_MAP = {
|
4
|
-
aborted:
|
5
|
-
completed:
|
6
|
-
disabled:
|
7
|
-
enabled:
|
8
|
-
failed:
|
9
|
-
paused:
|
10
|
-
pending:
|
11
|
-
queued:
|
12
|
-
running:
|
13
|
-
sleeping:
|
14
|
-
scheduled:
|
15
|
-
starting:
|
16
|
-
stopping:
|
17
|
-
zombie:
|
18
|
-
}
|
4
|
+
aborted: "fas fa-stop",
|
5
|
+
completed: "fas fa-check",
|
6
|
+
disabled: "fas fa-stop",
|
7
|
+
enabled: "fas fa-check",
|
8
|
+
failed: "fas fa-exclamation-triangle",
|
9
|
+
paused: "fas fa-pause",
|
10
|
+
pending: "fas fa-inbox",
|
11
|
+
queued: "fas fa-inbox",
|
12
|
+
running: "fas fa-play",
|
13
|
+
sleeping: "fas fa-hourglass",
|
14
|
+
scheduled: "fas fa-clock",
|
15
|
+
starting: "fas fa-cogs",
|
16
|
+
stopping: "fas fa-stop",
|
17
|
+
zombie: "fas fa-hourglass"
|
18
|
+
}.freeze
|
19
19
|
|
20
20
|
def state_icon(state)
|
21
|
-
STATE_ICON_MAP[state.to_sym] +
|
21
|
+
STATE_ICON_MAP[state.to_sym] + " " + state.to_s
|
22
22
|
end
|
23
23
|
|
24
24
|
def site_title
|
25
|
-
|
25
|
+
"Rocket Job Mission Control"
|
26
26
|
end
|
27
27
|
|
28
28
|
def title
|
29
29
|
@page_title ||= params[:controller].to_s.titleize
|
30
|
-
h(@full_title || [@page_title, site_title].compact.join(
|
30
|
+
h(@full_title || [@page_title, site_title].compact.join(" | "))
|
31
31
|
end
|
32
32
|
|
33
33
|
def active_page(path)
|
34
|
-
|
34
|
+
"active" if current_page?(path)
|
35
35
|
end
|
36
36
|
|
37
37
|
def pretty_print_array_or_hash(arguments)
|
38
|
-
return arguments unless arguments.
|
39
|
-
|
38
|
+
return arguments unless arguments.is_a?(Array) || arguments.is_a?(Hash)
|
39
|
+
|
40
|
+
json_string_options = {space: " ", indent: " ", array_nl: "<br />", object_nl: "<br />"}
|
40
41
|
JSON.generate(arguments, json_string_options).html_safe
|
41
42
|
end
|
42
43
|
|
@@ -60,49 +61,49 @@ module RocketJobMissionControl
|
|
60
61
|
# When editing a job the values are of the correct type.
|
61
62
|
# When editing a dirmon entry values are strings.
|
62
63
|
field = klass.fields[field_name.to_s]
|
63
|
-
return unless field
|
64
|
+
return unless field&.type
|
64
65
|
|
65
66
|
placeholder = field.default_val
|
66
67
|
placeholder = nil if placeholder.is_a?(Proc)
|
67
68
|
|
68
69
|
case field.type.name
|
69
|
-
when
|
70
|
+
when "Symbol", "String", "Integer"
|
70
71
|
options = extract_inclusion_values(klass, field_name)
|
71
72
|
str = "[#{field.type.name}]\n".html_safe
|
72
73
|
if options
|
73
|
-
str + f.select(field_name, options, {
|
74
|
+
str + f.select(field_name, options, {include_blank: options.include?(nil) || include_nil_selectors, selected: value}, {class: "selectize form-control"})
|
74
75
|
else
|
75
|
-
if field.type.name ==
|
76
|
-
str + f.number_field(field_name, value: value, class:
|
76
|
+
if field.type.name == "Integer"
|
77
|
+
str + f.number_field(field_name, value: value, class: "form-control", placeholder: placeholder)
|
77
78
|
else
|
78
|
-
str + f.text_field(field_name, value: value, class:
|
79
|
+
str + f.text_field(field_name, value: value, class: "form-control", placeholder: placeholder)
|
79
80
|
end
|
80
81
|
end
|
81
|
-
when
|
82
|
+
when "Hash"
|
82
83
|
"[JSON Hash]\n".html_safe +
|
83
|
-
f.text_field(field_name, value: value ? value.to_json :
|
84
|
-
when
|
84
|
+
f.text_field(field_name, value: value ? value.to_json : "", class: "form-control", placeholder: '{"key1":"value1", "key2":"value2", "key3":"value3"}')
|
85
|
+
when "Array"
|
85
86
|
options = Array(value)
|
86
87
|
"[Array]\n".html_safe +
|
87
|
-
f.select(field_name, options_for_select(options, options), {
|
88
|
-
when
|
88
|
+
f.select(field_name, options_for_select(options, options), {include_hidden: false}, {class: "selectize form-control", multiple: true})
|
89
|
+
when "Mongoid::Boolean"
|
89
90
|
name = "#{field_name}_true".to_sym
|
90
91
|
value = value.to_s
|
91
|
-
str
|
92
|
-
str << f.radio_button(field_name,
|
93
|
-
str <<
|
94
|
-
str <<
|
95
|
-
str <<
|
92
|
+
str = '<div class="radio-buttons">'.html_safe
|
93
|
+
str << f.radio_button(field_name, "true", checked: value == "true")
|
94
|
+
str << " ".html_safe + f.label(name, "true")
|
95
|
+
str << " ".html_safe + f.radio_button(field_name, "false", checked: value == "false")
|
96
|
+
str << " ".html_safe + f.label(name, "false")
|
96
97
|
# Allow this field to be unset (nil).
|
97
98
|
if include_nil_selectors
|
98
|
-
str <<
|
99
|
-
str <<
|
99
|
+
str << " ".html_safe + f.radio_button(field_name, "", checked: value == "")
|
100
|
+
str << " ".html_safe + f.label(name, "nil")
|
100
101
|
end
|
101
102
|
|
102
|
-
str <<
|
103
|
+
str << "</div>".html_safe
|
103
104
|
else
|
104
105
|
"[#{field.type.name}]".html_safe +
|
105
|
-
f.text_field(field_name, value: value, class:
|
106
|
+
f.text_field(field_name, value: value, class: "form-control", placeholder: placeholder)
|
106
107
|
end
|
107
108
|
end
|
108
109
|
end
|
@@ -20,7 +20,7 @@ module RocketJobMissionControl
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def job_states_with_scheduled
|
23
|
-
@job_states_with_scheduled ||= [
|
23
|
+
@job_states_with_scheduled ||= ["scheduled"] + job_states
|
24
24
|
end
|
25
25
|
|
26
26
|
def job_counts_by_state(state)
|
@@ -32,35 +32,34 @@ module RocketJobMissionControl
|
|
32
32
|
@job_counts.fetch(state.downcase.to_sym, 0)
|
33
33
|
end
|
34
34
|
|
35
|
-
def job_action_link(action, path, http_method
|
35
|
+
def job_action_link(action, path, http_method = :get)
|
36
36
|
link_to(
|
37
37
|
action,
|
38
38
|
path,
|
39
39
|
method: http_method,
|
40
40
|
title: "#{action} job",
|
41
|
-
class:
|
42
|
-
data: {confirm: t(:confirm, scope: [
|
41
|
+
class: "btn btn-default",
|
42
|
+
data: {confirm: t(:confirm, scope: %i[job action], action: action)}
|
43
43
|
)
|
44
44
|
end
|
45
45
|
|
46
|
-
def job_action_links_for_show(action, path, http_method
|
46
|
+
def job_action_links_for_show(action, path, http_method = :get)
|
47
47
|
link_to(
|
48
48
|
action,
|
49
49
|
path,
|
50
50
|
method: http_method,
|
51
51
|
title: "#{action} job",
|
52
|
-
class:
|
53
|
-
data: {confirm: t(:confirm, scope: [
|
52
|
+
class: "btn btn-primary",
|
53
|
+
data: {confirm: t(:confirm, scope: %i[job action], action: action)}
|
54
54
|
)
|
55
55
|
end
|
56
56
|
|
57
57
|
def job_selected_class(job, selected_job)
|
58
58
|
if selected_job.present? && job.id == selected_job.id
|
59
|
-
|
59
|
+
"selected"
|
60
60
|
else
|
61
|
-
|
61
|
+
""
|
62
62
|
end
|
63
63
|
end
|
64
|
-
|
65
64
|
end
|
66
65
|
end
|