marty 8.3.1 → 8.4.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a089e78541222d60d9d84b7339c0fdefc8c87f445f0943a471732167e6946e2
4
- data.tar.gz: cde4b147a1f9d753327c09665df1aa2045f887c9a6d0cafd0236227ceff3c7f9
3
+ metadata.gz: 6d2b7a71540fdd0a796cc8bd62725ddfa80231af28875eff79b5cbf1e6b8d65a
4
+ data.tar.gz: de508c108b52dc8b89d9d873030173594952a5c48ee507c68438f2e01a21d136
5
5
  SHA512:
6
- metadata.gz: 42d06eccfc9294f7151ab41f12e6a8970c0c086fe8d6cf492c3520d82ed2c9694bc9f231f8fb6e3d6bb4f8f9c251085145a2c7f5d2d04884bc071a68b64dc4ee
7
- data.tar.gz: 32f0ce4bd5c4425ab855e4d606b50d117be8609c4cf23ba0968b2ced644fcdc29ca1f5ad7b8b345b6b6bf42a0cee374c973ec8d6ac191ab7c37623c6c729b2be
6
+ metadata.gz: efbcc2b834193e2525809e494d6e12936d75606b03f7c2fb9970008eb3adac30bb4a193c9bd64323691db0fdd983401aba0e73907df16f839bfb4675551094af
7
+ data.tar.gz: 1c2834966a5b98f4177a14a297eed967b88a94b7f56c6c3597445e6dcd25ab96cad08465bcbf31f4675a76cc2d977f0a198efae2b15f47e64f771159ae2dfdf6
@@ -0,0 +1,71 @@
1
+ module Marty
2
+ module BackgroundJob
3
+ class DelayedJobsGrid < Marty::Grid
4
+ ACCESSIBLE_BY = [:admin]
5
+
6
+ has_marty_permissions(
7
+ read: ACCESSIBLE_BY,
8
+ create: nil,
9
+ update: nil,
10
+ delete: nil,
11
+ destroy: ACCESSIBLE_BY,
12
+ job_run: ACCESSIBLE_BY,
13
+ edit_window__edit_form__submit: ACCESSIBLE_BY,
14
+ add_window__add_form__submit: ACCESSIBLE_BY
15
+ )
16
+
17
+ def configure(c)
18
+ super
19
+
20
+ c.title ||= I18n.t(
21
+ 'schedule_jobs_dashboard_view_title',
22
+ default: 'Delayed Jobs Dashboard'
23
+ )
24
+
25
+ c.model = 'Delayed::Job'
26
+ c.paging = :buffered
27
+ c.editing = :in_form
28
+ c.multi_select = false
29
+
30
+ c.attributes = [
31
+ :id,
32
+ :handler,
33
+ :run_at,
34
+ :locked_at,
35
+ :locked_by,
36
+ :created_at,
37
+ :cron,
38
+ :last_error
39
+ ]
40
+
41
+ c.store_config.merge!(
42
+ sorters: [
43
+ { property: :locked_at, direction: 'DESC' },
44
+ { property: :run_at, direction: 'DESC' }
45
+ ])
46
+
47
+ # c.scope = lambda do |r|
48
+ # r.order('locked_at DESC NULLS LAST')
49
+ # end
50
+ end
51
+
52
+ attribute :locked_at do |c|
53
+ c.sorting_scope = lambda do |relation, dir|
54
+ relation.order("locked_at #{dir} NULLS LAST")
55
+ end
56
+ end
57
+
58
+ def default_context_menu
59
+ []
60
+ end
61
+
62
+ def default_bbar
63
+ []
64
+ end
65
+
66
+ attribute :cron do |c|
67
+ c.width = 400
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,53 @@
1
+ require 'marty/background_job/schedule_jobs_grid'
2
+
3
+ module Marty
4
+ module BackgroundJob
5
+ class ScheduleJobsDashboard < Marty::Form
6
+ include Marty::Extras::Layout
7
+
8
+ def configure(c)
9
+ super
10
+ c.items = [
11
+ :schedule_jobs_grid,
12
+ :schedule_jobs_warnings
13
+ ]
14
+ end
15
+
16
+ def prepare_warnings
17
+ djs = ::Marty::BackgroundJob::FetchMissingInScheduleCronJobs.call
18
+
19
+ messages = djs.map do |dj|
20
+ handler_str = dj.handler[/job_class.*\n/]
21
+ job_class = handler_str.gsub('job_class:', '').strip
22
+
23
+ "#{job_class} with cron #{dj.cron} is present " \
24
+ 'in delayed_jobs table, but is missing in the Dashboard.'
25
+ end
26
+
27
+ messages.join('<br>')
28
+ end
29
+
30
+ client_class do |c|
31
+ c.header = false
32
+ c.defaults = { body_style: 'padding:0px' }
33
+ end
34
+
35
+ component :schedule_jobs_grid do |c|
36
+ c.klass = Marty::BackgroundJob::ScheduleJobsGrid
37
+ c.region = :north
38
+ c.min_height = 500
39
+ end
40
+
41
+ component :schedule_jobs_warnings do |c|
42
+ c.klass = Marty::Panel
43
+ c.title = I18n.t('jobs.schedule_dashboard.warnings')
44
+ c.html = prepare_warnings
45
+ c.min_height = 200
46
+ end
47
+
48
+ def default_bbar
49
+ []
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,136 @@
1
+ module Marty
2
+ module BackgroundJob
3
+ class ScheduleJobsGrid < Marty::Grid
4
+ ACCESSIBLE_BY = [:admin]
5
+
6
+ has_marty_permissions(
7
+ read: ACCESSIBLE_BY,
8
+ create: ACCESSIBLE_BY,
9
+ update: ACCESSIBLE_BY,
10
+ delete: ACCESSIBLE_BY,
11
+ destroy: ACCESSIBLE_BY,
12
+ job_run: ACCESSIBLE_BY,
13
+ edit_window__edit_form__submit: ACCESSIBLE_BY,
14
+ add_window__add_form__submit: ACCESSIBLE_BY
15
+ )
16
+
17
+ def configure(c)
18
+ super
19
+
20
+ c.title ||= I18n.t(
21
+ 'schedule_jobs_dashboard_view_title',
22
+ default: 'Schedule Jobs Dashboard'
23
+ )
24
+
25
+ c.model = 'Marty::BackgroundJob::Schedule'
26
+ c.paging = :buffered
27
+ c.editing = :in_form
28
+ c.multi_select = false
29
+
30
+ c.attributes = [
31
+ :job_class,
32
+ :cron,
33
+ :state
34
+ ]
35
+ end
36
+
37
+ def default_context_menu
38
+ []
39
+ end
40
+
41
+ def default_bbar
42
+ super + [:do_job_run]
43
+ end
44
+
45
+ attribute :job_class do |c|
46
+ c.width = 400
47
+ end
48
+
49
+ attribute :cron do |c|
50
+ c.width = 400
51
+ end
52
+
53
+ attribute :state do |c|
54
+ c.width = 150
55
+ editor_config = {
56
+ trigger_action: :all,
57
+ xtype: :combo,
58
+ store: Marty::BackgroundJob::Schedule::ALL_STATES,
59
+ forceSelection: true,
60
+ }
61
+
62
+ c.column_config = { editor: editor_config }
63
+ c.field_config = editor_config
64
+ end
65
+
66
+ action :do_job_run do |a|
67
+ a.text = 'Run'
68
+ a.tooltip = 'Run'
69
+ a.icon_cls = 'fa fa-play glyph'
70
+ a.disabled = true
71
+ end
72
+
73
+ endpoint :edit_window__edit_form__submit do |params|
74
+ result = super(params)
75
+ next result if result.empty?
76
+
77
+ obj_hash = result.first
78
+
79
+ Marty::BackgroundJob::UpdateSchedule.call(
80
+ id: obj_hash['id'],
81
+ job_class: obj_hash['job_class']
82
+ )
83
+
84
+ result
85
+ end
86
+
87
+ endpoint :add_window__add_form__submit do |params|
88
+ result = super(params)
89
+ next result if result.empty?
90
+
91
+ obj_hash = result.first
92
+
93
+ Marty::BackgroundJob::UpdateSchedule.call(
94
+ id: obj_hash['id'],
95
+ job_class: obj_hash['job_class']
96
+ )
97
+
98
+ result
99
+ end
100
+
101
+ endpoint :multiedit_window__multiedit_form__submit do |_params|
102
+ client.netzke_notify 'Multiediting is disabled for cron schedules'
103
+ end
104
+
105
+ endpoint :destroy do |params|
106
+ res = params.each_with_object({}) do |id, hash|
107
+ job_class = model.find_by(id: id)&.job_class
108
+ result = super([id])
109
+
110
+ # Do nothing If it wasn't destroyed
111
+ next hash.merge(result) unless result[id.to_i] == 'ok'
112
+
113
+ Marty::BackgroundJob::UpdateSchedule.call(
114
+ id: id,
115
+ job_class: job_class
116
+ )
117
+
118
+ hash.merge(result)
119
+ end
120
+
121
+ res
122
+ end
123
+
124
+ endpoint :job_run do
125
+ begin
126
+ s = Marty::BackgroundJob::Schedule.find(client_config['selected'])
127
+ klass = s.job_class
128
+ klass.constantize.new.perform
129
+ rescue StandardError => e
130
+ next client.netzke_notify(e.message)
131
+ end
132
+ client.netzke_notify("#{klass.demodulize} ran successfully.")
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,87 @@
1
+ module Marty
2
+ module BackgroundJob
3
+ class ScheduleJobsLogs < Marty::Grid
4
+ ACCESSIBLE_BY = [:admin]
5
+
6
+ has_marty_permissions(
7
+ read: ACCESSIBLE_BY,
8
+ create: ACCESSIBLE_BY,
9
+ update: ACCESSIBLE_BY,
10
+ delete: ACCESSIBLE_BY,
11
+ destroy: ACCESSIBLE_BY,
12
+ destroy_all: ACCESSIBLE_BY,
13
+ ignore: ACCESSIBLE_BY,
14
+ edit_window__edit_form__submit: ACCESSIBLE_BY,
15
+ add_window__add_form__submit: ACCESSIBLE_BY
16
+ )
17
+
18
+ def configure(c)
19
+ super
20
+
21
+ c.title ||= I18n.t('schedule_jobs_dashboard_view_title', default: "Scheduled Job's Logs")
22
+ c.model = 'Marty::BackgroundJob::Log'
23
+ c.paging = :buffered
24
+ c.editing = :in_form
25
+ c.multi_select = true
26
+
27
+ c.attributes = [
28
+ :job_class,
29
+ :status,
30
+ :error,
31
+ :created_at
32
+ ]
33
+
34
+ c.store_config.merge!(sorters: [{ property: :id, direction: 'DESC' }])
35
+ end
36
+
37
+ def default_context_menu
38
+ []
39
+ end
40
+
41
+ def default_bbar
42
+ [:delete, :destroy_all, :ignore]
43
+ end
44
+
45
+ attribute :job_class do |c|
46
+ c.width = 400
47
+ c.read_only = true
48
+ end
49
+
50
+ attribute :status do |c|
51
+ c.read_only = true
52
+ end
53
+
54
+ attribute :error do |c|
55
+ c.width = 800
56
+ c.read_only = true
57
+ c.getter = ->(record) { record.error.to_json }
58
+ end
59
+
60
+ action :destroy_all do |a|
61
+ a.text = 'Delete all'
62
+ a.tooltip = 'Delete all logs'
63
+ a.icon_cls = 'fa fa-trash glyph'
64
+ end
65
+
66
+ action :ignore do |a|
67
+ a.text = 'Ignore in diag'
68
+ a.tooltip = 'Ignore in diag'
69
+ a.icon_cls = 'fa fa-trash glyph'
70
+ end
71
+
72
+ endpoint :destroy_all do
73
+ Marty::BackgroundJob::Log.delete_all
74
+ client.reload
75
+ end
76
+
77
+ endpoint :ignore do |ids|
78
+ Marty::BackgroundJob::Log.
79
+ where(id: ids).
80
+ where(status: :failure).
81
+ each { |record| record.update(status: :failure_ignore) }
82
+
83
+ client.reload
84
+ end
85
+ end
86
+ end
87
+ end
@@ -1,20 +1,21 @@
1
1
  require 'marty/api_auth_view'
