rocketjob_mission_control 1.2.4 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +201 -0
  3. data/README.md +85 -0
  4. data/Rakefile +12 -18
  5. data/app/assets/javascripts/rocket_job_mission_control/application.js +3 -0
  6. data/app/assets/javascripts/rocket_job_mission_control/base.js.coffee +9 -12
  7. data/app/assets/javascripts/rocket_job_mission_control/datatable.js.coffee +31 -0
  8. data/app/assets/javascripts/rocket_job_mission_control/dirmon_entries.js.coffee +0 -1
  9. data/app/assets/stylesheets/rocket_job_mission_control/application.scss +2 -0
  10. data/app/assets/stylesheets/rocket_job_mission_control/base.scss +310 -357
  11. data/app/assets/stylesheets/rocket_job_mission_control/bootstrap_and_overrides.scss +474 -3
  12. data/app/assets/stylesheets/rocket_job_mission_control/callout.scss +57 -12
  13. data/app/assets/stylesheets/rocket_job_mission_control/jobs.scss +3 -2
  14. data/app/assets/stylesheets/rocket_job_mission_control/worker_processes.scss +9 -0
  15. data/app/controllers/rocket_job_mission_control/active_processes_controller.rb +26 -0
  16. data/app/controllers/rocket_job_mission_control/dirmon_entries/index_filters_controller.rb +50 -0
  17. data/app/controllers/rocket_job_mission_control/dirmon_entries_controller.rb +11 -14
  18. data/app/controllers/rocket_job_mission_control/jobs/failures_controller.rb +2 -2
  19. data/app/controllers/rocket_job_mission_control/jobs/index_filters_controller.rb +69 -0
  20. data/app/controllers/rocket_job_mission_control/jobs_controller.rb +10 -12
  21. data/app/controllers/rocket_job_mission_control/workers/index_filters_controller.rb +50 -0
  22. data/app/controllers/rocket_job_mission_control/workers_controller.rb +14 -5
  23. data/app/datatables/rocket_job_mission_control/active_processes_datatable.rb +79 -0
  24. data/app/datatables/rocket_job_mission_control/completed_jobs_datatable.rb +26 -0
  25. data/app/datatables/rocket_job_mission_control/dirmon_entries_datatable.rb +95 -0
  26. data/app/datatables/rocket_job_mission_control/interrupted_jobs_datatable.rb +25 -0
  27. data/app/datatables/rocket_job_mission_control/jobs_datatable.rb +95 -0
  28. data/app/datatables/rocket_job_mission_control/queued_jobs_datatable.rb +22 -0
  29. data/app/datatables/rocket_job_mission_control/running_jobs_datatable.rb +35 -0
  30. data/app/datatables/rocket_job_mission_control/scheduled_jobs_datatable.rb +30 -0
  31. data/app/datatables/rocket_job_mission_control/workers_datatable.rb +127 -0
  32. data/app/helpers/rocket_job_mission_control/application_helper.rb +21 -2
  33. data/app/helpers/rocket_job_mission_control/dirmon_entries_helper.rb +7 -0
  34. data/app/helpers/rocket_job_mission_control/jobs_helper.rb +9 -26
  35. data/app/helpers/rocket_job_mission_control/workers_helper.rb +18 -6
  36. data/app/interactors/rocket_job_mission_control/dirmon_entries/search.rb +19 -0
  37. data/app/interactors/rocket_job_mission_control/jobs/search.rb +19 -0
  38. data/app/interactors/rocket_job_mission_control/workers/search.rb +19 -0
  39. data/app/models/job_failures.rb +5 -5
  40. data/app/views/layouts/rocket_job_mission_control/application.html.haml +22 -22
  41. data/app/views/layouts/rocket_job_mission_control/partials/_header.html.haml +33 -18
  42. data/app/views/layouts/rocket_job_mission_control/partials/_sidebar.html.haml +11 -24
  43. data/app/views/rocket_job_mission_control/active_processes/index.html.haml +24 -0
  44. data/app/views/rocket_job_mission_control/dirmon_entries/_form.html.haml +11 -10
  45. data/app/views/rocket_job_mission_control/dirmon_entries/_properties.html.haml +6 -3
  46. data/app/views/rocket_job_mission_control/dirmon_entries/_sidebar.html.haml +27 -0
  47. data/app/views/rocket_job_mission_control/dirmon_entries/_status.html.haml +0 -3
  48. data/app/views/rocket_job_mission_control/dirmon_entries/edit.html.haml +3 -7
  49. data/app/views/rocket_job_mission_control/dirmon_entries/index.html.haml +17 -10
  50. data/app/views/rocket_job_mission_control/dirmon_entries/index_filters/disabled.html.haml +17 -0
  51. data/app/views/rocket_job_mission_control/dirmon_entries/index_filters/enabled.html.haml +17 -0
  52. data/app/views/rocket_job_mission_control/dirmon_entries/index_filters/failed.html.haml +17 -0
  53. data/app/views/rocket_job_mission_control/dirmon_entries/index_filters/pending.html.haml +17 -0
  54. data/app/views/rocket_job_mission_control/dirmon_entries/new.html.haml +5 -8
  55. data/app/views/rocket_job_mission_control/dirmon_entries/show.html.haml +18 -22
  56. data/app/views/rocket_job_mission_control/jobs/_sidebar.html.haml +28 -0
  57. data/app/views/rocket_job_mission_control/jobs/failures/index.html.haml +2 -2
  58. data/app/views/rocket_job_mission_control/jobs/index.html.haml +23 -10
  59. data/app/views/rocket_job_mission_control/jobs/index_filters/aborted.html.haml +22 -0
  60. data/app/views/rocket_job_mission_control/jobs/index_filters/completed.html.haml +23 -0
  61. data/app/views/rocket_job_mission_control/jobs/index_filters/failed.html.haml +22 -0
  62. data/app/views/rocket_job_mission_control/jobs/index_filters/paused.html.haml +22 -0
  63. data/app/views/rocket_job_mission_control/jobs/index_filters/queued.html.haml +23 -0
  64. data/app/views/rocket_job_mission_control/jobs/index_filters/running.html.haml +24 -0
  65. data/app/views/rocket_job_mission_control/jobs/index_filters/scheduled.html.haml +23 -0
  66. data/app/views/rocket_job_mission_control/jobs/show.html.haml +5 -8
  67. data/app/views/rocket_job_mission_control/workers/_sidebar.html.haml +20 -0
  68. data/app/views/rocket_job_mission_control/workers/index.html.haml +36 -59
  69. data/app/views/rocket_job_mission_control/workers/index_filters/paused.html.haml +37 -0
  70. data/app/views/rocket_job_mission_control/workers/index_filters/running.html.haml +37 -0
  71. data/app/views/rocket_job_mission_control/workers/index_filters/starting.html.haml +37 -0
  72. data/app/views/rocket_job_mission_control/workers/index_filters/stopping.html.haml +37 -0
  73. data/config/routes.rb +28 -5
  74. data/lib/rocket_job_mission_control/engine.rb +2 -0
  75. data/lib/rocket_job_mission_control/version.rb +1 -1
  76. data/spec/controllers/application_controller_spec.rb +1 -1
  77. data/spec/controllers/dirmon_entries_controller_spec.rb +35 -97
  78. data/spec/controllers/jobs/failures_controller_spec.rb +4 -4
  79. data/spec/controllers/jobs_controller_spec.rb +10 -80
  80. data/spec/dummy/config/environments/development.rb +7 -7
  81. data/spec/dummy/config/environments/test.rb +9 -9
  82. data/spec/dummy/log/test.log +5446 -23487
  83. data/spec/helpers/application_helper_spec.rb +58 -0
  84. data/spec/helpers/jobs_helper_spec.rb +0 -65
  85. data/spec/helpers/slices_helper_spec.rb +1 -1
  86. data/spec/helpers/workers_helper_spec.rb +1 -1
  87. metadata +64 -44
  88. data/MIT-LICENSE +0 -20
  89. data/app/assets/javascripts/rocket_job_mission_control/jobs.js.coffee +0 -11
  90. data/app/views/rocket_job_mission_control/dirmon_entries/_list.html.haml +0 -31
  91. data/app/views/rocket_job_mission_control/jobs/_list.html.haml +0 -35
  92. data/app/views/rocket_job_mission_control/jobs/running.html.haml +0 -37
  93. data/spec/dummy/log/development.log +0 -0
  94. data/spec/views/workers/index.html.haml_spec.rb +0 -23
