rocketjob_mission_control 3.0.0.rc1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +10 -6
  3. data/app/assets/javascripts/rocket_job_mission_control/application.js +4 -3
  4. data/app/assets/javascripts/rocket_job_mission_control/base.js +12 -0
  5. data/app/assets/javascripts/rocket_job_mission_control/datatable.js +40 -0
  6. data/app/assets/javascripts/rocket_job_mission_control/dirmon_entries.js +16 -0
  7. data/app/assets/javascripts/rocket_job_mission_control/selectize.js +6 -0
  8. data/app/controllers/rocket_job_mission_control/active_workers_controller.rb +16 -5
  9. data/app/controllers/rocket_job_mission_control/application_controller.rb +2 -0
  10. data/app/controllers/rocket_job_mission_control/dirmon_entries_controller.rb +47 -67
  11. data/app/controllers/rocket_job_mission_control/jobs_controller.rb +113 -19
  12. data/app/controllers/rocket_job_mission_control/servers_controller.rb +71 -28
  13. data/app/datatables/rocket_job_mission_control/abstract_datatable.rb +3 -3
  14. data/app/datatables/rocket_job_mission_control/active_workers_datatable.rb +8 -14
  15. data/app/datatables/rocket_job_mission_control/dirmon_entries_datatable.rb +7 -15
  16. data/app/datatables/rocket_job_mission_control/jobs_datatable.rb +128 -13
  17. data/app/datatables/rocket_job_mission_control/servers_datatable.rb +13 -15
  18. data/app/helpers/rocket_job_mission_control/application_helper.rb +58 -0
  19. data/app/helpers/rocket_job_mission_control/jobs_helper.rb +15 -7
  20. data/app/helpers/rocket_job_mission_control/servers_helper.rb +1 -1
  21. data/app/models/rocket_job_mission_control/job_sanitizer.rb +47 -0
  22. data/app/models/rocket_job_mission_control/query.rb +24 -18
  23. data/app/views/layouts/rocket_job_mission_control/application.html.erb +43 -0
  24. data/app/views/layouts/rocket_job_mission_control/partials/_flash.html.erb +20 -0
  25. data/app/views/layouts/rocket_job_mission_control/partials/_header.html.erb +45 -0
  26. data/app/views/layouts/rocket_job_mission_control/partials/_sidebar.html.erb +12 -0
  27. data/app/views/rocket_job_mission_control/active_workers/index.html.erb +40 -0
  28. data/app/views/rocket_job_mission_control/dirmon_entries/_form.html.erb +60 -0
  29. data/app/views/rocket_job_mission_control/dirmon_entries/_sidebar.html.erb +38 -0
  30. data/app/views/rocket_job_mission_control/dirmon_entries/_status.html.erb +17 -0
  31. data/app/views/rocket_job_mission_control/dirmon_entries/edit.html.erb +4 -0
  32. data/app/views/rocket_job_mission_control/dirmon_entries/index.html.erb +33 -0
  33. data/app/views/rocket_job_mission_control/dirmon_entries/new.html.erb +8 -0
  34. data/app/views/rocket_job_mission_control/dirmon_entries/show.html.erb +29 -0
  35. data/app/views/rocket_job_mission_control/jobs/_pagination.html.erb +26 -0
  36. data/app/views/rocket_job_mission_control/jobs/_sidebar.html.erb +32 -0
  37. data/app/views/rocket_job_mission_control/jobs/_status.html.erb +42 -0
  38. data/app/views/rocket_job_mission_control/jobs/edit.html.erb +32 -0
  39. data/app/views/rocket_job_mission_control/jobs/exception.html.erb +19 -0
  40. data/app/views/rocket_job_mission_control/jobs/exceptions.html.erb +40 -0
  41. data/app/views/rocket_job_mission_control/jobs/index.html.erb +33 -0
  42. data/app/views/rocket_job_mission_control/jobs/show.html.erb +68 -0
  43. data/app/views/rocket_job_mission_control/servers/_sidebar.html.erb +31 -0
  44. data/app/views/rocket_job_mission_control/servers/index.html.erb +56 -0
  45. data/config/locales/en.yml +3 -10
  46. data/config/routes.rb +20 -17
  47. data/lib/rocket_job_mission_control/engine.rb +10 -0
  48. data/lib/rocket_job_mission_control/version.rb +1 -1
  49. data/test/compare_hashes.rb +17 -0
  50. data/test/controllers/rocket_job_mission_control/application_controller_test.rb +49 -0
  51. data/test/controllers/rocket_job_mission_control/dirmon_entries_controller_test.rb +417 -0
  52. data/test/controllers/rocket_job_mission_control/jobs_controller_test.rb +363 -0
  53. data/test/controllers/rocket_job_mission_control/servers_controller_test.rb +251 -0
  54. data/test/helpers/rocket_job_mission_control/application_helper_test.rb +54 -0
  55. data/test/helpers/rocket_job_mission_control/jobs_helper_test.rb +85 -0
  56. data/test/helpers/rocket_job_mission_control/pagination_helper_test.rb +23 -0
  57. data/test/helpers/rocket_job_mission_control/servers_helper_test.rb +64 -0
  58. data/test/helpers/rocket_job_mission_control/slices_helper_test.rb +30 -0
  59. data/test/models/rocket_job_mission_control/job_sanitizer_test.rb +92 -0
  60. data/test/models/rocket_job_mission_control/query_test.rb +136 -0
  61. data/test/test_helper.rb +23 -0
  62. metadata +75 -175
  63. data/app/assets/javascripts/rocket_job_mission_control/base.js.coffee +0 -11
  64. data/app/assets/javascripts/rocket_job_mission_control/datatable.js.coffee +0 -33
  65. data/app/assets/javascripts/rocket_job_mission_control/dirmon_entries.js.coffee +0 -13
  66. data/app/assets/javascripts/rocket_job_mission_control/selectize.js.coffee +0 -5
  67. data/app/assets/stylesheets/rocket_job_mission_control/jquery.bootstrap-touchspin.scss +0 -45
  68. data/app/controllers/rocket_job_mission_control/dirmon_entries/index_filters_controller.rb +0 -45
  69. data/app/controllers/rocket_job_mission_control/jobs/failures_controller.rb +0 -30
  70. data/app/controllers/rocket_job_mission_control/jobs/index_filters_controller.rb +0 -90
  71. data/app/controllers/rocket_job_mission_control/servers/index_filters_controller.rb +0 -49
  72. data/app/datatables/rocket_job_mission_control/completed_jobs_datatable.rb +0 -27
  73. data/app/datatables/rocket_job_mission_control/interrupted_jobs_datatable.rb +0 -26
  74. data/app/datatables/rocket_job_mission_control/queued_jobs_datatable.rb +0 -23
  75. data/app/datatables/rocket_job_mission_control/running_jobs_datatable.rb +0 -47
  76. data/app/datatables/rocket_job_mission_control/scheduled_jobs_datatable.rb +0 -31
  77. data/app/models/job_failures.rb +0 -20
  78. data/app/models/job_sanitizer.rb +0 -17
  79. data/app/views/layouts/rocket_job_mission_control/application.html.haml +0 -45
  80. data/app/views/layouts/rocket_job_mission_control/partials/_header.html.haml +0 -32
  81. data/app/views/layouts/rocket_job_mission_control/partials/_sidebar.html.haml +0 -11
  82. data/app/views/rocket_job_mission_control/active_workers/index.html.haml +0 -24
  83. data/app/views/rocket_job_mission_control/dirmon_entries/_form.html.haml +0 -37
  84. data/app/views/rocket_job_mission_control/dirmon_entries/_properties.html.haml +0 -30
  85. data/app/views/rocket_job_mission_control/dirmon_entries/_sidebar.html.haml +0 -27
  86. data/app/views/rocket_job_mission_control/dirmon_entries/_status.html.haml +0 -23
  87. data/app/views/rocket_job_mission_control/dirmon_entries/edit.html.haml +0 -4
  88. data/app/views/rocket_job_mission_control/dirmon_entries/index.html.haml +0 -18
  89. data/app/views/rocket_job_mission_control/dirmon_entries/index_filters/disabled.html.haml +0 -17
  90. data/app/views/rocket_job_mission_control/dirmon_entries/index_filters/enabled.html.haml +0 -17
  91. data/app/views/rocket_job_mission_control/dirmon_entries/index_filters/failed.html.haml +0 -17
  92. data/app/views/rocket_job_mission_control/dirmon_entries/index_filters/pending.html.haml +0 -17
  93. data/app/views/rocket_job_mission_control/dirmon_entries/new.html.haml +0 -6
  94. data/app/views/rocket_job_mission_control/dirmon_entries/show.html.haml +0 -23
  95. data/app/views/rocket_job_mission_control/jobs/_sidebar.html.haml +0 -28
  96. data/app/views/rocket_job_mission_control/jobs/_status.html.haml +0 -45
  97. data/app/views/rocket_job_mission_control/jobs/edit.html.haml +0 -34
  98. data/app/views/rocket_job_mission_control/jobs/exceptions.html.haml +0 -29
  99. data/app/views/rocket_job_mission_control/jobs/failures/_pagination.html.haml +0 -16
  100. data/app/views/rocket_job_mission_control/jobs/failures/index.html.haml +0 -32
  101. data/app/views/rocket_job_mission_control/jobs/index.html.haml +0 -25
  102. data/app/views/rocket_job_mission_control/jobs/index_filters/aborted.html.haml +0 -23
  103. data/app/views/rocket_job_mission_control/jobs/index_filters/completed.html.haml +0 -24
  104. data/app/views/rocket_job_mission_control/jobs/index_filters/failed.html.haml +0 -23
  105. data/app/views/rocket_job_mission_control/jobs/index_filters/paused.html.haml +0 -23
  106. data/app/views/rocket_job_mission_control/jobs/index_filters/queued.html.haml +0 -24
  107. data/app/views/rocket_job_mission_control/jobs/index_filters/running.html.haml +0 -25
  108. data/app/views/rocket_job_mission_control/jobs/index_filters/scheduled.html.haml +0 -24
  109. data/app/views/rocket_job_mission_control/jobs/show.html.haml +0 -51
  110. data/app/views/rocket_job_mission_control/servers/_actions.html.haml +0 -9
  111. data/app/views/rocket_job_mission_control/servers/_sidebar.html.haml +0 -20
  112. data/app/views/rocket_job_mission_control/servers/index.html.haml +0 -37
  113. data/app/views/rocket_job_mission_control/servers/index_filters/paused.html.haml +0 -37
  114. data/app/views/rocket_job_mission_control/servers/index_filters/running.html.haml +0 -37
  115. data/app/views/rocket_job_mission_control/servers/index_filters/starting.html.haml +0 -37
  116. data/app/views/rocket_job_mission_control/servers/index_filters/stopping.html.haml +0 -37
  117. data/spec/controllers/application_controller_spec.rb +0 -47
  118. data/spec/controllers/dirmon_entries/index_filters_controller_spec.rb +0 -77
  119. data/spec/controllers/dirmon_entries_controller_spec.rb +0 -383
  120. data/spec/controllers/jobs/failures_controller_spec.rb +0 -82
  121. data/spec/controllers/jobs/index_filters_controller_spec.rb +0 -66
  122. data/spec/controllers/jobs_controller_spec.rb +0 -172
  123. data/spec/controllers/workers/index_filters_controller_spec.rb +0 -59
  124. data/spec/controllers/workers_controller_spec.rb +0 -125
  125. data/spec/dummy/Rakefile +0 -7
  126. data/spec/dummy/config.ru +0 -4
  127. data/spec/dummy/config/application.rb +0 -26
  128. data/spec/dummy/config/boot.rb +0 -5
  129. data/spec/dummy/config/database.yml +0 -25
  130. data/spec/dummy/config/environment.rb +0 -5
  131. data/spec/dummy/config/environments/test.rb +0 -37
  132. data/spec/dummy/config/initializers/secret_token.rb +0 -7
  133. data/spec/dummy/config/initializers/session_store.rb +0 -3
  134. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  135. data/spec/dummy/config/mongoid.yml +0 -88
  136. data/spec/dummy/config/routes.rb +0 -3
  137. data/spec/dummy/config/secrets.yml +0 -22
  138. data/spec/dummy/config/symmetric-encryption.yml +0 -8
  139. data/spec/dummy/db/test.sqlite3 +0 -0
  140. data/spec/dummy/log/development.log +0 -0
  141. data/spec/dummy/log/test.log +0 -118933
  142. data/spec/helpers/application_helper_spec.rb +0 -58
  143. data/spec/helpers/jobs_helper_spec.rb +0 -35
  144. data/spec/helpers/pagination_helper_spec.rb +0 -21
  145. data/spec/helpers/servers_helper_spec.rb +0 -16
  146. data/spec/helpers/slices_helper_spec.rb +0 -33
  147. data/spec/models/job_failures_spec.rb +0 -14
  148. data/spec/models/job_sanitizer_spec.rb +0 -16
  149. data/spec/rails_helper.rb +0 -47
  150. data/spec/spec_helper.rb +0 -84
  151. data/vendor/assets/javascripts/jquery.bootstrap-touchspin.js +0 -686
  152. data/vendor/assets/javascripts/prism.js +0 -6
  153. data/vendor/assets/stylesheets/jquery.bootstrap-touchspin.css +0 -45
  154. data/vendor/assets/stylesheets/prism.scss +0 -160