2
2
  require 'marty/api_config_view'
3
3
  require 'marty/api_log_view'
4
+ require 'marty/background_job/delayed_jobs_grid'
5
+ require 'marty/background_job/schedule_jobs_dashboard'
6
+ require 'marty/background_job/schedule_jobs_logs'
4
7
  require 'marty/config_view'
5
8
  require 'marty/data_grid_view'
6
- require 'marty/schedule_jobs_dashboard'
7
- require 'marty/schedule_jobs_logs'
8
9
  require 'marty/data_grid_user_view'
9
10
  require 'marty/import_type_view'
10
11
  require 'marty/new_posting_window'
12
+ require 'marty/notifications/config_view'
13
+ require 'marty/notifications/deliveries_view'
11
14
  require 'marty/posting_window'
12
15
  require 'marty/promise_view'
13
16
  require 'marty/reporting'
14
17
  require 'marty/scripting'
15
18
  require 'marty/user_view'
16
- require 'marty/notifications/config_view'
17
- require 'marty/notifications/deliveries_view'
18
19
 
19
20
  class Marty::MainAuthApp < Marty::AuthApp
20
21
  extend ::Marty::Permissions
@@ -116,6 +117,7 @@ class Marty::MainAuthApp < Marty::AuthApp
116
117
  :bg_status,
