rocketjob_mission_control 5.0.1 → 6.0.0.beta

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/assets/config/manifest.js +3 -0
  4. data/app/assets/javascripts/rocket_job_mission_control/application.js +1 -1
  5. data/app/assets/javascripts/rocket_job_mission_control/nested_fields.js +112 -0
  6. data/app/assets/stylesheets/rocket_job_mission_control/{application.scss → application.css} +9 -8
  7. data/app/assets/stylesheets/rocket_job_mission_control/base.css +420 -0
  8. data/app/assets/stylesheets/rocket_job_mission_control/{callout.scss → callout.css} +50 -52
  9. data/app/assets/stylesheets/rocket_job_mission_control/jobs.css +57 -0
  10. data/app/assets/stylesheets/rocket_job_mission_control/worker_processes.css +7 -0
  11. data/app/controllers/rocket_job_mission_control/dirmon_entries_controller.rb +20 -20
  12. data/app/controllers/rocket_job_mission_control/jobs_controller.rb +44 -4
  13. data/app/datatables/rocket_job_mission_control/jobs_datatable.rb +1 -1
  14. data/app/helpers/rocket_job_mission_control/application_helper.rb +43 -26
  15. data/app/helpers/rocket_job_mission_control/dirmon_entries_helper.rb +8 -0
  16. data/app/helpers/rocket_job_mission_control/jobs_helper.rb +76 -8
  17. data/app/models/rocket_job_mission_control/dirmon_sanitizer.rb +68 -0
  18. data/app/models/rocket_job_mission_control/job_sanitizer.rb +35 -0
  19. data/app/views/rocket_job_mission_control/dirmon_entries/_form.html.erb +78 -42
  20. data/app/views/rocket_job_mission_control/dirmon_entries/_input_categories.html.erb +59 -0
  21. data/app/views/rocket_job_mission_control/dirmon_entries/_input_category_fields.html.erb +56 -0
  22. data/app/views/rocket_job_mission_control/dirmon_entries/_output_categories.html.erb +44 -0
  23. data/app/views/rocket_job_mission_control/dirmon_entries/_output_category_fields.html.erb +36 -0
  24. data/app/views/rocket_job_mission_control/dirmon_entries/_status.html.erb +22 -16
  25. data/app/views/rocket_job_mission_control/dirmon_entries/copy.html.erb +1 -1
  26. data/app/views/rocket_job_mission_control/dirmon_entries/edit.html.erb +7 -3
  27. data/app/views/rocket_job_mission_control/dirmon_entries/show.html.erb +2 -3
  28. data/app/views/rocket_job_mission_control/jobs/_attributes.html.erb +89 -0
  29. data/app/views/rocket_job_mission_control/jobs/_dates.html.erb +39 -0
  30. data/app/views/rocket_job_mission_control/jobs/_details.html.erb +86 -0
  31. data/app/views/rocket_job_mission_control/jobs/_exception.html.erb +33 -0
  32. data/app/views/rocket_job_mission_control/jobs/_input_categories.html.erb +126 -0
  33. data/app/views/rocket_job_mission_control/jobs/_input_category_fields.html.erb +56 -0
  34. data/app/views/rocket_job_mission_control/jobs/_output_categories.html.erb +60 -0
  35. data/app/views/rocket_job_mission_control/jobs/_output_category_fields.html.erb +36 -0
  36. data/app/views/rocket_job_mission_control/jobs/_retryable.html.erb +27 -0
  37. data/app/views/rocket_job_mission_control/jobs/_status.html.erb +21 -49
  38. data/app/views/rocket_job_mission_control/jobs/edit.html.erb +28 -0
  39. data/app/views/rocket_job_mission_control/jobs/exception.html.erb +1 -1
  40. data/app/views/rocket_job_mission_control/jobs/index.html.erb +24 -18
  41. data/app/views/rocket_job_mission_control/jobs/show.html.erb +32 -58
  42. data/app/views/rocket_job_mission_control/jobs/view_slice.html.erb +4 -4
  43. data/config/initializers/assets.rb +3 -4
  44. data/lib/rocket_job_mission_control/engine.rb +0 -1
  45. data/lib/rocket_job_mission_control/version.rb +1 -1
  46. data/test/controllers/rocket_job_mission_control/jobs_controller_test.rb +2 -1
  47. data/test/models/rocket_job_mission_control/dirmon_sanitizer_test.rb +146 -0
  48. data/test/test_helper.rb +5 -11
  49. data/vendor/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  50. data/vendor/assets/fonts/glyphicons-halflings-regular.svg +288 -0
  51. data/vendor/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  52. data/vendor/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  53. data/vendor/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
  54. data/vendor/assets/stylesheets/bootstrap.min.css.erb +6 -0
  55. metadata +37 -29
  56. data/app/assets/stylesheets/rocket_job_mission_control/base.scss +0 -436
  57. data/app/assets/stylesheets/rocket_job_mission_control/bootstrap_and_overrides.scss +0 -488
  58. data/app/assets/stylesheets/rocket_job_mission_control/jobs.scss +0 -72
  59. data/app/assets/stylesheets/rocket_job_mission_control/worker_processes.scss +0 -9
  60. data/vendor/assets/stylesheets/bootstrap.min.css +0 -6