@@ -0,0 +1,35 @@
1
+ module RocketJobMissionControl
2
+ class RunningJobsDatatable < JobsDatatable
3
+ private
4
+
5
+ def data
6
+ jobs.map do |job|
7
+ {
8
+ '0' => class_with_link(job),
9
+ '1' => h(job.description.try(:truncate, 50)),
10
+ '2' => progress(job),
11
+ '3' => h(job.priority),
12
+ '4' => h(started(job)),
13
+ 'DT_RowClass' => "card callout callout-#{job.state}"
14
+ }
15
+ end
16
+ end
17
+
18
+ def sort_column(index)
19
+ columns = %w[_type description percent_complete priority started_at]
20
+ columns[index.to_i]
21
+ end
22
+
23
+ def progress(job)
24
+ <<-EOS
25
+ <div class='progress'>
26
+ <div class='progress-bar' style="width: #{job.percent_complete}%;", title="#{job.percent_complete}% complete."></div>
27
+ </div>
28
+ EOS
29
+ end
30
+
31
+ def started(job)
32
+ "#{RocketJob.seconds_as_duration(Time.now - job.started_at)} ago" if job.started_at
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,30 @@
1
+ module RocketJobMissionControl
2
+ class ScheduledJobsDatatable < JobsDatatable
3
+ private
4
+
5
+ def data
6
+ jobs.map do |job|
7
+ {
8
+ '0' => class_with_link(job),
9
+ '1' => h(job.description.try(:truncate, 50)),
10
+ '2' => h(time_till_run(job)),
11
+ '3' => h(cron_schedule(job)),
12
+ 'DT_RowClass' => "card callout callout-#{job.state}"
13
+ }
14
+ end
15
+ end
16
+
17
+ def sort_column(index)
18
+ columns = %w[_type description run_at cron_schedule]
19
+ columns[index.to_i]
20
+ end
21
+
22
+ def time_till_run(job)
23
+ RocketJob.seconds_as_duration(job.run_at - Time.now)
24
+ end
25
+
26
+ def cron_schedule(job)
27
+ job.cron_schedule if job.respond_to?(:cron_schedule)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,127 @@
1
+ module RocketJobMissionControl
2
+ class WorkersDatatable
3
+ delegate :params,
4
+ :link_to,
5
+ :worker_icon,
6
+ :worker_path,
7
+ :stop_worker_path,
8
+ :resume_worker_path,
9
+ :pause_worker_path,
10
+ :worker_card_class,
11
+ :render, to: :@view
12
+
13
+ delegate :h, to: 'ERB::Util'
14
+
15
+ def initialize(view, workers)
16
+ @view = view
17
+ @unfiltered_workers = workers
18
+ end
19
+
20
+ def as_json(options = {})
21
+ {
22
+ :draw => params[:draw].to_i,
23
+ :recordsTotal => get_raw_records.count,
24
+ :recordsFiltered => filter_records(get_raw_records).count,
25
+ :data => data
26
+ }
27
+ end
28
+
29
+ private
30
+
31
+ def data
32
+ workers.map do |worker|
33
+ {
34
+ '0' => name_with_icon(worker),
35
+ '1' => h(threads(worker)),
36
+ '2' => h(started_ago(worker)),
37
+ '3' => h(time_since_heartbeat(worker)),
38
+ '4' => action_links_html(worker),
39
+ 'DT_RowClass' => "card callout #{worker_card_class(worker)}"
40
+ }
41
+ end
42
+ end
43
+
44
+ def get_raw_records
45
+ @unfiltered_workers
46
+ end
47
+
48
+ def workers
49
+ @workers ||= fetch_workers
50
+ end
51
+
52
+ def fetch_workers
53
+ records = get_raw_records
54
+ records = sort_records(records) if params[:order].present?
55
+ records = filter_records(records) if params[:search].present?
56
+ records = paginate_records(records) unless params[:length].present? && params[:length] == '-1'
57
+ records
58
+ end
59
+
60
+ def page
61
+ (params[:start].to_i / per_page) + 1
62
+ end
63
+
64
+ def per_page
65
+ params.fetch(:length, 10).to_i
66
+ end
67
+
68
+ def sort_records(records)
69
+ sort_by = {}
70
+ params[:order].keys.each do |key|
71
+ sort_by[sort_column(params[:order][key][:column])] = params[:order][key][:dir]
72
+ end
73
+ records.sort(sort_by)
74
+ end
75
+
76
+ def sort_column(index)
77
+ columns = %w[name max_threads started_at heartbeat.updated_at]
78
+ columns[index.to_i]
79
+ end
80
+
81
+ def filter_records(records)
82
+ return records unless (params[:search].present? && params[:search][:value].present?)
83
+ conditions = params[:search][:value]#build_conditions_for(params[:search][:value])
84
+ records = RocketJobMissionControl::Workers::Search.new(conditions, records).execute if conditions
85
+ records
86
+ end
87
+
88
+ def paginate_records(records)
89
+ Kaminari.paginate_array(records.all).page(page).per(per_page)
90
+ end
91
+
92
+ def name_with_icon(worker)
93
+ <<-EOS
94
+ <i class="fa #{worker_icon(worker)}" style="font-size: 75%" title="#{worker.state}"></i>
95
+ #{worker.name}
96
+ EOS
97
+ end
98
+
99
+ def threads(worker)
100
+ "#{worker.heartbeat.current_threads.to_i}/#{worker.max_threads}"
101
+ end
102
+
103
+ def started_ago(worker)
104
+ "#{RocketJob.seconds_as_duration(Time.now - worker.started_at)} ago"
105
+ end
106
+
107
+ def time_since_heartbeat(worker)
108
+ "#{RocketJob.seconds_as_duration(Time.now - worker.heartbeat.updated_at)} ago"
109
+ end
110
+
111
+ def action_links_html(worker)
112
+ actions = '<div class="actions">'
113
+ if worker.stopping?
114
+ actions += "Worker is stopping..."
115
+ actions += "#{ link_to "destroy", worker_path(worker), method: :delete, class: 'btn btn-danger', data: { confirm: "Destroy this worker?"} }"
116
+ else
117
+ if worker.paused?
118
+ actions += "#{ link_to "resume", resume_worker_path(worker), method: :patch, class: 'btn btn-default', data: { confirm: "Resume this worker?"} }"
119
+ else
120
+ actions += "#{ link_to "pause", pause_worker_path(worker), method: :patch, class: 'btn btn-default', data: { confirm: "Pause this worker?"} }"
121
+ end
122
+ actions += "#{ link_to "stop", stop_worker_path(worker), method: :patch, class: 'btn btn-danger', data: { confirm: "Stop this worker?"} }"
123
+ end
124
+ actions += '</div>'
125
+ end
126
+ end
127
+ end
@@ -1,5 +1,25 @@
1
1
  module RocketJobMissionControl