117
118
  :bg_stop,
118
119
  :bg_restart,
120
+ :delayed_jobs_grid,
119
121
  :schedule_jobs_dashboard,
120
122
  :schedule_jobs_logs,
121
123
  ]
@@ -298,6 +300,14 @@ class Marty::MainAuthApp < Marty::AuthApp
298
300
  a.disabled = !self.class.has_perm?(:admin)
299
301
  end
300
302
 
303
+ action :delayed_jobs_grid do |a|
304
+ a.text = 'Delayed Jobs Dashboard'
305
+ a.tooltip = 'Show running delayed jobs'
306
+ a.icon_cls = 'fa fa-clock glyph'
307
+ a.disabled = !self.class.has_perm?(:admin)
308
+ a.handler = :netzke_load_component_by_action
309
+ end
310
+
301
311
  action :schedule_jobs_dashboard do |a|
302
312
  a.text = 'Schedule Jobs Dashboard'
303
313
  a.tooltip = 'Edit Delayed Jobs Cron schedules'
@@ -438,9 +448,9 @@ class Marty::MainAuthApp < Marty::AuthApp
438
448
 
439
449
  component :api_config_view
440
450
 
441
- component :schedule_jobs_dashboard
442
-
443
- component :schedule_jobs_logs
451
+ component :delayed_jobs_grid do |c|
452
+ c.klass = ::Marty::BackgroundJob::DelayedJobsGrid
453
+ end
444
454
 
