rocketjob_mission_control 5.0.0.beta1 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/Rakefile +1 -2
  4. data/app/assets/config/manifest.js +3 -0
  5. data/app/assets/javascripts/rocket_job_mission_control/application.js +3 -5
  6. data/app/assets/javascripts/rocket_job_mission_control/nested_fields.js +112 -0
  7. data/app/assets/stylesheets/rocket_job_mission_control/{application.scss → application.css} +9 -9
  8. data/app/assets/stylesheets/rocket_job_mission_control/base.css +420 -0
  9. data/app/assets/stylesheets/rocket_job_mission_control/{callout.scss → callout.css} +50 -52
  10. data/app/assets/stylesheets/rocket_job_mission_control/jobs.css +56 -0
  11. data/app/assets/stylesheets/rocket_job_mission_control/worker_processes.css +7 -0
  12. data/app/controllers/rocket_job_mission_control/application_controller.rb +3 -1
  13. data/app/controllers/rocket_job_mission_control/dirmon_entries_controller.rb +40 -21
  14. data/app/controllers/rocket_job_mission_control/jobs_controller.rb +50 -7
  15. data/app/controllers/rocket_job_mission_control/servers_controller.rb +7 -7
  16. data/app/datatables/rocket_job_mission_control/dirmon_entries_datatable.rb +1 -1
  17. data/app/datatables/rocket_job_mission_control/jobs_datatable.rb +1 -1
  18. data/app/helpers/rocket_job_mission_control/application_helper.rb +51 -26
  19. data/app/helpers/rocket_job_mission_control/dirmon_entries_helper.rb +12 -0
  20. data/app/helpers/rocket_job_mission_control/jobs_helper.rb +76 -8
  21. data/app/helpers/rocket_job_mission_control/servers_helper.rb +4 -0
  22. data/app/models/rocket_job_mission_control/access_policy.rb +2 -2
  23. data/app/models/rocket_job_mission_control/dirmon_sanitizer.rb +68 -0
  24. data/app/models/rocket_job_mission_control/job_sanitizer.rb +37 -0
  25. data/app/views/layouts/rocket_job_mission_control/partials/_flash.html.erb +4 -4
  26. data/app/views/rocket_job_mission_control/dirmon_entries/_form.html.erb +78 -42
  27. data/app/views/rocket_job_mission_control/dirmon_entries/_input_categories.html.erb +59 -0
  28. data/app/views/rocket_job_mission_control/dirmon_entries/_input_category_fields.html.erb +56 -0
  29. data/app/views/rocket_job_mission_control/dirmon_entries/_output_categories.html.erb +44 -0
  30. data/app/views/rocket_job_mission_control/dirmon_entries/_output_category_fields.html.erb +36 -0
  31. data/app/views/rocket_job_mission_control/dirmon_entries/_status.html.erb +22 -16
  32. data/app/views/rocket_job_mission_control/dirmon_entries/copy.html.erb +4 -0
  33. data/app/views/rocket_job_mission_control/dirmon_entries/edit.html.erb +7 -3
  34. data/app/views/rocket_job_mission_control/dirmon_entries/show.html.erb +8 -5
  35. data/app/views/rocket_job_mission_control/jobs/_attributes.html.erb +28 -0
  36. data/app/views/rocket_job_mission_control/jobs/_dates.html.erb +35 -0
  37. data/app/views/rocket_job_mission_control/jobs/_details.html.erb +125 -0
  38. data/app/views/rocket_job_mission_control/jobs/_exception.html.erb +22 -0
  39. data/app/views/rocket_job_mission_control/jobs/_input_categories.html.erb +76 -0
  40. data/app/views/rocket_job_mission_control/jobs/_input_category_fields.html.erb +56 -0
  41. data/app/views/rocket_job_mission_control/jobs/_output_categories.html.erb +49 -0
  42. data/app/views/rocket_job_mission_control/jobs/_output_category_fields.html.erb +36 -0
  43. data/app/views/rocket_job_mission_control/jobs/_retryable.html.erb +16 -0
  44. data/app/views/rocket_job_mission_control/jobs/_status.html.erb +20 -48
  45. data/app/views/rocket_job_mission_control/jobs/edit.html.erb +28 -0
  46. data/app/views/rocket_job_mission_control/jobs/edit_slice.html.erb +2 -2
  47. data/app/views/rocket_job_mission_control/jobs/exception.html.erb +1 -1
  48. data/app/views/rocket_job_mission_control/jobs/index.html.erb +24 -18
  49. data/app/views/rocket_job_mission_control/jobs/show.html.erb +32 -58
  50. data/app/views/rocket_job_mission_control/jobs/view_slice.html.erb +6 -4
  51. data/config/initializers/assets.rb +3 -4
  52. data/config/routes.rb +4 -0
  53. data/lib/rocket_job_mission_control/engine.rb +0 -3
  54. data/lib/rocket_job_mission_control/version.rb +1 -1
  55. data/test/controllers/rocket_job_mission_control/application_controller_test.rb +4 -12
  56. data/test/controllers/rocket_job_mission_control/dirmon_entries_controller_test.rb +20 -52
  57. data/test/controllers/rocket_job_mission_control/jobs_controller_test.rb +21 -41
  58. data/test/controllers/rocket_job_mission_control/servers_controller_test.rb +3 -3
  59. data/test/models/rocket_job_mission_control/dirmon_sanitizer_test.rb +146 -0
  60. data/test/models/rocket_job_mission_control/job_sanitizer_test.rb +9 -3
  61. data/test/test_helper.rb +6 -12
  62. data/vendor/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  63. data/vendor/assets/fonts/glyphicons-halflings-regular.svg +288 -0
  64. data/vendor/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  65. data/vendor/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  66. data/vendor/assets/fonts/glyphicons-halflings-regular.woff2 +0 -0
  67. data/vendor/assets/javascripts/bootstrap.min.js +3 -4
  68. data/vendor/assets/javascripts/datatables.min.js +881 -0
  69. data/vendor/assets/javascripts/jquery-3.5.1.min.js +2 -0
  70. data/vendor/assets/stylesheets/bootstrap.min.css.erb +6 -0
  71. data/vendor/assets/stylesheets/bootstrap.min.css.map +1 -1
  72. data/vendor/assets/stylesheets/datatables.min.css +141 -0
  73. metadata +60 -63
  74. data/app/assets/stylesheets/rocket_job_mission_control/base.scss +0 -436
  75. data/app/assets/stylesheets/rocket_job_mission_control/bootstrap_and_overrides.scss +0 -488
  76. data/app/assets/stylesheets/rocket_job_mission_control/jobs.scss +0 -72
  77. data/app/assets/stylesheets/rocket_job_mission_control/worker_processes.scss +0 -9
  78. data/vendor/assets/stylesheets/bootstrap.min.css +0 -6