@@ -0,0 +1,126 @@
1
+ <div class='lead'>Input Categories:</div>
2
+ <% @job.input_categories.each do |category| %>
3
+ <div class='row'>
4
+ <div class='col-md-12'>
5
+ <div class='status-message'><label><%= category.name.to_s.camelcase %>:</label></div>
6
+ <div class='row'>
7
+ <div class='col-md-12'>
8
+ <table>
9
+ <% if category.name == :main %>
10
+ <tr>
11
+ <td><label>Record Count:</label></td>
12
+ <td><%= @job.record_count %></td>
13
+ </tr>
14
+ <% if @job.completed? %>
15
+ <tr>
16
+ <td><label>Records Per Hour:</label></td>
17
+ <td><%= job_records_per_hour(@job) %></td>
18
+ </tr>
19
+ <% elsif @job.running? || @job.paused? || @job.failed? %>
20
+ <tr>
21
+ <td><label>Progress:</label></td>
22
+ <td><%= @job.percent_complete %> %</td>
23
+ </tr>
24
+ <% if @job.running? %>
25
+ <tr>
26
+ <td><label>Est. Time Remaining:</label></td>
27
+ <td><%= job_estimated_time_left(@job) %></td>
28
+ </tr>
29
+ <% end %>
30
+ <tr>
31
+ <td><label>Queued Slices:</label></td>
32
+ <td><%= @job.input.queued.count %></td>
33
+ </tr>
34
+ <tr>
35
+ <td><label>Active Slices:</label></td>
36
+ <td><%= @job.input.running.count %></td>
37
+ </tr>
38
+ <tr>
39
+ <td><label>Failed Slices:</label></td>
40
+ <td><%= @job.input.failed.count %></td>
41
+ </tr>
42
+ <% end %>
43
+ <tr>
44
+ <td><label>Slice Size:</label></td>
45
+ <td><%= category.slice_size %></td>
46
+ </tr>
47
+ <% end %>
48
+ <% if category.serializer %>
49
+ <tr>
50
+ <td><label>Serializer:</label></td>
51
+ <td><%= category.serializer %></td>
52
+ </tr>
53
+ <% end %>
54
+ <% if category.file_name %>
55
+ <tr>
56
+ <td><label>File Name:</label></td>
57
+ <td><%= category.file_name %></td>
58
+ </tr>
59
+ <% end %>
60
+ </tr>
61
+ <% if category.format %>
62
+ <tr>
63
+ <td><label>Format:</label></td>
64
+ <td><%= category.format %></td>
65
+ </tr>
66
+ <tr>
67
+ <td><label>Header Cleanser:</label></td>
68
+ <td><%= category.header_cleanser %></td>
69
+ </tr>
70
+ <% if category.allowed_columns %>
71
+ <tr>
72
+ <td><label>Allowed Columns:</label></td>
73
+ <td><%= category.allowed_columns.ai(plain: true) %></td>
74
+ </tr>
75
+ <% end %>
76
+ <% if category.required_columns %>
77
+ <tr>
78
+ <td><label>Required Columns:</label></td>
79
+ <td><%= category.required_columns.ai(plain: true) %></td>
80
+ </tr>
81
+ <% end %>
82
+ <% if category.skip_unknown %>
83
+ <tr>
84
+ <td><label>Skip Unknown Columns:</label></td>
85
+ <td><%= category.skip_unknown %></td>
86
+ </tr>
87
+ <% end %>
88
+ <% if category.mode != :line %>
89
+ <tr>
90
+ <td><label>Mode:</label></td>
91
+ <td><%= category.mode %></td>
92
+ </tr>
93
+ <% end %>
94
+ <% if category.format_options %>
95
+ <tr>
96
+ <td><label>Format Options:</label></td>
97
+ <td>
98
+ <pre><code><%= category.format_options.ai(plain: true, ruby19_syntax: true, sort_keys: true) %></code></pre>
99
+ </td>
100
+ </tr>
101
+ <% end %>
102
+ <% end %>
103
+ <% if category.columns %>
104
+ <% first = true %>
105
+ <% category.columns.each do |item| %>
106
+ <% if first %>
107
+ <tr>
108
+ <td><label>Columns:</label></td>
109
+ <td><%= item %></td>
110
+ </tr>
111
+ <% first = false %>
112
+ <% else %>
113
+ <tr>
114
+ <td></td>
115
+ <td><%= item %></td>
116
+ </tr>
117
+ <% end %>
118
+ <% end %>
119
+ <% end %>
120
+ </table>
121
+ </div>
122
+ </div>
123
+ </div>
124
+ </div>
125
+ <br/>
126
+ <% end %>
@@ -0,0 +1,56 @@
1
+ <% input_category = f.object %>
2
+
3
+ <div class="nested-fields">
4
+ <div class="panel panel-primary">
5
+ <div class="panel-heading">
6
+ <div class="row">
7
+ <div class="col-sm-12">
8
+ <h4><%= input_category.name %></h4>
9
+ </div>
10
+ </div>
11
+ </div>
12
+
13
+ <div class="panel-body">
14
+ <%= f.hidden_field :name, value: input_category.name %>
15
+
16
+ <div class="form-group">
17
+ <%= f.label :columns %>
18
+ <% options = input_category.columns || [] %>
19
+ <%= f.select(:columns, options_for_select(options, options), { include_hidden: false }, { class: "selectize form-control", multiple: true }) %>
20
+ </div>
21
+
22
+ <div class="form-group">
23
+ <%= f.label :format %>
24
+ <% options = extract_inclusion_values(RocketJob::Category::Input, :format) %>
25
+ <% value = input_category.format %>
26
+ <%= f.select(:format, options, { include_blank: true, selected: value }, { class: "selectize form-control" }) %>
27
+ </div>
28
+
29
+ <div class="form-group">
30
+ <%= f.label :format_options %>
31
+ <% value = input_category.format_options %>
32
+ <%= f.text_field(:format_options, value: value ? value.to_json : nil, class: "form-control", placeholder: '{"key1":"value1", "key2":"value2", "key3":"value3"}') %>
33
+ </div>
34
+
35
+ <div class="form-group">
36
+ <%= f.label :mode %>
37
+ <% options = extract_inclusion_values(RocketJob::Category::Input, :mode) %>
38
+ <% value = input_category.mode %>
39
+ <%= f.select(:mode, options, { include_blank: true, selected: value }, { class: "selectize form-control" }) %>
40
+ </div>
41
+
42
+ <div class="form-group">
43
+ <%= f.label "Skip and Ignore Unknown Columns" %>
44
+ <% options = extract_inclusion_values(RocketJob::Category::Input, :skip_unknown) %>
45
+ <% value = input_category.skip_unknown %>
46
+ <%= f.select(:skip_unknown, options, { include_blank: true, selected: value }, { class: "selectize form-control" }) %>
47
+ </div>
48
+
49
+ <div class="form-group">
50
+ <%= f.label :slice_size %>
51
+ <% value = input_category.slice_size %>
52
+ <%= f.number_field(:slice_size, value: value, class: "form-control") %>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </div>
@@ -0,0 +1,60 @@
1
+ <div class='lead'>Output Categories:</div>
2
+ <% @job.output_categories.each do |category| %>
3
+ <div class='row'>
4
+ <div class='col-md-12'>
5
+ <div class='status-message'><label><%= category.name.to_s.camelcase %>:</label></div>
6
+ <div class='row'>
7
+ <div class='col-md-12'>
8
+ <table>
9
+ <% if category.serializer %>
10
+ <tr>
11
+ <td><label>Serializer:</label></td>
12
+ <td><%= category.serializer %></td>
13
+ </tr>
14
+ <% end %>
15
+ <tr>
16
+ <td><label>Collect nil output:</label></td>
17
+ <td><%= category.nils %></td>
18
+ </tr>
19
+ <% if category.file_name %>
20
+ <tr>
21
+ <td><label>File Name:</label></td>
22
+ <td><%= category.file_name %></td>
23
+ </tr>
24
+ <% end %>
25
+ <% if category.format %>
26
+ <tr>
27
+ <td><label>Format:</label></td>
28
+ <td><%= category.format %></td>
29
+ </tr>
30
+ <% if category.format_options %>
31
+ <tr>
32
+ <td><label>Format Options:</label></td>
33
+ <td><pre><code><%= category.format_options.ai(plain: true, ruby19_syntax: true, sort_keys: true) %></code></pre></td>
34
+ </tr>
35
+ <% end %>
36
+ <% end %>
37
+ <% if category.columns %>
38
+ <% first = true %>
39
+ <% category.columns.each do |item| %>
40
+ <% if first %>
41
+ <tr>
42
+ <td><label>Columns:</label></td>
43
+ <td><%= item %></td>
44
+ </tr>
45
+ <% first = false %>
46
+ <% else %>
47
+ <tr>
48
+ <td></td>
49
+ <td><%= item %></td>
50
+ </tr>
51
+ <% end %>
52
+ <% end %>
53
+ <% end %>
54
+ </table>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </div>
59
+ <br/>
60
+ <% end %>
@@ -0,0 +1,36 @@
1
+ <% output_category = f.object %>
2
+
3
+ <div class="nested-fields">
4
+ <div class="panel panel-success">
5
+ <div class="panel-heading">
6
+ <div class="row">
7
+ <div class="col-sm-12">
8
+ <h4 class="pull-left"><%= output_category.name %></h4>
9
+ </div>
10
+ </div>
11
+ </div>
12
+
13
+ <div class="panel-body">
14
+ <%= f.hidden_field :name, value: output_category.name %>
15
+
16
+ <div class="form-group">
17
+ <%= f.label :columns %>
18
+ <% options = output_category.columns || [] %>
19
+ <%= f.select(:columns, options_for_select(options, options), { include_hidden: false }, { class: "selectize form-control", multiple: true }) %>
20
+ </div>
21
+
22
+ <div class="form-group">
23
+ <%= f.label :format %>
24
+ <% options = extract_inclusion_values(RocketJob::Category::Output, :format) %>
25
+ <% value = output_category.format %>
26
+ <%= f.select(:format, options, { include_blank: true, selected: value }, { class: "selectize form-control" }) %>
27
+ </div>
28
+
29
+ <div class="form-group">
30
+ <%= f.label :format_options %>
31
+ <% value = output_category.format_options %>
32
+ <%= f.text_field(:format_options, value: value ? value.to_json : nil, class: "form-control", placeholder: '{"key1":"value1", "key2":"value2", "key3":"value3"}') %>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
@@ -0,0 +1,27 @@
1
+ <div class='lead'>Retryable:</div>
2
+ <div class='row'>
3
+ <div class='col-md-12'>
4
+ <table>
5
+ <% first = true %>
6
+ <% @job.failed_at_list.each do |time| %>
7
+ <% if first %>
8
+ <tr>
9
+ <td><label>Retry Limit</label></td>
10
+ <td><%= @job.retry_limit %></td>
11
+ <td><label>Failures</label></td>
12
+ <td><%= job_time(time) %></td>
13
+ </tr>
14
+ <% first = false %>
15
+ <% else %>
16
+ <tr>
17
+ <td></td>
18
+ <td></td>
19
+ <td></td>
20
+ <td><%= job_time(time) %></td>
21
+ </tr>
22
+ <% end %>
23
+ <% end %>
24
+ </table>
25
+ </div>
26
+ </div>
27
+ <br/>
@@ -1,58 +1,30 @@
1
- <% status = job.status(Time.zone) %>
2
-
3
- <div class='id'>
4
- <label>ID:</label> <%= status.delete('_id') %>
5
- </div>
6
-
7
- <% if description = status.delete('description') %>
8
- <div class='status-message'><label>Description:</label> <%= description %></div>
1
+ <%= render partial: 'details', locals: {job: @job} %>
2
+ <%= render partial: 'dates', locals: {job: @job} %>
3
+ <% if @job.respond_to?(:failed_at_list) && @job.failed_at_list.present? %>
4
+ <%= render partial: 'retryable', locals: {job: @job} %>
9
5
  <% end %>