445
455
  component :config_view
446
456
 
@@ -472,6 +482,14 @@ class Marty::MainAuthApp < Marty::AuthApp
472
482
 
473
483
  component :reporting
474
484
 
485
+ component :schedule_jobs_dashboard do |c|
486
+ c.klass = ::Marty::BackgroundJob::ScheduleJobsDashboard
487
+ end
488
+
489
+ component :schedule_jobs_logs do |c|
490
+ c.klass = ::Marty::BackgroundJob::ScheduleJobsLogs
491
+ end
492
+
475
493
  component :scripting do |c|
476
494
  c.allow_edit = self.class.has_scripting_perm?
477
495
  end
@@ -56,7 +56,7 @@ class Marty::DataConversion
56
56
  # Dates are kept as float in Google spreadsheets. Need to
57
57
  # convert them to dates.
58
58
  begin
59
- FLOAT_PAT.match?(v) ? EXCEL_START_DATE + v.to_f :
59
+ FLOAT_PAT.match?(v.to_s) ? EXCEL_START_DATE + v.to_f :
60
60
  Mcfly.is_infinity(v) ? 'infinity' : v.to_date
61
61
  rescue StandardError => e
62
62
  raise "date conversion failed for #{v.inspect}}"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Marty
4
- VERSION = '8.3.1'
4
+ VERSION = '8.4.1'
5
5
  end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Delayed Jobs Dashboard', js: true do