2
2
  module ApplicationHelper
3
+ STATE_ICON_MAP = {
4
+ aborted: 'fa-stop',
5
+ completed: 'fa-check',
6
+ disabled: 'fa-stop',
7
+ enabled: 'fa-check',
8
+ failed: 'fa-exclamation-triangle',
9
+ paused: 'fa-pause',
10
+ pending: 'fa-inbox',
11
+ queued: 'fa-inbox',
12
+ running: 'fa-play',
13
+ scheduled: 'fa-clock-o',
14
+ starting: 'fa-cogs',
15
+ stopping: 'fa-stop',
16
+ zombie: 'fa-hourglass-o'
17
+ }
18
+
19
+ def state_icon(state)
20
+ STATE_ICON_MAP[state.to_sym] + ' ' + state.to_s
21
+ end
22
+
3
23
  def site_title
4
24
  'Rocket Job Mission Control'
5
25
  end
@@ -15,9 +35,8 @@ module RocketJobMissionControl
15
35
 
16
36
  def pretty_print_array_or_hash(arguments)
17
37
  return arguments unless arguments.kind_of?(Array) || arguments.kind_of?(Hash)
18
- json_string_options = { space: ' ', indent: ' ', array_nl: '<br />', object_nl: '<br />' }
38
+ json_string_options = {space: ' ', indent: ' ', array_nl: '<br />', object_nl: '<br />'}
19
39
  JSON.generate(arguments, json_string_options).html_safe