@@ -1,40 +1,63 @@
1
1
  module RocketJobMissionControl
2
2
  class ServersController < RocketJobMissionControl::ApplicationController
3
- before_filter :find_server, only: [:stop, :pause, :resume, :destroy]
3
+ before_filter :find_server_or_redirect, only: [:stop, :pause, :resume, :destroy]
4
4
  before_filter :show_sidebar
5
5
 
6
6
  def index
7
- @query = RocketJobMissionControl::Query.new(RocketJob::Server.all, name: :asc)
8
- respond_to do |format|
9
- format.html
10
- format.json { render(json: ServersDatatable.new(view_context, @query)) }
11
- end
7
+ @data_table_url = servers_url(format: 'json')
8
+ @actions = [:pause_all, :resume_all, :stop_all, :destroy_zombies]
9
+ render_datatable(RocketJob::Server.all, 'All')
10
+ end
11
+
12
+ def starting
13
+ @data_table_url = starting_servers_url(format: 'json')
14
+ @actions = [:pause_all, :stop_all]
15
+ render_datatable(RocketJob::Server.starting, 'Starting')
16
+ end
17
+
18
+ def running
19
+ @data_table_url = running_servers_url(format: 'json')
20
+ @actions = [:pause_all, :stop_all, :destroy_zombies]
21
+ render_datatable(RocketJob::Server.running, 'Running')
12
22
  end