10
-
11
- <% if duration = status.delete('duration') %>
12
- <div class='status-message'><label>Duration:</label> <%= duration %></div>
13
- <% end %>
14
-
15
- <% if record_count = status.delete('record_count') %>
16
- <div class='status-message'><label>Record Count:</label> <%= record_count %></div>
17
- <% end %>
18
-
19
- <div class='created_at'>
20
- <label>Created At:</label> <%= status.delete('created_at') %>
21
- </div>
22
-
23
- <% if started_at = status.delete('started_at') %>
24
- <div class='status-message'><label>Started At:</label> <%= started_at %></div>
25
- <% end %>
26
-
27
- <% if percent_complete = status.delete('percent_complete') %>
28
- <div class='status-message'><label>% Complete:</label> <%= percent_complete %></div>
29
- <% end %>
30
-
31
- <%
32
- remaining = {}
33
- status.each_pair do |key, value|
34
- next if ((value != false) && value.blank?) || ['state', '_type', 'sub_state'].include?(key)
35
- if value.kind_of?(Hash) || value.kind_of?(Array)
36
- remaining[key] = value
37
- next
38
- end
39
- %>
40
- <div class='status-message'><label><%= key.to_s.titleize %>:</label> <%= value %></div>
41
- <% end %>
42
-
43
- <div class='clearfix'></div>
44
-
45
- <% if job.respond_to?('input') && job.input.failed.count.positive? %>
46
- <% status.delete('exception') %>
6
+ <% if @job.respond_to?(:input) && @job.input.failed.count.positive? %>
47
7
  <div class='status-message'>