20
40
  end
21
-
22
41
  end
23
42
  end
@@ -0,0 +1,7 @@
1
+ module RocketJobMissionControl
2
+ module DirmonEntriesHelper
3
+ def dirmon_counts_by_state(state)
4
+ RocketJob::DirmonEntry.counts_by_state.fetch(state.downcase.to_sym, 0)
5
+ end
6
+ end
7
+ end
@@ -1,31 +1,18 @@
1
1
  module RocketJobMissionControl
2
2
  module JobsHelper
3
- STATE_ICON_MAP = {
4
- aborted: 'fa-stop',
5
- completed: 'fa-check',
6
- disabled: 'fa-stop',
7
- enabled: 'fa-check',
8
- failed: 'fa-exclamation-triangle',
9
- paused: 'fa-pause',
10
- pending: 'fa-inbox',
11
- queued: 'fa-inbox',
12
- running: 'fa-play',
13
- scheduled: 'fa-clock-o',
14
- }
15
-
16
- def job_state_icon(state)
17
- STATE_ICON_MAP[state.to_sym] + ' ' + state.to_s
18
- end
19
-
20
3
  def job_icon(job)
21
- # TODO move this logic to RocketJob::Job
22
4
  state =
23
- if job.queued? && job.run_at && (job.run_at > Time.now)
5
+ if job.scheduled?
24
6
  :scheduled