4
+ before do
5
+ Delayed::Job.delete_all
6
+ populate_test_users
7
+ end
8
+
9
+ context 'as dev' do
10
+ before do
11
+ log_in_as('dev1')
12
+ wait_for_ajax
13
+ press('System')
14
+ press('Background Jobs')
15
+ press('Schedule Jobs Dashboard')
16
+ wait_for_ajax
17
+ end
18
+
19
+ it 'access denied' do
20
+ expect(page).to_not have_content 'Schedule Jobs Dashboard'
21
+ end
22
+ end
23
+
24
+ context 'as admin' do
25
+ let(:jobs_view) { netzke_find('delayed_jobs_grid') }
26
+
27
+ let!(:schedule) do
28
+ ['TestJob', 'Test2Job', 'TestFailingJob'].each do |klass_name|
29
+ Marty::BackgroundJob::Schedule.create(
30
+ job_class: klass_name,
31
+ cron: '0 0 * * *',
32
+ state: 'on'
33
+ ).tap do |job|
34
+ Marty::BackgroundJob::UpdateSchedule.call(
35
+ id: job.id,
36
+ job_class: job.job_class
37
+ )
38
+ end
39
+ end
40
+ end
41
+
42
+ let(:time1) { 10.hours.ago }
43
+
44
+ let(:time2) { 20.hours.ago }
45
+
46
+ before do
47
+ @djs = Delayed::Job.all
48
+ @djs.first.update!(locked_at: time1)
49
+ @djs.last.update!(locked_at: time2)
50
+
51
+ log_in_as('admin1')
52
+ wait_for_ajax
53
+ press('System')
54
+ press('Background Jobs')
55
+ press('Delayed Jobs Dashboard')
56
+
57
+ wait_for_ajax
58
+
59
+ expect(page).to have_content 'Delayed Jobs Dashboard'
60
+ end
61
+
62
+ it 'shows delayed jobs' do
63
+ expect(jobs_view.row_count).to eq @djs.size
64
+ expect(jobs_view.row_count).to eq 3
65
+ locked_at = jobs_view.get_col_vals('locked_at', 3, 0, false).map do |str|
66
+ next unless str
67
+
68
+ Time.zone.parse(str).to_s
69
+ end
70
+
71
+ expect(locked_at).to eq(
72
+ [
73
+ time1.to_s,
74
+ time2.to_s,
75
+ nil
76
+ ]
77
+ )
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ module Marty
4
+ describe DataConversion do
5
+ describe '#convert' do
6
+ describe 'date' do
7
+ let(:date) { 1.day.ago.to_date }
8
+
9
+ it 'converts float strings to date' do
10
+ res = described_class.convert('40000.0', :date)
11
+ expect(res).to eq Date.new(2009, 7, 6)
12
+ end
13
+
14
+ it 'converts date to date' do
15
+ res = described_class.convert(date, :date)
16
+ expect(res).to eq date
17
+ end
18
+
19
+ it 'converts infinity' do
20
+ ['Infinity', 'infinity', ::Float::INFINITY].each do |value|
21
+ res = described_class.convert(value, :date)
22
+ expect(res).to eq 'infinity'
23
+ end
24
+ end
25
+
26
+ it 'raises error if the value is not valid' do
27
+ expect { described_class.convert(true, :date) }.
28
+ to raise_error(/date conversion failed for true/)
29
+ end
30
+ end
31
+
32
+ describe 'boolean' do
33
+ it 'converts true' do
34
+ ['true', '1', 'y', 't'].each do |value|
35
+ res = described_class.convert(value, :boolean)
36
+ expect(res).to eq true
37
+ end
38
+ end
39
+
40
+ it 'converts false' do
41
+ ['false', '0', 'n', 'f'].each do |value|
42
+ res = described_class.convert(value, :boolean)
43
+ expect(res).to eq false
44
+ end
45
+ end
46
+
47
+ it 'raises error if the value is not valid' do
48
+ expect { described_class.convert(1.day.ago, :boolean) }.
49
+ to raise_error(/unknown boolean/)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marty
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.3.1
4
+ version: 8.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arman Bostani
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2019-12-03 00:00:00.000000000 Z
17
+ date: 2019-12-05 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: actioncable
@@ -310,6 +310,12 @@ files:
310
310
  - app/components/marty/api_log_view.rb