@@ -4,74 +4,72 @@
4
4
  border-left-width: 0.5em;
5
5
  }
6
6
  .callout-queued {
7
- border-left-color: #A29F00;
8
- a {
9
- color: #A29F00;
10
- }
7
+ border-left-color: #a29f00;
8
+ }
9
+ .callout-queued a {
10
+ color: #a29f00;
11
11
  }
12
12
  .callout-running {
13
13
  border-left-color: #337ab7;
14
- a {
15
- color: #337ab7;
16
- }
14
+ }
15
+ .callout-running a {
16
+ color: #337ab7;
17
17
  }
18
18
  .callout-sleeping {
19
19
  border-left-color: darkcyan;
20
- a {
21
- color: darkcyan;
22
- }
20
+ }
21
+ .callout-sleeping a {
22
+ color: darkcyan;
23
23
  }
24
24
  .callout-scheduled {
25
- border-left-color: #92001B;
26
- a {
27
- color: #92001B;
28
- }
25
+ border-left-color: purple;
26
+ }
27
+ .callout-scheduled a {
28
+ color: purple;
29
29
  }
30
30
  .callout-completed {
31
31
  border-left-color: green;
32
- a {
33
- color: green;
34
- }
32
+ }
33
+ .callout-completed a {
34
+ color: green;
35
35
  }