25
7
  else
26
8
  job.state
27
9
  end
28
- job_state_icon(state)
10
+ state_icon(state)
11
+ end
12
+
13
+ def job_counts_by_state(state)
14
+ state = 'queued_now' if state == 'queued'
15
+ RocketJob::Job.counts_by_state.fetch(state.downcase.to_sym, 0)
29
16
  end
30
17
 
31
18
  def job_action_link(action, path, http_method=:get)
@@ -33,8 +20,8 @@ module RocketJobMissionControl
33
20
  action,
34
21
  path,
35
22
  method: http_method,
36
- class: 'btn btn-default',
37
- data: { confirm: t(:confirm, scope: [:job, :action], action: action)}
23
+ class: 'btn btn-default',
24
+ data: {confirm: t(:confirm, scope: [:job, :action], action: action)}
38
25
  )
39
26
  end
40
27
 
@@ -50,9 +37,5 @@ module RocketJobMissionControl
50
37
  end
51
38
  end
52
39
 
53
- def job_title(job)
54
- perform_method = job.perform_method == :perform ? '' : "##{job.perform_method}"
55
- "#{job.class.name}#{perform_method}"
56
- end
57
40
  end
58
41
  end
@@ -1,18 +1,30 @@
1
1
  module RocketJobMissionControl
2
2
  module WorkersHelper
3
+ def worker_counts_by_state(state)
4
+ RocketJob::Worker.counts_by_state.fetch(state.downcase.to_sym, 0)
5
+ end
6
+
7
+ def worker_icon(worker)
8
+ state =
9
+ if worker.zombie?
10
+ 'zombie'
11
+ else
12
+ worker.state
13
+ end
14
+ state_icon(state)
15
+ end
3
16
 
4
17
  def worker_card_class(worker)
5
18
  if worker.zombie?
6
- 'callout-zombie-top'
19
+ 'callout-zombie'
7
20
  else
8
21
  map = {
9
- running: 'callout-success-top',
10
- paused: 'callout-warning-top',
11
- stopping: 'callout-alert-top',
22
+ running: 'callout-success',
23
+ paused: 'callout-warning',
24
+ stopping: 'callout-alert',
12
25
  }
13
- map[worker.state] || 'callout-info-top'
26
+ map[worker.state] || 'callout-info'
14
27
  end
15
28
  end
16
-
17
29
  end
18
30
  end