48
8
  <label><%= 'Exceptions' %>:</label>
49
9
  <%= render partial: 'exceptions', locals: {job: @job} %>
50
10
  </div>
11
+ <% elsif @job.exception.present? %>
12
+ <%= render partial: 'exception', locals: {job: @job} %>
51
13
  <% end %>
52
-
53
- <% remaining.each_pair do |key, value| %>
14
+ <% if @job.respond_to?(:statistics) && @job.statistics.present? %>
54
15
  <div class='status-message'>
55
- <label><%= key.to_s.titleize %>:</label>
56
- <pre><code><%= pretty_print_array_or_hash(value) %></code></pre>
16
+ <label>Statistics:</label>
17
+ <pre><code><%= @job.statistics.ai(plain: true, ruby19_syntax: true, sort_keys: true) %></code></pre>
57
18
  </div>
19
+ <br/>
20
+ <% end %>
21
+ <% if @job.respond_to?(:input_categories) %>
22
+ <%= render partial: 'input_categories', locals: {job: @job} %>
23
+ <% end %>
24
+ <% if @job.respond_to?(:output_categories) %>
25
+ <%= render partial: 'output_categories', locals: {job: @job} %>
26
+ <% end %>
27
+ <% @attributes = job_custom_fields(@job) %>
28
+ <% if @attributes.present? %>
29
+ <%= render partial: 'attributes', locals: {attributes: @attributes} %>
58
30
  <% end %>