36
36
  .callout-paused {
37
37
  border-left-color: orange;
38
- a {
39
- color: orange;
40
- }
38
+ }
39
+ .callout-paused a {
40
+ color: orange;
41
41
  }
42
42
  .callout-failed {
43
43
  border-left-color: red;
44
- a {
45
- color: red;
46
- }
44
+ }
45
+ .callout-failed a {
46
+ color: red;
47
47
  }
48
48
  .callout-aborted {
49
49
  border-left-color: darkorange;
50
- a {
51
- color: darkorange;
52
- }
53
50
  }
54
-
51
+ .callout-aborted a {
52
+ color: darkorange;
53
+ }
55
54
  /* Used by Dirmon Entries */
56
55
  .callout-pending {
57
56
  border-color: orange;
58
- a {
59
- color: orange;
60
- }
57
+ }
58
+ .callout-pending a {
59
+ color: orange;
61
60
  }
62
61
  .callout-enabled {
63
62
  border-left-color: green;
64
- a {
65
- color: green;
66
- }
63
+ }
64
+ .callout-enabled a {
65
+ color: green;
67
66
  }
68
67
  .callout-disabled {
69
68
  border-left-color: grey;
70
- a {
71
- color: grey;
72
- }
73
69
  }
74
-
70
+ .callout-disabled a {
71
+ color: grey;
72
+ }
75
73
  /* Used by Servers */
76
74
  .callout-top {
77
75
  border: 1px solid #eee;
@@ -79,31 +77,31 @@
79
77
  }
80
78
  .callout-info {
81
79
  border-left-color: #1b809e;
82
- .title {
83
- color: #1b809e;
84
- }
80
+ }
81
+ .callout-info .title {
82
+ color: #1b809e;
85
83
  }
86
84
  .callout-success {
87
85
  border-left-color: #3c763d;
88
- .title {
89
- color: #3c763d;
90
- }
86
+ }
87
+ .callout-success .title {
88
+ color: #3c763d;
91
89
  }
92
90
  .callout-warning {
93
91
  border-left-color: #aa6708;
94
- .title {
95
- color: #aa6708;
96
- }
92
+ }
93
+ .callout-warning .title {
94
+ color: #aa6708;
97
95
  }
98
96
  .callout-alert {
99
97
  border-left-color: #ce4844;
100
- .title {
101
- color: #ce4844;
102
- }
98
+ }
99
+ .callout-alert .title {
100
+ color: #ce4844;
103
101
  }
104
102
  .callout-zombie {
105
103
  border-left-color: darkred;
106
- .title {
107
- color: darkred;
108
- }
104
+ }
105
+ .callout-zombie .title {
106
+ color: darkred;
109
107
  }
@@ -0,0 +1,56 @@
1
+ .job-list {
2
+ /*padding: 1px 1px 1px 1px;
3
+ */
4
+ }
5
+ .job-list .breadcrumb {
6
+ margin-bottom: 0px;
7
+ }
8
+ .job-list .breadcrumb {
9
+ padding: 2px;
10
+ }
11
+ .job-list .breadcrumb > li {
12
+ margin: 5px 0 0 5px;
13
+ }
14
+ .job-list .list .progress {
15
+ width: 10em;
16
+ height: 1em;
17
+ margin: 5px 0px 0px 10px;
18
+ display: inline-block;
19
+ -webkit-border-radius: 0 !important;
20
+ -moz-border-radius: 0 !important;
21
+ border-radius: 0 !important;
22
+ }
23
+ .job-list .list .progress-bar {
24
+ min-width: 0em;
25
+ }
26
+ .error pre {
27
+ margin: 0px 0px 0px 0px;
28
+ border-bottom: 0;
29
+ border-radius: 0;
30
+ word-wrap: normal;
31
+ }
32
+ .error pre:last-child {
33
+ border: 1px solid #ccc;
34
+ }
35
+ .pagination {
36
+ margin-top: 1em;
37
+ }
38
+ .pagination .btn {
39
+ border-radius: 0;
40
+ }
41
+ .input_slices {
42
+ font-size: 14px;
43
+ line-height: 2;
44
+ resize: none;
45
+ width: 100%;
46
+ padding-top: 5px;
47
+ padding-bottom: 5px;
48
+ margin-bottom: 4px;
49
+ }
50
+ .edit_button {
51
+ float: right;
52
+ margin-left: 3px;
53
+ }
54
+ .edit_input {
55
+ margin-left: 80px;
56
+ }
@@ -0,0 +1,7 @@
1
+ #servers .server-collection-actions {
2
+ margin: 1em 0;
3
+ }
4
+ #servers .actions > a {
5
+ display: inline;
6
+ margin: 5px;
7
+ }
@@ -20,11 +20,13 @@ module RocketJobMissionControl
20
20
  else