@@ -0,0 +1,19 @@
1
+ module RocketJobMissionControl
2
+ module DirmonEntries
3
+ class Search
4
+ attr_reader :results, :search_term
5
+
6
+ def initialize(search_term, search_subset)
7
+ @search_term = search_term
8
+ @results = search_subset
9
+ end
10
+
11
+ def execute
12
+ if !search_term.blank?
13
+ @results = @results.where('$or' => [{job_class_name: /#{search_term}/i}, {name: /#{search_term}/i}, {pattern: /#{search_term}/i}])
14
+ end
15
+ @results
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module RocketJobMissionControl
2
+ module Jobs
3
+ class Search
4
+ attr_reader :results, :search_term
5
+
6
+ def initialize(search_term, search_subset)
7
+ @search_term = search_term
8
+ @results = search_subset
9
+ end
10
+
11
+ def execute
12
+ if !search_term.blank?
13
+ @results = @results.where('$or' => [{_type: /#{search_term}/i}, {description: /#{search_term}/i}])
14
+ end
15
+ @results
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module RocketJobMissionControl
2
+ module Workers
3
+ class Search
4
+ attr_reader :results, :search_term
5
+
6
+ def initialize(search_term, search_subset)
7
+ @search_term = search_term
8
+ @results = search_subset
9
+ end
10
+
11
+ def execute
12
+ if !search_term.blank?
13
+ @results = @results.where('$or' => [{name: /#{search_term}/i}])
14
+ end
15
+ @results
16
+ end
17
+ end
18
+ end
19
+ end
@@ -13,13 +13,13 @@ class JobFailures
13
13
  @slice_errors ||= job.input.collection.aggregate(
14
14
  [
15
15
  {
16
- '$match' => { state: 'failed' }
16
+ '$match' => {state: 'failed'}
17
17
  },
18
18
  {
19
19
  '$group' => {
20
- _id: { error_class: '$exception.class_name' },
21
- messages: { '$addToSet' => '$exception.message' },
22
- count: { '$sum' => 1 }
20
+ _id: {error_class: '$exception.class_name'},
21
+ messages: {'$addToSet' => '$exception.message'},
22
+ count: {'$sum' => 1}
23
23
  },
24
24
  }
25
25
  ]
@@ -27,7 +27,7 @@ class JobFailures
27
27
  end
28
28
 
29
29
  def for_error(error_type, page_offset=0)
30
- query = { 'state' => 'failed', 'exception.class_name' => error_type }
30
+ query = {'state' => 'failed', 'exception.class_name' => error_type}
31
31
  @job.input.collection.find(query).limit(1).skip(page_offset)
32
32
  end
33
33
  end
@@ -21,25 +21,25 @@
21
21
  %link{href: "//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css", rel: "stylesheet"}/
22
22
 
23
23
  %body.rocket_job
24
- #wrapper.toggled
25
- = render partial: 'layouts/rocket_job_mission_control/partials/sidebar'
26
-
27
- #page-content-wrapper
28
- = render partial: 'layouts/rocket_job_mission_control/partials/header'
29
-
30
- .flash.text-center
31
- - flash.each do |key, msg|
32
- - if msg
33
- .alert{class: "alert-#{key} alert-dismissable", role: 'alert'}
34
- %button.close{ data: { dismiss: 'alert' } }
35
- %span &times;
36
- -if msg.kind_of? Array
37
- %ul.list-unstyled.margin-bottom-0
38
- - msg.each do |m|
39
- %li= m.html_safe
40
- - else
41
- = msg.html_safe
42
-
43
- = yield
44
-
45
- %footer.footer
24
+ #wrapper
25
+ .container-fluid
26
+ .row.row-offcanvas.row-offcanvas-left
27
+ = render partial: 'layouts/rocket_job_mission_control/partials/sidebar'
28
+
29
+ .col-sm-10.col-xs-11.white-background#main
30
+ = render partial: 'layouts/rocket_job_mission_control/partials/header'
31
+
32
+ .flash.text-center
33
+ - flash.each do |key, msg|
34
+ - if msg
35
+ .alert{class: "alert-#{key} alert-dismissable", role: 'alert'}
36
+ %button.close{ data: { dismiss: 'alert' } }
37
+ %span &times;
38
+ -if msg.kind_of? Array
39
+ %ul.list-unstyled.margin-bottom-0
40
+ - msg.each do |m|
41
+ %li= m.html_safe
42
+ - else
43
+ = msg.html_safe
44
+ #content
45
+ = yield
@@ -1,18 +1,33 @@
1
- #header
2
- %a#menu-toggle.btn.btn-default.btn-blank.first{href: ""}
3
- %i.fa.fa-bars
4
- Menu
5
-
6
-
7
- = link_to '..', class: 'btn btn-default btn-blank last' do
8
- %i.fa.fa-reply
9
- Back Home
10
-
11
-
12
- .clearfix
13
-
14
- .brand
15
- = link_to root_path, class: 'text-center' do
16
- = image_tag('rocket_job_mission_control/rocket-icon-64x64.png', size: '32x32')
17
- rocket
18
- %span job
1
+ %nav.navbar.navbar-default#header
2
+ .container-fluid
3
+ .navbar-header
4
+ %button.navbar-toggle.collapsed{ "aria-expanded" => "false", "data-target" => ".navbar-collapse", "data-toggle" => "collapse", :type => "button" }
5
+ %span.sr-only Toggle navigation
6
+ %span.icon-bar
7
+ %span.icon-bar
8
+ %span.icon-bar
9
+ %a.navbar-brand.brand{ href: 'http://rocketjob.io', target: '_blank'}
10
+ = image_tag('rocket_job_mission_control/rocket-icon-64x64.png', size: '32x32')
11
+ Rocket
12
+ %span Job
13
+ .navbar-collapse.collapse
14
+ %ul.nav.navbar-nav
15
+ %li
16
+ = link_to running_jobs_path, class: active_page(running_jobs_path) do
17
+ %i.fa.fa-home
18
+ Jobs
19
+ %li
20
+ = link_to workers_path, class: active_page(workers_path) do
21
+ %i.fa.fa-database
22
+ Workers
23
+ %li
24
+ = link_to active_processes_path, class: active_page(active_processes_path) do
25
+ %i.fa.fa-circle-o-notch
26
+ Activity
27
+ %li
28
+ = link_to enabled_dirmon_entries_path, class: active_page(enabled_dirmon_entries_path) do
29
+ %i.fa.fa-folder-o
30
+ Directory Monitors
31
+ %ul.nav.navbar-nav.navbar-right
32
+ %li
33
+ %a{:href => main_app.root_path } Home
@@ -1,24 +1,11 @@
1
- #sidebar-wrapper
2
- %ul.sidebar-nav
3
- %li.sidebar-brand
4
- %a#menu-close.menu-close
5
- %i.fa.fa-times
6
-
7
- .clearfix
8
-
9
- %li
10
- = link_to jobs_path, class: active_page(jobs_path) do
11
- %i.fa.fa-home
12
- Jobs
13
- %li
14
- = link_to workers_path, class: active_page(workers_path) do
15
- %i.fa.fa-database
16
- Workers
17
- %li
18
- = link_to running_jobs_path, class: active_page(running_jobs_path) do
19
- %i.fa.fa-circle-o-notch
20
- Running
21
- %li
22
- = link_to dirmon_entries_path, class: active_page(dirmon_entries_path) do
23
- %i.fa.fa-folder-o
24
- Dirmon
1
+ #sidebar.col-sm-2.col-xs-1.sidebar-offcanvas
2
+ %ul.nav
3
+ %li
4
+ %a.visible-xs{"data-toggle" => "offcanvas", :href => "#"}
5
+ %i.fa.fa-chevron-right
6
+ - if @jobs_sidebar
7
+ = render partial: 'rocket_job_mission_control/jobs/sidebar'
8
+ - if @dirmon_sidebar
9
+ = render partial: 'rocket_job_mission_control/dirmon_entries/sidebar'
10
+ - if @workers_sidebar
11
+ = render partial: 'rocket_job_mission_control/workers/sidebar'
@@ -0,0 +1,24 @@
1
+ .job-list
2
+ .list
3
+ .row
4
+ .col-sm-10
5
+ %h2 Active Processes
6
+ .col-sm-2
7
+ .btn.btn-default.pull-right.dt-reload{ data: { behavior: 'reload' } }
8
+ %i.fa.fa-refresh
9
+ %table.table.datatable.active-processes-datatable{ style: "width: 100%", data: { source: "#{active_processes_url(format: 'json')}", column_num: 4 } }
10
+ %thead
11
+ %tr
12
+ %th Hostname : PID
13
+ %th Class
14
+ %th Description
15
+ %th Started
16
+ %tbody
17
+
18
+ :javascript
19
+ jQuery(function() {
20
+ new RjmcDatatable(
21
+ $('.active-processes-datatable'),
22
+ [{data: '0'}, {data: '1'}, {data: '2'}, {data: '3'}],
23
+ {ordering: false, searching: false});
24
+ });
@@ -5,19 +5,20 @@
5
5
  - @dirmon_entry.errors.messages.each_pair do |field, message|
6
6
  .message
7
7
  = "#{field}: #{message}"
8
+
8
9
  = form_for @dirmon_entry, url: {action: action} do |f|
9
- .name.form-group
10
- = f.label :name
11
- = f.text_field :name, class: 'form-control'
10
+ .row
11
+ .col-md-6
12
+ .name.form-group
13
+ = f.label :name
14
+ = f.text_field :name, class: 'form-control'
15
+ .col-md-6
16
+ .job.form-group
17
+ = f.label :job_class_name
18
+ = f.text_field :job_class_name, class: 'form-control', disabled: action != :create
12
19
  .path.form-group
13
20
  = f.label :pattern
14
21
  = f.text_field :pattern, class: 'form-control'
15
- .job.form-group
16
- = f.label :job_class_name
17
- = f.text_field :job_class_name, class: 'form-control', disabled: action != :create
18
- .job.form-group
19
- = f.label :perform_method
20
- = f.text_field :perform_method, class: 'form-control', disabled: action != :create
21
22
  .path.form-group
22
23
  = f.label :archive_directory
23
24
  = f.text_field :archive_directory, class: 'form-control'
@@ -25,7 +26,7 @@
25
26
  .col-md-12
26
27
  = render partial: 'properties', locals: { f: f }
27
28
 
28
- .buttons
29
+ .buttons.pull-right
29
30
  = f.submit action, class: 'btn btn-primary'
30
31
  = link_to 'cancel', :back, class: 'btn btn-default'
31
32
  - if action == :create
@@ -1,7 +1,7 @@
1
1
  - if @dirmon_entry.job_class
2
2
  .arguments
3
3
  .job_arguments.form-group
4
- - count = @dirmon_entry.job_class.argument_count(@dirmon_entry.perform_method)
4
+ - count = @dirmon_entry.job_class.rocket_job_argument_count
5
5
  - count.times do |counter|
6
6
  - argument = @dirmon_entry.arguments[counter]
7
7
  = f.label "Argument #{counter + 1}:"
@@ -13,15 +13,18 @@
13
13
  class: 'form-control'
14
14
  = f.fields_for :properties do |properties|
15
15
  - @dirmon_entry.job_class.rocket_job_properties.each do |property_name|
16
- - next if [:arguments, :perform_method].include?(property_name)
16
+ - next if property_name == :arguments
17
17
  - key = @dirmon_entry.job_class.keys[property_name.to_s]
18
- - next unless key
18
+ - next unless key && key.type
19
19
  - placeholder = key.default? ? key.default : nil
20
20
  .form-group
21
21
  = properties.label property_name.to_s
22
22
  - case key.type.name
23
23
  - when 'Integer'
24
24
  = properties.number_field property_name, value: @dirmon_entry.properties[property_name], class: 'form-control', placeholder: placeholder
25
+ - when 'Hash'
26
+ - value = @dirmon_entry.properties[property_name]
27
+ = properties.text_field property_name, value: value ? value.to_json : '', class: 'form-control', placeholder: '{"argument1":"value1", "argument2":"value2", "argument3":"value3"}'
25
28
  - when 'Array'
26
29
  - options = Array(@dirmon_entry.properties[property_name])
27
30
  = properties.select property_name, options_for_select(options, options), {include_hidden: false}, {class: 'selectize', multiple: true}