311
311
  - app/components/marty/auth_app.rb
312
312
  - app/components/marty/auth_app/client/auth_app.js
313
+ - app/components/marty/background_job/delayed_jobs_grid.rb
314
+ - app/components/marty/background_job/schedule_jobs_dashboard.rb
315
+ - app/components/marty/background_job/schedule_jobs_grid.rb
316
+ - app/components/marty/background_job/schedule_jobs_grid/client/schedule_jobs_grid.js
317
+ - app/components/marty/background_job/schedule_jobs_logs.rb
318
+ - app/components/marty/background_job/schedule_jobs_logs/client/schedule_jobs_logs.js
313
319
  - app/components/marty/base_rule_view.rb
314
320
  - app/components/marty/base_rule_view/client/base_rule_view.js
315
321
  - app/components/marty/config_view.rb
@@ -356,11 +362,6 @@ files:
356
362
  - app/components/marty/report_select/client/report_select.js
357
363
  - app/components/marty/reporting.rb
358
364
  - app/components/marty/reporting/client/reporting.js
359
- - app/components/marty/schedule_jobs_dashboard.rb
360
- - app/components/marty/schedule_jobs_grid.rb
361
- - app/components/marty/schedule_jobs_grid/client/schedule_jobs_grid.js
362
- - app/components/marty/schedule_jobs_logs.rb
363
- - app/components/marty/schedule_jobs_logs/client/schedule_jobs_logs.js
364
365
  - app/components/marty/script_form.rb
365
366
  - app/components/marty/script_form/client/script_form.js
366
367
  - app/components/marty/script_grid.rb
@@ -1695,6 +1696,7 @@ files:
1695
1696
  - spec/features/data_blame_report_spec.rb
1696
1697
  - spec/features/data_grid_spec.rb
1697
1698
  - spec/features/data_import_spec.rb
1699
+ - spec/features/delayed_jobs_grid_spec.rb
1698
1700
  - spec/features/endpoint_access.rb
1699
1701
  - spec/features/enum_spec.rb
1700
1702
  - spec/features/enum_values_report_spec.rb
@@ -1737,6 +1739,7 @@ files:
1737
1739
  - spec/job_helper.rb
1738
1740
  - spec/jobs/cron_job_spec.rb
1739
1741
  - spec/lib/data_blame_spec.rb
1742
+ - spec/lib/data_conversion_spec.rb
1740
1743
  - spec/lib/data_exporter_spec.rb
1741
1744
  - spec/lib/data_importer_spec.rb
1742
1745
  - spec/lib/delorean_query_spec.rb
