rocketjob_mission_control 1.1.0 → 1.2.0

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/rocket_job_mission_control/dirmon_entries.js.coffee +18 -0
  3. data/app/assets/stylesheets/rocket_job_mission_control/base.scss +33 -59
  4. data/app/assets/stylesheets/rocket_job_mission_control/bootstrap_and_overrides.scss +12 -0
  5. data/app/assets/stylesheets/rocket_job_mission_control/callout.scss +8 -0
  6. data/app/assets/stylesheets/rocket_job_mission_control/jobs.scss +35 -0
  7. data/app/controllers/rocket_job_mission_control/application_controller.rb +0 -2
  8. data/app/controllers/rocket_job_mission_control/dirmon_entries_controller.rb +125 -0
  9. data/app/controllers/rocket_job_mission_control/jobs/failures_controller.rb +31 -0
  10. data/app/helpers/rocket_job_mission_control/application_helper.rb +7 -0
  11. data/app/helpers/rocket_job_mission_control/jobs_helper.rb +18 -11
  12. data/app/helpers/rocket_job_mission_control/pagination_helper.rb +7 -0
  13. data/app/helpers/rocket_job_mission_control/slices_helper.rb +9 -0
  14. data/app/models/job_failures.rb +30 -0
  15. data/app/views/layouts/rocket_job_mission_control/application.html.haml +3 -1
  16. data/app/views/layouts/rocket_job_mission_control/partials/_header.html.haml +2 -2
  17. data/app/views/layouts/rocket_job_mission_control/partials/_sidebar.html.haml +4 -0
  18. data/app/views/rocket_job_mission_control/dirmon_entries/_form.html.haml +36 -0
  19. data/app/views/rocket_job_mission_control/dirmon_entries/_list.html.haml +31 -0
  20. data/app/views/rocket_job_mission_control/dirmon_entries/_properties.html.haml +8 -0
  21. data/app/views/rocket_job_mission_control/dirmon_entries/_status.html.haml +23 -0
  22. data/app/views/rocket_job_mission_control/dirmon_entries/edit.html.haml +8 -0
  23. data/app/views/rocket_job_mission_control/dirmon_entries/index.html.haml +11 -0
  24. data/app/views/rocket_job_mission_control/dirmon_entries/new.html.haml +9 -0
  25. data/app/views/rocket_job_mission_control/dirmon_entries/show.html.haml +26 -0
  26. data/app/views/rocket_job_mission_control/jobs/_list.html.haml +34 -30
  27. data/app/views/rocket_job_mission_control/jobs/failures/_pagination.html.haml +16 -0
  28. data/app/views/rocket_job_mission_control/jobs/failures/index.html.haml +32 -0
  29. data/app/views/rocket_job_mission_control/jobs/index.html.haml +10 -8
  30. data/app/views/rocket_job_mission_control/jobs/running.html.haml +1 -1
  31. data/app/views/rocket_job_mission_control/jobs/show.html.haml +39 -35
  32. data/app/views/rocket_job_mission_control/workers/_actions.html.haml +4 -4
  33. data/app/views/rocket_job_mission_control/workers/index.html.haml +50 -45
  34. data/config/locales/en.yml +23 -1
  35. data/config/routes.rb +8 -0
  36. data/lib/rocket_job_mission_control/version.rb +1 -1
  37. data/spec/controllers/dirmon_entries_controller_spec.rb +451 -0
  38. data/spec/controllers/jobs/failures_controller_spec.rb +60 -0
  39. data/spec/dummy/config/environments/test.rb +1 -1
  40. data/spec/dummy/config/mongo.yml +15 -0
  41. data/spec/dummy/log/development.log +2 -0
  42. data/spec/dummy/log/test.log +52763 -2015
  43. data/spec/helpers/jobs_helper_spec.rb +27 -0
  44. data/spec/helpers/pagination_helper_spec.rb +21 -0
  45. data/spec/helpers/slices_helper_spec.rb +33 -0
  46. data/spec/models/job_failures_spec.rb +14 -0
  47. data/spec/views/workers/index.html.haml_spec.rb +23 -0
  48. metadata +35 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7e41c195c2f19cc796166af9416626e889f659ae