13
23
 
14
- VALID_STATES = {
15
- stop_all: 'stopped',
16
- pause_all: 'paused',
17
- resume_all: 'resumed',
18
- destroy_zombies: 'destroyed if zombified',
19
- }
24
+ def paused
25
+ @data_table_url = paused_servers_url(format: 'json')
26
+ @actions = [:resume_all, :destroy_zombies]
27
+ render_datatable(RocketJob::Server.paused, 'Paused')
28
+ end
29
+
30
+ def stopping
31
+ @data_table_url = stopping_servers_url(format: 'json')
32
+ @actions = [:destroy_zombies]
33
+ render_datatable(RocketJob::Server.stopping, 'Stopping')
34
+ end
35
+
36
+ def zombie
37
+ @data_table_url = zombie_servers_url(format: 'json')
38
+ @actions = [:destroy_zombies]
39
+ render_datatable(RocketJob::Server.zombies, 'Zombie')
40
+ end
41
+
42
+ VALID_ACTIONS = [:stop_all, :pause_all, :resume_all, :destroy_zombies]
20
43
 
21
44
  def update_all
22
45
  server_action = params[:server_action].to_sym
23
- if VALID_STATES.keys.include?(server_action)
24
- RocketJob::Server.send(server_action.to_sym)
25
- flash[:notice] = t(:success, scope: [:server, :update_all], server_action: VALID_STATES[server_action])
46
+ if VALID_ACTIONS.include?(server_action)
47
+ RocketJob::Server.public_send(server_action.to_sym)
26
48
  else