21
21
  {roles: %i[admin]}
22
22
  end
23
- AccessPolicy.new(Authorization.new(@args))
23
+ AccessPolicy.new(Authorization.new(**@args))
24
24
  end
25
25
  end
26
26
 
27
27
  def login
28
+ return unless Config.authorization_callback
29
+
28
30
  @login ||= begin
29
31
  args = instance_exec(&Config.authorization_callback)
30
32
  args[:login]
@@ -1,18 +1,11 @@
1
1
  module RocketJobMissionControl
2
2
  class DirmonEntriesController < RocketJobMissionControl::ApplicationController
3
- if Rails.version.to_i < 5
4
- before_filter :find_entry_or_redirect, except: %i[index disabled enabled failed pending new create]
5
- before_filter :authorize_read, only: %i[index disabled enabled failed pending]
6
- before_filter :show_sidebar
7
- else
8
- before_action :find_entry_or_redirect, except: %i[index disabled enabled failed pending new create]
9
- before_action :authorize_read, only: %i[index disabled enabled failed pending]
10
- before_action :show_sidebar
11
- end
3
+ before_action :find_entry_or_redirect, except: %i[index disabled enabled failed pending new create]
4
+ before_action :authorize_read, only: %i[index disabled enabled failed pending]
5
+ before_action :show_sidebar
12
6
 
13
7
  rescue_from AccessGranted::AccessDenied do |exception|
14
8
  raise exception if Rails.env.development? || Rails.env.test?
15
-
16
9
  redirect_to :back, alert: "Access not authorized."
17
10
  end
18
11
 
@@ -56,6 +49,7 @@ module RocketJobMissionControl
56
49
  def create
57
50
  authorize! :create, RocketJob::DirmonEntry
58
51
  @dirmon_entry = RocketJob::DirmonEntry.new(dirmon_params)
52
+
59
53
  if properties = params[:rocket_job_dirmon_entry][:properties]
60
54
  @dirmon_entry.properties = JobSanitizer.sanitize(properties, @dirmon_entry.job_class, @dirmon_entry, false)
61
55
  end
@@ -77,12 +71,37 @@ module RocketJobMissionControl
77
71
  authorize! :edit, @dirmon_entry
78
72
  end
79
73
 
80
- def update
81
- authorize! :update, @dirmon_entry
74
+ # When you click on the Copy button,
75
+ # the copy method loads the Dirmon Entity attributes in Copy Dirmon Entry Page
76
+ def copy
77
+ authorize! :copy, @dirmon_entry
78
+ end
79
+
80
+ # When you click on the replicate button,
81
+ # the replicate method clones the existing Dirmon Entity
82
+ def replicate
83
+ authorize! :replicate, @dirmon_entry
84
+ dirmon_entry_replicate = RocketJob::DirmonEntry.new(@dirmon_entry.dup.attributes.except("id"))
85
+
82
86
  if properties = params[:rocket_job_dirmon_entry][:properties]