4
- data.tar.gz: de8a20f45aec4ca0fd5d6de4a6e2a6ac8fd923c2
3
+ metadata.gz: c8d7c96f03155c733cf07a5e81796020552dd378
4
+ data.tar.gz: cf0647850f7b019530b1f1c6d4a511dbcb5fcc5b
5
5
  SHA512:
6
- metadata.gz: 286dfb374edb8f8ff0da5cc215aedb9197369e9ad825289e6588cac983be1faaccf5b049f435909f5c35c5bc1a27251955af99a6897e41eb06f1ad588fe2f5eb
7
- data.tar.gz: daf53bdc5365b5ba592eba9fdbf8f32bc03aa50d92a1c26b49131f6a44fdc2ac02fdb3a468545be334e718ca96791a86ae1f44be6f3caf0f525506c6e09c33f6
6
+ metadata.gz: 4639ef836e562dc597c5e0651571111ac84b3a217b3599da8f06807513375c73b44eb9a091517da37c57f6fa9d478fa2f23f75825ef6c8afad0e899f4892d67b
7
+ data.tar.gz: fe70a9fd5c6cbd029443dda89be419f9c08b6de28fe3a90f2908bccd753f3d4c5837fb239e9d970170e3849c7086e33d9ee5b38518298676b0844308298b9303
@@ -0,0 +1,18 @@
1
+ $(document).on 'ready', ->
2
+ $('.filter .state-toggle').on 'change', ->
3
+ active_states = $('.filter :checked')
4
+ param_string = "?"
5
+ active_states.each (_, state) ->
6
+ param_string += "states[]=" + $(state).attr('id') + "&"
7
+ window.location.href = window.location.href.replace( /[\?#].*|$/, param_string );
8
+
9
+ if $('#properties').length
10
+ $('#expand').on 'click', ->
11
+ $(this).hide()
12
+ $('#collapse').show()
13
+ $('#properties').show()
14
+ $('#collapse').on 'click', ->
15
+ $(this).hide()
16
+ $('#expand').show()
17
+ $('#properties').hide()
18
+
@@ -3,6 +3,13 @@
3
3
  overflow: hidden;
4
4
  }
5
5
 
6
+ .footer {
7
+ position: relative;
8
+ height: 100px;
9
+ clear:both;
10
+ padding-top:20px;
11
+ }
12
+
6
13
  body.rocket_job {
7
14
  padding: 0;
8
15
 
@@ -10,8 +17,8 @@ body.rocket_job {
10
17
 
11
18
  .job-list {
12
19
  height: 100%;
20
+ min-height: 768px;
13
21
  border-right: 1px solid #ddd;
14
- padding: 0;
15
22
  }
16
23
 
17
24
  .job-status {
@@ -41,7 +48,7 @@ body.rocket_job {
41
48
  p { font-size: 16px; }
42
49
  }
43
50
 
44
- .job-retry {
51
+ .job-actions {
45
52
  float: left;
46
53
  margin-top: 23px;
47
54
  margin-left: 20px;
@@ -49,6 +56,12 @@ body.rocket_job {
49
56
  .btn { padding: 2px 6px; }
50
57
  }
51
58
 
59
+ .pagination-buttons {
60
+ float: left;
61
+ margin-top: 23px;
62
+ margin-left: 20px;
63
+ }
64
+
52
65
  .job-state {
53
66
  margin-left: 20px;
54
67
  padding: 0;
@@ -75,10 +88,10 @@ body.rocket_job {
75
88
  border-bottom-right-radius: 3px;
76
89
  }
77
90
 
78
- .queued { background-color: darkgrey; }
91
+ .queued, .pending { background-color: darkgrey; }
79
92
  .running { background-color: #337ab7; }
80
- .completed { background-color: green; }
81
- .paused { background-color: orange; }
93
+ .completed, .enabled { background-color: green; }
94
+ .paused, .disabled { background-color: orange; }
82
95
  .failed { background-color: red; }
83
96
  .aborted { background-color: darkorange; }
84
97
  }
@@ -125,11 +138,18 @@ body.rocket_job {
125
138
  text-align: center;
126
139
 
127
140
  a {
141
+ display: inline-block;
128
142
  color: orange;
129
143
  font-weight: bold;
144
+
130
145
  }
131
146
 
132
- .color {
147
+ a:hover, a:active {
148
+ text-decoration: none;
149
+ }
150
+
151
+
152
+ span {
133
153
  display: inline-block;
134
154
  position: relative;
135
155
  left: -3px;
@@ -278,7 +298,7 @@ body.rocket_job {
278
298
  a { display: block; }
279
299
 
280
300
  .card:nth-child(1) { border-top: 1px solid #ddd; }
281
- .card:nth-child(odd) { background-color: #fff; }
301
+ .card:nth-child(odd):not(.selected) { background-color: #fff; }
282
302
 
283
303
  .card {
284
304
  border-bottom: 1px solid #ddd;
@@ -305,6 +325,8 @@ body.rocket_job {
305
325
  i.paused { color: orange; }
306
326
  i.failed { color: red; }
307
327
  i.aborted { color: darkorange; }
328
+ i.enabled { color: green; }
329
+ i.disabled { color: orange; }
308
330
 
309
331
  h3 {
310
332
  font-weight: bold;
@@ -336,9 +358,9 @@ body.rocket_job {
336
358
  }
337
359
 
338
360
  .selected {
339
- border-bottom: 2px solid blue;
340
- border-right: 2px solid blue;
341
- border-top: 2px solid blue;
361
+ border-bottom: 1px solid blue;
362
+ border-right: 1px solid blue;
363
+ border-top: 1px solid blue;
342
364
  background-color: lightcyan;
343
365
  }
344
366
 
@@ -367,12 +389,6 @@ body.rocket_job {
367
389
  position: relative;
368
390
  text-align: center;
369
391
 
370
- .icon {
371
- color: #83ADFA;
372
- text-align: center;
373
- font-size: 50px;
374
- }
375
-
376
392
  .title, .state, .threads, .time { margin-bottom: 10px; }
377
393
 
378
394
  .actions {
@@ -395,7 +411,7 @@ body.rocket_job {
395
411
  }
396
412
  }
397
413
 
398
- .spinner {
414
+ .priority-group {
399
415
  width: 67px;
400
416
  margin: 0 auto;
401
417
 
@@ -436,51 +452,9 @@ body.rocket_job {
436
452
  }
437
453
  }
438
454
 
439
- .green.signal {
440
- -webkit-animation: greenPulse 2s infinite;
441
- -moz-animation: greenPulse 2s infinite;
442
- -o-animation: greenPulse 2s infinite;
443
- animation: greenPulse 2s infinite;
444
- margin: 0 5px 0 10px;
445
- }
446
-
447
455
  .code-block { margin-top: 25px; }
448
456
 
449
457
  .status {
450
458
  padding: 1em;
451
459
  }
452
-
453
- // Warnings & Notifications
454
-
455
- .no-servers {
456
- text-align: center;
457
- font-size: 23px;
458
- padding-top: 50px;
459
- color: #777;
460
- }
461
- }
462
-
463
- // Rocket Job Animations
464
- @-webkit-keyframes greenPulse {
465
- 0% { color: #91bd09; -webkit-box-shadow: 0 0 9px #91bd09; border-radius: 30px; }
466
- 50% { color: rgb(107, 240, 123); -webkit-box-shadow: 0 0 18px rgb(107, 240, 123); border-radius: 30px; }
467
- 100% { color: #91bd09; -webkit-box-shadow: 0 0 9px #91bd09; border-radius: 30px; }
468
- }
469
-
470
- @-moz-keyframes greenPulse {
471
- 0% { background-color: #749a02; -moz-box-shadow: 0 0 9px #333; }
472
- 50% { background-color: lime; -moz-box-shadow: 0 0 18px #91bd09; }
473
- 100% { background-color: #749a02; -moz-box-shadow: 0 0 9px #333; }
474
- }
475
-
476
- @-o-keyframes greenPulse {
477
- 0% { background-color: #749a02; box-shadow: 0 0 9px #749a02; }
478
- 50% { background-color: #91bd09; box-shadow: 0 0 18px #91bd09; }
479
- 100% { background-color: #749a02; box-shadow: 0 0 9px #749a02; }
480
- }
481
-
482
- @keyframes greenPulse {
483
- 0% { background-color: #749a02; box-shadow: 0 0 9px #333; }
484
- 50% { background-color: #91bd09; box-shadow: 0 0 18px #91bd09; }
485
- 100% { background-color: #749a02; box-shadow: 0 0 9px #333; }
486
460
  }
@@ -1,6 +1,18 @@
1
+ $border-radius-small: 2px;
2
+ $border-radius-base: 3px;
3
+ $border-radius-large: 4px;
4
+
1
5
  @import "bootstrap-sprockets";
2
6
  @import "bootstrap";
3
7
 
8
+ .alert {
9
+ margin-bottom: 0px;
10
+ }
11
+
4
12
  .alert-notice {
5
13
  @extend .alert-info
6
14
  }
15
+
16
+ .alert-alert {
17
+ @extend .alert-danger
18
+ }
@@ -22,6 +22,14 @@
22
22
  border-left-color: darkorange;
23
23
  }
24
24
 
25
+ /* Used by Dirmon Entries */
26
+ .callout-enabled {
27
+ border-left-color: green;
28
+ }
29
+ .callout-disabled {
30
+ border-left-color: orange;
31
+ }
32
+
25
33
  /* Used by Workers */
26
34
  .callout-top {
27
35
  border: 1px solid #eee;
@@ -1,4 +1,18 @@
1
1
  .job-list {
2
+ .breadcrumb {
3
+ margin-bottom: 0px;
4
+ }
5
+
6
+ /*padding: 1px 1px 1px 1px;*/
7
+
8
+ .breadcrumb {
9
+ padding: 2px;
10
+
11
+ > li {
12
+ margin: 5px 0 0 5px;
13
+ }
14
+ }
15
+
2
16
  .list {
3
17
  .progress {
4
18
  width: 16em;
@@ -14,3 +28,24 @@
14
28
  }
15
29
  }
16
30
  }
31
+
32
+ .error {
33
+ pre {
34
+ margin: 0px 0px 0px 0px;
35
+ border-bottom: 0;
36
+ border-radius: 0;
37
+ word-wrap: normal;
38
+ }
39
+
40
+ pre:last-child {
41
+ border: 1px solid #cccccc;
42
+ }
43
+ }
44
+
45
+ .pagination {
46
+ margin-top: 1em;
47
+
48
+ .btn {
49
+ border-radius: 0;
50
+ }
51
+ }
@@ -1,7 +1,5 @@
1
1
  module RocketJobMissionControl
2
2
  class ApplicationController < ActionController::Base
3
- include ActionController::Live
4
-
5
3
  around_action :with_time_zone
6
4
 
7
5
  private
@@ -0,0 +1,125 @@
1
+ module RocketJobMissionControl
2
+ class DirmonEntriesController < RocketJobMissionControl::ApplicationController
3
+ before_filter :find_entry_or_redirect, except: [:index, :new, :create]
4
+ before_filter :clean_values, only: [:create, :update]
5
+ before_action :load_entries, only: [:index, :show, :new, :edit]
6
+
7
+ def index
8
+ end
9
+
10
+ def show
11
+ end
12
+
13
+ def new
14
+ @dirmon_entry = RocketJob::DirmonEntry.new(arguments: nil)
15
+ end
16
+
17
+ def create
18
+ @dirmon_entry = RocketJob::DirmonEntry.new(dirmon_params)
19
+
20
+ parse_and_assign_arguments
21
+
22
+ if @dirmon_entry.errors.empty? && @dirmon_entry.save
23
+ flash[:success] = t(:success, scope: [:dirmon_entry, :create])
24
+ redirect_to(dirmon_entry_path(@dirmon_entry))
25
+ else
26
+ load_entries
27
+ render :new
28
+ end
29
+ end
30
+
31
+ def destroy
32
+ @dirmon_entry.destroy
33
+ flash[:success] = t(:success, scope: [:dirmon_entry, :destroy])
34
+
35
+ redirect_to(dirmon_entries_path)
36
+ end
37
+
38
+ def edit
39
+ end
40
+
41
+ def update
42
+ parse_and_assign_arguments
43
+ if @dirmon_entry.errors.empty? && @dirmon_entry.update_attributes(dirmon_params)
44
+ flash[:success] = t(:success, scope: [:dirmon_entry, :update])
45
+ redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
46
+ else
47
+ load_entries
48
+ render :edit
49
+ end
50
+ end
51
+
52
+ def enable
53
+ if @dirmon_entry.may_enable?
54
+ @dirmon_entry.enable!
55
+ flash[:success] = t(:success, scope: [:dirmon_entry, :enable])
56
+ redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
57
+ else
58
+ flash[:alert] = t(:failure, scope: [:dirmon_entry, :enable])
59
+ load_entries
60
+ render(:show)
61
+ end
62
+ end
63
+
64
+ def disable
65
+ if @dirmon_entry.may_disable?
66
+ @dirmon_entry.disable!
67
+ flash[:success] = t(:success, scope: [:dirmon_entry, :disable])
68
+ redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
69
+ else
70
+ flash[:alert] = t(:failure, scope: [:dirmon_entry, :disable])
71
+ load_entries
72
+ render(:show)
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def parse_and_assign_arguments
79
+ if arguments = params[:rocket_job_dirmon_entry][:arguments]
80
+ begin
81
+ arguments = JSON.parse(arguments)
82
+ @dirmon_entry.arguments = arguments.kind_of?(Array) ? arguments : [arguments]
83
+ rescue JSON::ParserError => e
84
+ @dirmon_entry.errors.add(:arguments, e.message)
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ def clean_values
91
+ params[:rocket_job_dirmon_entry].fetch(:properties, {}).each_pair do |param, value|
92
+ params[:rocket_job_dirmon_entry][:properties].delete(param) if value.blank?
93
+ end
94
+ end
95
+
96
+ def load_entries
97
+ @states = dirmons_params
98
+ @dirmons = RocketJob::DirmonEntry.limit(1000).sort(created_at: :desc)
99
+ @dirmons = @dirmons.where(state: @states) unless @states.empty?
100
+ end
101
+
102
+ def find_entry_or_redirect
103
+ @dirmon_entry = RocketJob::DirmonEntry.find(params[:id])
104
+
105
+ if @dirmon_entry.nil?
106
+ flash[:alert] = t(:failure, scope: [:dirmon_entry, :find], id: params[:id])
107
+
108
+ redirect_to(dirmon_entries_path)
109
+ end
110
+ end
111
+
112
+ def dirmons_params
113
+ params.fetch(:states, [])
114
+ end
115
+
116
+ def dirmon_params
117
+ params
118
+ .require(:rocket_job_dirmon_entry)
119
+ .permit(:name, :archive_directory, :pattern, :job_class_name).tap do |whitelist|
120
+ whitelist[:properties] = params[:rocket_job_dirmon_entry][:properties] if params[:rocket_job_dirmon_entry][:properties]
121
+ end
122
+ end
123
+
124
+ end
125
+ end
@@ -0,0 +1,31 @@
1
+ module RocketJobMissionControl
2
+ module Jobs
3
+ class FailuresController < RocketJobMissionControl::ApplicationController
4
+ def index
5
+ job_failures = JobFailures.new(params[:job_id])
6
+ @job = job_failures.job
7
+
8
+ if @job && @job.failed?
9
+ @slice_errors = job_failures.list
10
+ @error_type = params[:error_type] || @slice_errors.first['_id']['error_class']
11
+
12
+ offset = params.fetch(:offset, 1).to_i
13
+ selected_exception = job_failures.for_error(@error_type, offset)
14
+ current_failure = selected_exception.first
15
+
16
+ @pagination = {
17
+ offset: offset,
18
+ total: (selected_exception.count - 1),
19
+ }
20
+
21
+ if current_failure.present?
22
+ @failure_exception = current_failure['exception']
23
+ end
24
+
25
+ else
26
+ redirect_to(job_path(params[:job_id]))
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -12,5 +12,12 @@ module RocketJobMissionControl
12
12
  def active_page(path)
13
13
  'active' if current_page?(path)
14
14
  end
15
+
16
+ def pretty_print_array_or_hash(arguments)
17
+ return arguments unless arguments.kind_of?(Array) || arguments.kind_of?(Hash)
18
+ json_string_options = { space: ' ', indent: ' ', array_nl: '<br />', object_nl: '<br />' }
19
+ JSON.generate(arguments, json_string_options).html_safe
20
+ end
21
+
15
22
  end
16
23
  end
@@ -1,13 +1,16 @@
1
1
  module RocketJobMissionControl
2
2
  module JobsHelper
3
3
  STATE_ICON_MAP = {
4
- queued: 'fa-inbox',
4
+ aborted: 'fa-stop',
5
+ completed: 'fa-check',
6
+ disabled: 'fa-stop',
7
+ enabled: 'fa-check',
8
+ failed: 'fa-exclamation-triangle',
5
9
  paused: 'fa-pause',
10
+ pending: 'fa-inbox',
11
+ queued: 'fa-inbox',
6
12
  running: 'fa-play',
7
- completed: 'fa-check',
8
- aborted: 'fa-stop',
9
- failed: 'fa-times',
10
- scheduled: 'fa-clock-o'
13
+ scheduled: 'fa-clock-o',
11
14
  }
12
15
 
13
16
  def job_state_icon(state)
@@ -25,14 +28,18 @@ module RocketJobMissionControl
25
28
  job_state_icon(state)
26
29
  end
27
30
 
28
- def job_states
29
- @job_states ||= RocketJob::Job.aasm.states.collect { |state| state.name.to_s }
31
+ def job_action_link(action, path, http_method=:get)
32
+ link_to(
33
+ action,
34
+ path,
35
+ method: http_method,
36
+ class: 'btn btn-default',
37
+ data: { confirm: t(:confirm, scope: [:job, :action], action: action)}
38
+ )
30
39
  end
31
40
 
32
- def pretty_print_array_or_hash(arguments)
33
- return arguments unless arguments.kind_of?(Array) || arguments.kind_of?(Hash)
34
- json_string_options = { space: ' ', indent: ' ', array_nl: '<br />', object_nl: '<br />' }
35
- JSON.generate(arguments, json_string_options).html_safe
41
+ def job_states
42
+ @job_states ||= RocketJob::Job.aasm.states.map { |state| state.name.to_s }
36
43
  end
37
44
 
38
45
  def job_selected_class(job, selected_job)
@@ -0,0 +1,7 @@
1
+ module RocketJobMissionControl
2
+ module PaginationHelper
3
+ def page_nav_disabled_class(current_position, boundary)
4
+ current_position.to_i == boundary.to_i ? 'disabled' : ''
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module RocketJobMissionControl
2
+ module SlicesHelper
3
+
4
+ def display_slice_info(slice, encrypted=false)
5
+ encrypted ? 'encrypted' : pretty_print_array_or_hash(slice.to_a)
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,30 @@
1
+ class JobFailures
2
+ attr_reader :job_id
3
+
4
+ def initialize(job_id)
5
+ @job_id = job_id
6
+ end
7
+
8
+ def job
9
+ @job ||= RocketJob::Job.find(job_id)
10
+ end
11
+
12
+ def list
13
+ @slice_errors ||= job.input.collection.aggregate(
14
+ [
15
+ {
16
+ '$group' => {
17
+ _id: { error_class: '$exception.class_name' },
18
+ messages: { '$addToSet' => '$exception.message' },
19
+ count: { '$sum' => 1 }
20
+ },
21
+ }
22
+ ]
23
+ )
24
+ end
25
+
26
+ def for_error(error_type, page_offset=0)
27
+ query = { 'state' => 'failed', 'exception.class_name' => error_type }
28
+ @job.input.collection.find(query).limit(1).skip(page_offset)
29
+ end
30
+ end
@@ -18,7 +18,7 @@
18
18
 
19
19
  = csrf_meta_tag
20
20
 
21
- %link{href: "//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css", rel: "stylesheet"}/
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
24
  #wrapper.toggled
@@ -41,3 +41,5 @@
41
41
  = msg.html_safe
42
42
 
43
43
  = yield
44
+
45
+ %footer.footer
@@ -13,6 +13,6 @@
13
13
 
14
14
  .brand
15
15
  = link_to root_path, class: 'text-center' do
16
- = image_tag('rocket_job_mission_control/rocket-icon-64x64.png', size: '56x32')
16
+ = image_tag('rocket_job_mission_control/rocket-icon-64x64.png', size: '32x32')
17
17
  rocket
18
- .color job
18
+ %span job
@@ -18,3 +18,7 @@
18
18
  = link_to running_jobs_path, class: active_page(running_jobs_path) do
19
19
  %i.fa.fa-circle-o-notch
20
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
@@ -0,0 +1,36 @@
1
+ - action ||= :create
2
+ - if @dirmon_entry.errors.present?
3
+ .alert.alert-alert
4
+ Error saving entry!
5
+ - @dirmon_entry.errors.messages.each_pair do |field, message|
6
+ .message
7
+ = "#{field}: #{message}"
8
+ = 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'
12
+ .path.form-group
13
+ = f.label :pattern
14
+ = f.text_field :pattern, class: 'form-control'
15
+ .path.form-group
16
+ = f.label :archive_directory
17
+ = f.text_field :archive_directory, class: 'form-control'
18
+ .job.form-group
19
+ = f.label :job_class_name
20
+ = f.text_field :job_class_name, class: 'form-control'
21
+ .job_arguments.form-group
22
+ = f.label :arguments
23
+ = f.text_area :arguments,
24
+ value: @dirmon_entry.arguments.empty? ? nil : @dirmon_entry.arguments.to_json,
25
+ rows: 10,
26
+ placeholder: '{"argument1"":"value1", "argument2":"value2", "argument3":"value3"}',
27
+ class: 'form-control'
28
+ .row
29
+ .col-md-12#properties{ style: 'display:none;' }
30
+ = render partial: 'properties', locals: { f: f }
31
+
32
+ .buttons
33
+ = f.submit action, class: 'btn btn-primary'
34
+ = link_to 'cancel', :back, class: 'btn btn-default'
35
+ = button_tag 'properties',type: 'button', class: 'btn btn-default', id: 'expand'
36
+ = button_tag 'collapse',type: 'button', class: 'btn btn-default', id: 'collapse', style: 'display:none;'
@@ -0,0 +1,31 @@
1
+ .col-md-4
2
+ .job-list
3
+ .filter
4
+ %ol.breadcrumb
5
+ %li.active Dirmon Entries
6
+ .pull-right
7
+ = link_to "Create", new_dirmon_entry_path, class: "btn btn-default"
8
+ .btn-group{ data: { toggle: 'buttons' } }
9
+ - RocketJob::DirmonEntry.aasm.states.map { |s| s.name.to_s }.each do |state|
10
+ - enabled = @states.include?(state.to_s) || @states.empty?
11
+ - title = enabled ? 'Hide' : 'Show'
12
+ %label.btn.btn-default.state-toggle{ class: ('active' if enabled), title: "#{title} #{state.to_s.capitalize}" }
13
+ = check_box_tag(state.to_s, state.to_s, enabled)
14
+ %i.fa{class: job_state_icon(state)}
15
+ .clearfix
16
+ .list
17
+ - if @dirmons.empty?
18
+ .card.inner
19
+ .title
20
+ .lead.text-center No Dirmon Entries Found.
21
+ - else
22
+ - @dirmons.each do |dirmon|
23
+ - state = dirmon.enabled? ? :enabled : :disabled
24
+ = link_to dirmon_entry_path(id: dirmon.id, states: @states), class: "card callout callout-#{dirmon.state} #{job_selected_class(dirmon, @dirmon_entry)}" do
25
+ .inner
26
+ .title
27
+ .lead
28
+ %i.fa{class: job_state_icon(dirmon.state), style: 'font-size: 75%;', title: dirmon.state}
29
+ = dirmon.name
30
+
31
+ .description= dirmon.pattern.try(:truncate, 80)
@@ -0,0 +1,8 @@
1
+ .arguments
2
+ = f.fields_for :properties do |properties|
3
+ .form-group
4
+ = properties.label :description
5
+ = properties.text_field :description, value: @dirmon_entry.properties[:description], placeholder: "max length: 128", class: 'form-control'
6
+ .form-group
7
+ = properties.label :priority
8
+ = properties.text_field :priority, value: @dirmon_entry.properties[:priority], placeholder: "e.g 1..100", class: 'form-control'