27
49
  flash[:alert] = t(:invalid, scope: [:server, :update_all])
28
50
  end
29
51
 
52
+ # TODO: Refresh the same page it was on
30
53
  respond_to do |format|
31
54
  format.html { redirect_to servers_path }
32
55
  end
33
56
  end
34
57
 
35
58
  def stop
36
- if @server.stop!
37
- flash[:notice] = t(:success, scope: [:server, :stop])
59
+ if @server.may_stop?
60
+ @server.stop!
38
61
  else
39
62
  flash[:alert] = t(:failure, scope: [:server, :stop])
40
63
  end
@@ -45,11 +68,8 @@ module RocketJobMissionControl
45
68
  end
46
69
 
47
70
  def destroy
48
- if @server.nil? || @server.destroy
49
- flash[:notice] = t(:success, scope: [:server, :destroy])
50
- else
51
- flash[:alert] = t(:failure, scope: [:server, :destroy])
52
- end
71
+ @server.destroy
72
+ flash[:notice] = t(:success, scope: [:server, :destroy])
53
73
 
54
74
  respond_to do |format|
55
75
  format.html { redirect_to servers_path }
@@ -57,8 +77,8 @@ module RocketJobMissionControl
57
77
  end
58
78
 
59
79
  def pause
60
- if @server.pause!
61
- flash[:notice] = t(:success, scope: [:server, :pause])
80
+ if @server.may_pause?
81
+ @server.pause!
62
82
  else