83
- @dirmon_entry.properties = JobSanitizer.sanitize(properties, @dirmon_entry.job_class, @dirmon_entry, false)
87
+ dirmon_entry_replicate.properties = JobSanitizer.sanitize(properties, dirmon_entry_replicate.job_class, @dirmon_entry, false)
88
+ end
89
+
90
+ if dirmon_entry_replicate.errors.empty? && dirmon_entry_replicate.valid? && dirmon_entry_replicate.update_attributes(dirmon_params)
91
+ redirect_to(rocket_job_mission_control.dirmon_entry_path(dirmon_entry_replicate))
92
+ else
93
+ render :copy
84
94
  end
85
- if @dirmon_entry.errors.empty? && @dirmon_entry.valid? && @dirmon_entry.update_attributes(dirmon_params)
95
+ end
96
+
97
+ def update
98
+ authorize! :update, @dirmon_entry
99
+ sanitized_params = DirmonSanitizer.sanitize(params[:rocket_job_dirmon_entry], @dirmon_entry.job_class, @dirmon_entry)
100
+ properties = DirmonSanitizer.diff_properties(sanitized_params[:properties], @dirmon_entry)
101
+
102
+ sanitized_params[:properties] = properties
103
+
104
+ if @dirmon_entry.errors.empty? && @dirmon_entry.valid? && @dirmon_entry.update_attributes(sanitized_params)
86
105
  redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
87
106
  else
88
107
  render :edit
@@ -91,22 +110,24 @@ module RocketJobMissionControl
91
110
 
92
111
  def enable
93
112
  authorize! :enable, @dirmon_entry
113
+
94
114
  if @dirmon_entry.may_enable?
95
115
  @dirmon_entry.enable!
96
116
  redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
97
117
  else
98
- flash[:alert] = t(:failure, scope: %i[dirmon_entry enable])
118
+ flash[:danger] = t(:failure, scope: %i[dirmon_entry enable])
99
119
  render(:show)
100
120
  end
101
121
  end
102
122
 
103
123
  def disable
104
124
  authorize! :disable, @dirmon_entry
125
+
105
126
  if @dirmon_entry.may_disable?
106
127
  @dirmon_entry.disable!
107
128
  redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
108
129
  else
109
- flash[:alert] = t(:failure, scope: %i[dirmon_entry disable])
130
+ flash[:danger] = t(:failure, scope: %i[dirmon_entry disable])
110
131
  render(:show)
111
132
  end
112
133
  end
@@ -128,16 +149,13 @@ module RocketJobMissionControl
128
149
 
129
150
  def find_entry_or_redirect
130
151
  unless @dirmon_entry = RocketJob::DirmonEntry.where(id: params[:id]).first
131
- flash[:alert] = t(:failure, scope: %i[dirmon_entry find], id: params[:id])
132
-
152
+ flash[:danger] = t(:failure, scope: %i[dirmon_entry find], id: ActionController::Base.helpers.sanitize(params[:id]))
133
153
  redirect_to(dirmon_entries_path)
134
154
  end
135
155
  end
136
156
 
137
157
  def dirmon_params
138
- params.
139
- fetch(:rocket_job_dirmon_entry, {}).
140
- permit(:name, :archive_directory, :pattern, :job_class_name)
158
+ params.fetch(:rocket_job_dirmon_entry, {}).permit(:name, :archive_directory, :pattern, :job_class_name, :properties)
141
159
  end
142
160
 
143
161
  def render_datatable(entries, description)
@@ -146,6 +164,7 @@ module RocketJobMissionControl
146
164
  @description = description
147
165
  render :index
148
166
  end
167
+
149
168
  format.json do
150
169
  query = RocketJobMissionControl::Query.new(entries, name: :asc)
151
170
  query.search_columns = %i[job_class_name name pattern]
@@ -74,8 +74,11 @@ module RocketJobMissionControl
74
74
 
75
75
  def update
76
76
  authorize! :update, @job