@@ -1,52 +0,0 @@
1
- require 'marty/schedule_jobs_grid'
2
-
3
- class Marty::ScheduleJobsDashboard < Marty::Form
4
- include Marty::Extras::Layout
5
-
6
- def configure(c)
7
- super
8
- c.items = [
9
- :schedule_jobs_grid,
10
- :schedule_jobs_warnings
11
- ]
12
- end
13
-
14
- def prepare_warnings
15
- djs = ::Marty::BackgroundJob::FetchMissingInScheduleCronJobs.call
16
-
17
- messages = djs.map do |dj|
18
- handler_str = dj.handler[/job_class.*\n/]
19
- job_class = handler_str.gsub('job_class:', '').strip
20
-
21
- "#{job_class} with cron #{dj.cron} is present in delayed_jobs table, " \
22
- 'but is missing in the Dashboard.'
23
- end
24
-
25
- messages.join('<br>')
26
- end
27
-
28
- client_class do |c|
29
- c.header = false
30
- # c.layout = :border
31
- c.defaults = { body_style: 'padding:0px' }
32
- end
33
-
34
- component :schedule_jobs_grid do |c|
35
- c.klass = Marty::ScheduleJobsGrid
36
- c.region = :north
37
- c.min_height = 500
38
- end
39
-
40
- component :schedule_jobs_warnings do |c|
41
- c.klass = Marty::Panel
42
- c.title = I18n.t('jobs.schedule_dashboard.warnings')
43
- c.html = prepare_warnings
44
- c.min_height = 200
45
- end
46
-
47
- def default_bbar
48
- []
49
- end
50
- end
51
-
52
- ScheduleJobsDashboard = Marty::ScheduleJobsDashboard
@@ -1,118 +0,0 @@
1
- class Marty::ScheduleJobsGrid < Marty::Grid
2
- ACCESSIBLE_BY = [:admin]
3
-
4
- has_marty_permissions(
5
- read: ACCESSIBLE_BY,
6
- create: ACCESSIBLE_BY,
7
- update: ACCESSIBLE_BY,
8
- delete: ACCESSIBLE_BY,
9
- destroy: ACCESSIBLE_BY,
10
- job_run: ACCESSIBLE_BY,
11
- edit_window__edit_form__submit: ACCESSIBLE_BY,
12
- add_window__add_form__submit: ACCESSIBLE_BY
13
- )
14
-
15
- def configure(c)
16
- super
17
-
18
- c.title ||= I18n.t('schedule_jobs_dashboard_view_title', default: 'Schedule Jobs Dashboard')
19
- c.model = 'Marty::BackgroundJob::Schedule'
20
- c.paging = :buffered
21
- c.editing = :in_form
22
- c.multi_select = false
23
-
24
- c.attributes = [
25
- :job_class,
26
- :cron,
27
- :state
28
- ]
29
- end
30
-
31
- def default_context_menu
32
- []
33
- end
34
-
35
- def default_bbar
36
- super + [:do_job_run]
37
- end
38
-
39
- attribute :job_class do |c|
40
- c.width = 400
41
- end
42
-
43
- attribute :cron do |c|
44
- c.width = 400
45
- end
46
-
47
- attribute :state do |c|
48
- c.width = 150
49
- editor_config = {
50
- trigger_action: :all,
51
- xtype: :combo,
52
- store: Marty::BackgroundJob::Schedule::ALL_STATES,
53
- forceSelection: true,
54
- }
55
-
56
- c.column_config = { editor: editor_config }
57
- c.field_config = editor_config
58
- end
59
-
60
- action :do_job_run do |a|
61
- a.text = 'Run'
62
- a.tooltip = 'Run'
63
- a.icon_cls = 'fa fa-play glyph'
64
- a.disabled = true
65
- end
66
-
67
- endpoint :edit_window__edit_form__submit do |params|
68
- result = super(params)
69
- next result if result.empty?
70
-
71
- obj_hash = result.first
72
- Marty::BackgroundJob::UpdateSchedule.call(id: obj_hash['id'], job_class: obj_hash['job_class'])
73
-
74
- result
75
- end
76
-
77
- endpoint :add_window__add_form__submit do |params|
78
- result = super(params)
79
- next result if result.empty?
80
-
81
- obj_hash = result.first
82
- Marty::BackgroundJob::UpdateSchedule.call(id: obj_hash['id'], job_class: obj_hash['job_class'])
83
-
84
- result
85
- end
86
-
87
- endpoint :multiedit_window__multiedit_form__submit do |_params|
88
- client.netzke_notify 'Multiediting is disabled for cron schedules'
89
- end
90
-
91
- endpoint :destroy do |params|
92
- res = params.each_with_object({}) do |id, hash|
93
- job_class = model.find_by(id: id)&.job_class
94
- result = super([id])
95
-
96
- # Do nothing If it wasn't destroyed
97
- next hash.merge(result) unless result[id.to_i] == 'ok'
98
-
99
- Marty::BackgroundJob::UpdateSchedule.call(id: id, job_class: job_class)
100
- hash.merge(result)
101
- end
102
-
103
- res
104
- end
105
-
106
- endpoint :job_run do
107
- begin
108
- s = Marty::BackgroundJob::Schedule.find(client_config['selected'])
109
- klass = s.job_class
110
- klass.constantize.new.perform
111
- rescue StandardError => e
112
- next client.netzke_notify(e.message)
113
- end
114
- client.netzke_notify("#{klass.demodulize} ran successfully.")
115
- end
116
- end
117
-
118
- ScheduleJobsGrid = Marty::ScheduleJobsGrid
@@ -1,85 +0,0 @@
1
- class Marty::ScheduleJobsLogs < Marty::Grid
2
- ACCESSIBLE_BY = [:admin]
3
-
4
- has_marty_permissions(
5
- read: ACCESSIBLE_BY,
6
- create: ACCESSIBLE_BY,
7
- update: ACCESSIBLE_BY,
8
- delete: ACCESSIBLE_BY,
9
- destroy: ACCESSIBLE_BY,
10
- destroy_all: ACCESSIBLE_BY,
11
- ignore: ACCESSIBLE_BY,
12
- edit_window__edit_form__submit: ACCESSIBLE_BY,
13
- add_window__add_form__submit: ACCESSIBLE_BY
14
- )
15
-
16
- def configure(c)
17
- super
18
-
19
- c.title ||= I18n.t('schedule_jobs_dashboard_view_title', default: "Scheduled Job's Logs")
20
- c.model = 'Marty::BackgroundJob::Log'
21
- c.paging = :buffered
22
- c.editing = :in_form
23
- c.multi_select = true
24
-
25
- c.attributes = [
26
- :job_class,
27
- :status,
28
- :error,
29
- :created_at
30
- ]
31
-
32
- c.store_config.merge!(sorters: [{ property: :id, direction: 'DESC' }])
33
- end
34
-
35
- def default_context_menu
36
- []
37
- end
38
-
39
- def default_bbar
40
- [:delete, :destroy_all, :ignore]
41
- end
42
-
43
- attribute :job_class do |c|
44
- c.width = 400
45
- c.read_only = true
46
- end
47
-
48
- attribute :status do |c|
49
- c.read_only = true
50
- end
51
-
52
- attribute :error do |c|
53
- c.width = 800
54
- c.read_only = true
55
- c.getter = ->(record) { record.error.to_json }
56
- end
57
-
58
- action :destroy_all do |a|
59
- a.text = 'Delete all'
60
- a.tooltip = 'Delete all logs'
61
- a.icon_cls = 'fa fa-trash glyph'
62
- end
63
-
64
- action :ignore do |a|
65
- a.text = 'Ignore in diag'
66
- a.tooltip = 'Ignore in diag'
67
- a.icon_cls = 'fa fa-trash glyph'
68
- end
69
-
70
- endpoint :destroy_all do
71
- Marty::BackgroundJob::Log.delete_all
72
- client.reload
73
- end
74
-
75
- endpoint :ignore do |ids|
76
- Marty::BackgroundJob::Log.
77
- where(id: ids).
78
- where(status: :failure).
79
- each { |record| record.update(status: :failure_ignore) }
80
-
81
- client.reload
82
- end
83
- end
84
-
85
- ScheduleJobsLogs = Marty::ScheduleJobsLogs