63
83
  flash[:alert] = t(:failure, scope: [:server, :pause])
64
84
  end
@@ -69,8 +89,8 @@ module RocketJobMissionControl
69
89
  end
70
90
 
71
91
  def resume
72
- if @server.resume!
73
- flash[:notice] = t(:success, scope: [:server, :resume])
92
+ if @server.may_resume?
93
+ @server.resume!
74
94
  else
75
95
  flash[:alert] = t(:failure, scope: [:server, :resume])
76
96
  end
@@ -82,8 +102,31 @@ module RocketJobMissionControl
82
102
 
83
103
  private
84
104
 
85
- def find_server
86
- @server = RocketJob::Server.find(params[:id])
105
+ def render_datatable(servers, description)
106
+ respond_to do |format|
107
+ format.html do
108
+ @description = description
109
+ @states = RocketJob::Server.aasm.states.map { |s| s.name.to_s }
110
+ @states << 'zombie'
111
+
112
+ @server_counts = RocketJob::Server.counts_by_state
113
+ # TODO: Move into RocketJob
114
+ @server_counts[:zombie] = RocketJob::Server.zombies.count
115
+ render :index
116
+ end
117
+ format.json do
118
+ query = RocketJobMissionControl::Query.new(servers, name: :asc)
119
+ render(json: ServersDatatable.new(view_context, query))
120
+ end
121
+ end
122
+ end
123
+
124
+ def find_server_or_redirect
125
+ unless @server = RocketJob::Server.where(id: params[:id]).first
126
+ flash[:alert] = t(:failure, scope: [:server, :find], id: params[:id])
127
+
128
+ redirect_to(servers_path)
129
+ end
87
130
  end
88
131
 
89
132
  def show_sidebar
@@ -16,13 +16,13 @@ module RocketJobMissionControl
16
16
  draw: params[:draw].to_i,
17
17
  recordsTotal: query.unfiltered_count,