@@ -24,6 +24,34 @@
24
24
  <% end %>
25
25
  </div>
26
26
  </div>
27
+
28
+ <% if @job.class.respond_to?(:defined_input_categories) && @job.class.respond_to?(:defined_output_categories) %>
29
+ <div class="row">
30
+ <div class="col-sm-6">
31
+ <div class="panel panel-primary">
32
+ <div class="panel-body">
33
+ <div class='lead'>Input Categories</div>
34
+
35
+ <%= f.fields_for :input_categories do |i| %>
36
+ <%= render "input_category_fields.html", f: i %>
37
+ <% end %>
38
+ </div>
39
+ </div>
40
+ </div>
41
+
42
+ <div class="col-sm-6">
43
+ <div class="panel panel-success">
44
+ <div class="panel-body">
45
+ <div class='lead'>Output Categories</div>
46
+
47
+ <%= f.fields_for :output_categories do |o| %>
48
+ <%= render "output_category_fields.html", f: o %>
49
+ <% end %>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ <% end %>
27
55
  </div>
28
56
  </div>
29
57
 
@@ -11,7 +11,7 @@
11
11
  <div class='clearfix'></div>
12
12
 
13
13
  <div class='message'>
14
- <pre><code><%= @failure_exception.message %></code></pre>
14
+ <pre><code class="language-html"><%= @failure_exception.message %></code></pre>
15
15
  </div>