77
- permitted_params = JobSanitizer.sanitize(params[:job], @job.class, @job)
78
- if @job.errors.empty? && @job.valid? && @job.update_attributes(permitted_params)
77
+ permitted_params = JobSanitizer.sanitize(job_params, @job.class, @job)
78
+
79
+ assign_job_values(@job, permitted_params)
80
+
81
+ if @job.errors.empty? && @job.valid? && @job.save
79
82
  redirect_to job_path(@job)
80
83
  else
81
84
  render :edit
@@ -179,6 +182,9 @@ module RocketJobMissionControl
179
182
  # Finds specific slice [Array]
180
183
  slice = @job.input.failed.skip(offset).first
181
184
 
185
+ # Converts \r\n line breaks to \n
186
+ updated_records.each { |record| record.gsub(/\r\n/, "\n") }
187
+
182
188
  # Assings modified slice (from the form) back to slice
183
189
  slice.records = updated_records
184
190
 
@@ -225,14 +231,14 @@ module RocketJobMissionControl
225
231
  offset = params.fetch(:offset, 0).to_i
226
232
 
227
233
  unless error_type.present?
228
- flash[:notice] = t(:no_errors, scope: %i[job failures])
234
+ flash[:warning] = t(:no_errors, scope: %i[job failures])
229
235
  redirect_to(job_path(@job))
230
236
  end
231
237
 
232
238
  scope = @job.input.failed.where("exception.class_name" => error_type)
233
239
  count = scope.count
234
240
  unless count.positive?
235
- flash[:notice] = t(:no_errors, scope: %i[job failures])
241
+ flash[:warning] = t(:no_errors, scope: %i[job failures])
236
242
  redirect_to(job_path(@job))
237
243
  end
238
244
 
@@ -247,6 +253,24 @@ module RocketJobMissionControl
247
253
 
248
254
  private
249
255
 
256
+ def assign_job_values(target, hash)
257
+ hash.each_pair do |attribute, value|
258
+ if attribute == :input_categories
259
+ value.each do |category_hash|
260
+ h = category_hash.dup
261
+ assign_job_values(target.input_category(h.delete(:name)), h)
262
+ end
263
+ elsif attribute == :output_categories
264
+ value.each do |category_hash|
265
+ h = category_hash.dup
266
+ assign_job_values(target.output_category(h.delete(:name)), h)
267
+ end
268
+ elsif attribute != :id
269
+ target.send("#{attribute}=", value)
270
+ end
271
+ end
272
+ end
273
+
250
274
  def authorize_read
251
275
  authorize! :read, RocketJob::Job
252
276
  end
@@ -257,14 +281,33 @@ module RocketJobMissionControl
257
281
 
258
282
  def find_job_or_redirect
259
283
  unless @job = RocketJob::Job.where(id: params[:id]).first
260
- flash[:alert] = t(:failure, scope: %i[job find], id: params[:id])
284
+ flash[:danger] = t(:failure, scope: %i[job find], id: ActionController::Base.helpers.sanitize(params[:id]))
261
285
 
262
286
  redirect_to(jobs_path)
263
287
  end
264
288
  end
265
289
 
266
290
  def job_params
267
- params.require(:job).permit(@job.class.user_editable_fields)
291
+ params.require(:job).permit(
292
+ @job.class.user_editable_fields,
293
+ input_categories_attributes: [
294
+ :id,
295
+ :name,
296
+ :format,
297
+ :format_options,
298
+ :mode,
299
+ :skip_unknown,
300
+ :slice_size,
301
+ columns: []
302
+ ],
303
+ output_categories_attributes: [
304
+ :id,
305
+ :name,
306
+ :format,
307
+ :format_options,
308
+ columns: []
309
+ ]
310
+ )
268
311
  end
269
312
 
270
313
  def error_occurred(exception)
@@ -308,7 +351,7 @@ module RocketJobMissionControl
308
351
  h = {data: index.to_s}
309
352
  h[:width] = column[:width] if column.key?(:width)
310
353
  h[:orderable] = column[:orderable] if column.key?(:orderable)
311
- index += 1
354
+ index += 1
312
355
  h
313
356
  end
314
357
  end