18
18
  recordsFiltered: query.count,
19
- data: data(query.query)
19
+ data: query.query.collect{|record| map(record)}
20
20
  }
21
21
  end
22
22
 
23
23
  private
24
24
 
25
- def data(records)
25
+ def map(record)
26
26
  raise NotImplementedError
27
27
  end
28
28
 
@@ -51,7 +51,7 @@ module RocketJobMissionControl
51
51
  ap order
52
52
  sort_by = {}
53
53
  order.each_pair do |key, value|
54
- name = query.display_columns[value[:column].to_i]
54
+ name = query.display_columns[value[:column].to_i]
55
55
  raise(ArgumentError, "Invalid column id: #{value[:column]}. Must fit #{query.display_columns.inspect}") unless name.present?
56
56
  sort_by[name] = value[:dir]
57
57
  end
@@ -2,26 +2,20 @@ module RocketJobMissionControl
2
2
  class ActiveWorkersDatatable < AbstractDatatable
3
3
  delegate :job_path, :state_icon, to: :@view
4
4
 
5
- def initialize(view, query)
6
- super(view, query)
7
- end
8
-
9
5
  private
10
6
 
11
7
  def extract_query_params
12
8
  @query.order_by = nil
13
9
  end
14
10
 
15
- def data(active_workers)
16
- active_workers.collect do |active_worker|
17
- {
18
- '0' => worker_name_with_icon(active_worker, active_worker.job),
19
- '1' => job_name_with_link(active_worker.job.class.name, active_worker.job.id),
20
- '2' => h(active_worker.job.description.try!(:truncate, 50)),
21
- '3' => h("#{active_worker.duration} ago"),
22
- 'DT_RowClass' => 'card callout callout-running'
23
- }
24
- end
11
+ def map(active_worker)
12
+ {
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
+ }
25
19
  end
26
20
 
27
21
  def worker_name_with_icon(active_worker, job)
@@ -2,23 +2,15 @@ module RocketJobMissionControl
2
2
  class DirmonEntriesDatatable < AbstractDatatable
3
3
  delegate :dirmon_entry_path, :state_icon, to: :@view
4
4
 
5
- def initialize(view, query)
6
- query.display_columns = %w[name _type pattern]
7
- query.search_columns = [:job_class_name, :name, :pattern]
8
- super(view, query)
9
- end
10
-
11
5
  private
12
6
 
13
- def data(dirmons)
14
- dirmons.map do |dirmon|
15
- {
16
- '0' => name_with_link(dirmon),
17
- '1' => h(dirmon.job_class_name),
18
- '2' => h(dirmon.pattern.try(:truncate, 80)),
19
- 'DT_RowClass' => "card callout callout-#{dirmon.state}"
20
- }
21
- end
7
+ def map(dirmon)
8
+ {
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
+ }
22
14
  end
23
15
 
24
16
  def name_with_link(dirmon)
@@ -2,28 +2,92 @@ module RocketJobMissionControl
2
2
  class JobsDatatable < AbstractDatatable
3
3
  delegate :job_path, :job_icon, :edit_job_path,
4
4
  :abort_job_path, :job_path, :fail_job_path, :run_now_job_path, :pause_job_path,
5
- :resume_job_path, :retry_job_path, :job_failures_path, :job_action_link, :exceptions_job_path, to: :@view
5
+ :resume_job_path, :retry_job_path, :exception_job_path, :job_action_link, :exceptions_job_path, to: :@view
6
6
 