16
16
 
17
17
  <div class='error'>
@@ -1,28 +1,34 @@
1
1
  <div class='job-list'>
2
2
  <div class='list'>
3
- <div class='row'>
4
- <div class='col-sm-10'>
5
- <h2><%= @description %> Jobs</h2>
6
- </div>
3
+ <div class="panel panel-default">
4
+ <div class="panel-heading">
5
+ <div class='row'>
6
+ <div class='col-sm-10'>
7
+ <h2><%= @description %> Jobs</h2>
8
+ </div>
7
9
 
8
- <div class='col-sm-2'>
9
- <div class='btn btn-default pull-right dt-reload' data-behavior='reload'>
10
- <i class='fas fa-sync'></i>
10
+ <div class='col-sm-2'>
11
+ <div class='btn btn-default pull-right dt-reload' data-behavior='reload'>
12
+ <i class='fas fa-sync'></i>
13
+ </div>
14
+ </div>
11
15
  </div>
12
16
  </div>
13
- </div>
14
17
 
15
- <table class='table datatable jobs-datatable' data-source='<%= @data_table_url %>' style='width: 100%'>
16
- <thead>
17
- <tr>
18
- <% @columns.each do |column| %>
19
- <th><%= column[:display] %></th>
20
- <% end %>
21
- </tr>
22
- </thead>
18
+ <div class="panel-body">
19
+ <table class='table datatable jobs-datatable' data-source='<%= @data_table_url %>' style='width: 100%'>
20
+ <thead>
21
+ <tr>
22
+ <% @columns.each do |column| %>
23
+ <th><%= column[:display] %></th>
24
+ <% end %>
25
+ </tr>
26
+ </thead>
23
27
 
24
- <tbody></tbody>
25
- </table>
28
+ <tbody></tbody>
29
+ </table>
30
+ </div>
31
+ </div>
26
32
  </div>
27
33
  </div>
28
34