7
- def initialize(view, query)
8
- query.search_columns = [:_type, :description]
7
+ COMMON_FIELDS = [:id, :_type, :description, :completed_at, :created_at, :started_at, :state].freeze
8
+
9
+ ABORTED_COLUMNS = [
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
+ ]
15
+
16
+ ALL_COLUMNS = [
17
+ {display: 'Class', value: :class_with_link, field: '_type'},
18
+ {display: 'Description', value: :description, field: 'description'},
19
+ {display: 'Created', value: :created_at, field: 'created_at'},
20
+ {display: 'Duration', value: :duration, field: 'duration', orderable: false},
21
+ {display: 'Actions', value: :action_buttons, orderable: false}
22
+ ]
23
+ ALL_FIELDS = COMMON_FIELDS + [:run_at].freeze
24
+
25
+ COMPLETED_COLUMNS = [
26
+ {display: 'Class', value: :class_with_link, field: '_type', width: '30%'},
27
+ {display: 'Description', value: :description, field: 'description', width: '30%'},
28
+ {display: 'Duration', value: :duration, field: 'duration', orderable: false},
29
+ {display: 'Completed', value: :completed_ago, field: 'completed_at'},
30
+ {display: 'Actions', value: :action_buttons, orderable: false}
31
+ ]
32
+
33
+ FAILED_COLUMNS = ABORTED_COLUMNS.deep_dup
34
+ FAILED_COLUMNS[2][:display] = 'Failed'
35
+
36
+ PAUSED_COLUMNS = ABORTED_COLUMNS.deep_dup
37
+ PAUSED_COLUMNS[2][:display] = 'Paused'
38
+
39
+ QUEUED_COLUMNS = [
40
+ {display: 'Class', value: :class_with_link, field: '_type'},
41
+ {display: 'Description', value: :description, field: 'description'},
42
+ {display: 'Priority', value: :priority, field: 'priority'},
43
+ {display: 'Queued For', value: :duration, field: 'duration', orderable: false},
44
+ {display: 'Actions', value: :action_buttons, orderable: false}
45
+ ]
46
+ QUEUED_FIELDS = COMMON_FIELDS + [:run_at, :priority].freeze
47
+
48
+ RUNNING_COLUMNS = [
49
+ {display: 'Class', value: :class_with_link, field: '_type'},
50
+ {display: 'Description', value: :description, field: 'description'},
51
+ {display: 'Progress', value: :progress, field: 'percent_complete', orderable: false},
52
+ {display: 'Priority', value: :priority, field: 'priority'},
53
+ {display: 'Started', value: :started, field: 'started_at'},
54
+ {display: 'Actions', value: :action_buttons, orderable: false}
55
+ ]
56
+ RUNNING_FIELDS = COMMON_FIELDS + [:record_count, :collect_output, :input_categories, :output_categories, :encrypt, :compress, :slice_size, :priority, :sub_state, :percent_complete].freeze
57
+
58
+ SCHEDULED_COLUMNS = [
59
+ {display: 'Class', value: :class_with_link, field: '_type'},
60
+ {display: 'Description', value: :description, field: 'description'},
61
+ {display: 'Runs in', value: :time_till_run, field: 'run_at'},
62
+ {display: 'Cron Schedule', value: :cron_schedule, field: 'cron_schedule'},
63
+ {display: 'Actions', value: :action_buttons, orderable: false}
64
+ ]
65
+ SCHEDULED_FIELDS = COMMON_FIELDS + [:run_at, :cron_schedule].freeze
66
+
67
+ def initialize(view, query, columns)
68
+ @columns = columns
9
69
  super(view, query)
10
70
  end
11
71
 
12
72
  private
13
73
 
14
- def data(jobs)
15
- jobs.map do |job|
16
- {
17
- '0' => class_with_link(job),
18
- '1' => h(job.description.try(:truncate, 50)),
19
- '2' => h(job.created_at),
20
- '3' => h(job.duration),
21
- '4' => action_buttons(job),
22
- 'DT_RowClass' => "card callout callout-#{job.state}"
23
- }
74
+ def sort_column(index)
75
+ @columns[index.to_i][:field]
76
+ end
77
+
78
+ # Map the values for each column
79
+ def map(job)
80
+ index = 0
81
+ h = {}
82
+ @columns.each do |column|
83
+ h[index.to_s] = send(column[:value], job)
84
+ index += 1
24
85
  end
86
+ h['DT_RowClass'] = "card callout callout-#{job.state}"
87
+ h
25
88
  end
26
89
 
90
+ # Job View Helper methods
27
91
  def class_with_link(job)
28
92
  <<-EOS
29
93
  <a class='job-link' href="#{job_path(job.id)}">
@@ -33,6 +97,57 @@ module RocketJobMissionControl
33
97
  EOS
34
98
  end
35
99
 
100
+ def description(job)
101
+ h(job.description.try(:truncate, 50))
102
+ end
103
+
104
+ def duration(job)
105
+ h(job.duration)
106
+ end
107
+
108
+ def created_at(job)
109
+ h(job.created_at)
110
+ end
111
+
112
+ def priority(job)
113
+ h(job.priority)
114
+ end
115
+
116
+ def started(job)
117
+ "#{RocketJob.seconds_as_duration(Time.now - (job.started_at || Time.now))} ago" if job.started_at
118
+ end
119
+
120
+ def completed_ago(job)
121
+ "#{RocketJob.seconds_as_duration(Time.now - (job.completed_at || Time.now))} ago"
122
+ end
123
+
124
+ def time_till_run(job)
125
+ h(RocketJob.seconds_as_duration((job.run_at || Time.now) - Time.now))
126
+ end
127
+
128
+ def cron_schedule(job)
129
+ h(job.cron_schedule) if job.respond_to?(:cron_schedule)
130
+ end
131
+
132
+ def progress(job)
133
+ if (sub_state = job.attributes['sub_state']) && [:before, :after].include?(sub_state)
134
+ <<-EOS
135
+ <div class="job-status">
136
+ <div class="job-state">
137
+ <div class="left">Batch</div>
138
+ <div class="right running">#{sub_state}</div>
139
+ </div>
140
+ </div>
141
+ EOS
142
+ else
143
+ <<-EOS
144
+ <div class='progress'>
145
+ <div class='progress-bar' style="width: #{job.percent_complete}%;", title="#{job.percent_complete}% complete."></div>
146
+ </div>
147
+ EOS
148
+ end
149
+ end
150
+
36
151
  def action_buttons(job)
37
152
  events = valid_events(job)
38
153
  buttons = "<div class='inline-job-actions'>"
@@ -4,23 +4,21 @@ module RocketJobMissionControl
4
4
 
5
5
  def initialize(view, query)
6
6
  query.display_columns = %w[name heartbeat.workers started_at heartbeat.updated_at]
7
- query.search_columns = [:name]
7
+ query.search_columns = [:name]
8
8
  super(view, query)
9
9
  end
10
10
 
11
11
  private
12
12
 
13
- def data(servers)
14
- servers.collect do |server|
15
- {
16
- '0' => name_with_icon(server),
17
- '1' => h(threads(server)),
18
- '2' => h(started_ago(server)),
19
- '3' => h(time_since_heartbeat(server)),
20
- '4' => action_links_html(server),
21
- 'DT_RowClass' => "card callout #{server_card_class(server)}"
22
- }
23
- end
13
+ def map(server)
14
+ {
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
+ }
24
22
  end
25
23
 
26
24
  def name_with_icon(server)
@@ -31,15 +29,15 @@ module RocketJobMissionControl
31
29
  end
32
30
 
33
31
  def threads(server)
34
- "#{server.heartbeat.workers.to_i}/#{server.max_workers}"
32
+ "#{server.try!(:heartbeat).try!(:workers).to_i}/#{server.max_workers}"
35
33
  end
36
34
 
37
35
  def started_ago(server)
38
- "#{RocketJob.seconds_as_duration(Time.now - server.started_at)} ago"
36
+ "#{RocketJob.seconds_as_duration(Time.now - (server.started_at || Time.now))} ago"
39
37
  end
40
38
 
41
39
  def time_since_heartbeat(server)
42
- "#{RocketJob.seconds_as_duration(Time.now - server.heartbeat.updated_at)} ago"
40
+ "#{RocketJob.seconds_as_duration(Time.now - (server.try!(:heartbeat).try!(:updated_at) || Time.now))} ago"
43
41
  end
44
42
 
45
43
  def action_links_html(server)