marty 2.1.5 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +4 -4
  4. data/app/components/marty/auth_app.rb +3 -3
  5. data/app/components/marty/auth_app/client/auth_app.js +1 -3
  6. data/app/components/marty/base_rule_view.rb +32 -20
  7. data/app/components/marty/data_grid_view.rb +3 -3
  8. data/app/components/marty/event_view.rb +0 -5
  9. data/app/components/marty/form.rb +8 -1
  10. data/app/components/marty/form/client/form.css +3 -0
  11. data/app/components/marty/grid.rb +174 -33
  12. data/app/components/marty/import_view.rb +151 -0
  13. data/app/components/marty/main_auth_app.rb +28 -28
  14. data/app/components/marty/mcfly_grid_panel.rb +1 -1
  15. data/app/components/marty/new_posting_form.rb +3 -3
  16. data/app/components/marty/new_posting_window.rb +5 -6
  17. data/app/components/marty/posting_grid.rb +2 -2
  18. data/app/components/marty/posting_window.rb +1 -2
  19. data/app/components/marty/promise_view.rb +11 -6
  20. data/app/components/marty/record_form_window.rb +1 -1
  21. data/app/components/marty/report_form.rb +4 -4
  22. data/app/components/marty/report_select.rb +1 -1
  23. data/app/components/marty/script_form.rb +4 -4
  24. data/app/components/marty/script_grid.rb +2 -2
  25. data/app/components/marty/script_tester.rb +1 -1
  26. data/app/components/marty/simple_app.rb +1 -2
  27. data/app/components/marty/simple_app/client/statusbar_ext.js +1 -1
  28. data/app/components/marty/tag_grid.rb +1 -1
  29. data/app/components/marty/user_view.rb +5 -5
  30. data/app/controllers/marty/job_controller.rb +5 -1
  31. data/app/models/marty/base.rb +0 -15
  32. data/app/models/marty/data_grid.rb +1 -1
  33. data/app/models/marty/log.rb +1 -0
  34. data/app/models/marty/promise.rb +27 -84
  35. data/app/models/marty/vw_promise.rb +72 -0
  36. data/app/views/layouts/marty/application.html.erb +6 -3
  37. data/config/locales/en.yml +4 -0
  38. data/db/migrate/410_jsonb_promise_result.rb +9 -0
  39. data/db/migrate/411_create_vw_promises.rb +26 -0
  40. data/lib/marty/data_change.rb +3 -4
  41. data/lib/marty/data_conversion.rb +1 -2
  42. data/lib/marty/data_importer.rb +13 -14
  43. data/lib/marty/javascript/{overrides.js → grid_view_in_form.js} +10 -6
  44. data/lib/marty/mcfly_model.rb +13 -20
  45. data/lib/marty/monkey.rb +33 -40
  46. data/lib/marty/promise_job.rb +8 -2
  47. data/lib/marty/promise_proxy.rb +6 -11
  48. data/lib/marty/rule_script_set.rb +5 -2
  49. data/lib/marty/version.rb +1 -1
  50. data/marty.gemspec +1 -1
  51. data/other/marty/diagnostic/delayed_job_workers.rb +8 -5
  52. data/spec/controllers/job_controller_spec.rb +34 -15
  53. data/spec/dummy/app/components/gemini/my_rule_view.rb +6 -0
  54. data/spec/dummy/app/models/gemini/helper.rb +2 -2
  55. data/spec/dummy/config/application.rb +1 -1
  56. data/spec/features/rule_spec.rb +100 -5
  57. data/spec/fixtures/csv/rule/MyRule.csv +1 -1
  58. data/spec/job_helper.rb +2 -4
  59. data/spec/lib/data_importer_spec.rb +10 -10
  60. data/spec/lib/delorean_query_spec.rb +13 -2
  61. data/spec/lib/logger_spec.rb +16 -14
  62. data/spec/models/data_grid_spec.rb +4 -10
  63. data/spec/models/promise_spec.rb +8 -8
  64. data/spec/models/rule_spec.rb +7 -7
  65. data/spec/spec_helper.rb +1 -1
  66. metadata +10 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fbcd682cde37ed604e64d620393437a1724e9f30
4
- data.tar.gz: d3473e2724bd6e74973f3c8747e3a40f680ccda1
3
+ metadata.gz: 8dc054b69b36c3f88865983281fb580a69870469
4
+ data.tar.gz: e09a7b2ec29e732f516d803fc9c3acec66db98c9
5
5
  SHA512:
6
- metadata.gz: 021540ab0f6c04931ee8aa2a343dbf1f9f16bbce2b2d26a5ce245020afc5a4573acaca71ff9a8dd32abde5449afb731e582ba2cf87f1ae7b2d2c0f7832728f01
7
- data.tar.gz: cd4eadcc498283fa179c04ca61f2b36e5b9cbab57755d47abbd06a3d147525d8c2e831f18eec18d5fcd57e72cffc6dd63d463c7b5d6b49adeb2fef6599d2a00e
6
+ metadata.gz: 647481fb469e7dc0a979c792eff8dcfab5367bd44e8df5f28cefde2e781c61e16730e8a29262c2cda1f36f04ee82ea18d87000014705df8126b3d4c26dd04512
7
+ data.tar.gz: dd873fbce7126aa5ae3c947bc091edece040a8854be98be0991c03cdb32dedd4523c2978d8ea7c6c44d25c4f897bece30fe35b9cdcb79ffafb99cdcab1ecc1d0
data/Gemfile CHANGED
@@ -28,6 +28,8 @@ group :development, :test do
28
28
  gem 'mcfly'
29
29
  gem 'netzke', '6.5.0.0'
30
30
 
31
+ # gem 'delorean_lang', path: File.expand_path('../../delorean', __FILE__)
32
+
31
33
  # gem 'marty_rspec', path: File.expand_path('../../marty_rspec', __FILE__)
32
34
  gem 'marty_rspec'
33
35
  end
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- marty (2.1.5)
4
+ marty (2.3.0)
5
5
  aws-sigv4 (~> 1.0, >= 1.0.2)
6
6
  axlsx (= 3.0.0pre)
7
7
  coderay
8
- delorean_lang (~> 0.3.37)
8
+ delorean_lang (~> 0.4.00)
9
9
  json-schema
10
10
  mcfly (= 0.0.20)
11
11
  net-ldap (= 0.12.1)
@@ -93,7 +93,7 @@ GEM
93
93
  delayed_job_active_record (4.1.2)
94
94
  activerecord (>= 3.0, < 5.2)
95
95
  delayed_job (>= 3.0, < 5)
96
- delorean_lang (0.3.37)
96
+ delorean_lang (0.4.00)
97
97
  activerecord (>= 3.2)
98
98
  treetop (~> 1.5)
99
99
  diff-lcs (1.3)
@@ -255,4 +255,4 @@ DEPENDENCIES
255
255
  timecop
256
256
 
257
257
  BUNDLED WITH
258
- 1.16.1
258
+ 1.16.3
@@ -29,12 +29,12 @@ class Marty::AuthApp < Marty::SimpleApp
29
29
  end
30
30
 
31
31
  action :sign_in do |c|
32
- c.icon = :door_in
32
+ c.icon_cls = "fa fa-sign-in-alt gylph"
33
33
  end
34
34
 
35
35
  action :sign_out do |c|
36
- c.icon = :door_out
37
- c.text = "Sign out #{Mcfly.whodunnit.name}" if Mcfly.whodunnit
36
+ c.icon_cls = "fa fa-sign-out-alt gylph"
37
+ c.text = "Sign out #{Mcfly.whodunnit.name}" if Mcfly.whodunnit
38
38
  end
39
39
 
40
40
  endpoint :sign_in do |params|
@@ -2,8 +2,6 @@
2
2
  netzkeOnSignIn: function() {
3
3
  var me = this;
4
4
  this.signinWin = this.signinWin || Ext.create('Ext.Window', {
5
- width: 300,
6
- height: 150,
7
5
  modal: true,
8
6
  layout: 'fit',
9
7
 
@@ -47,7 +45,7 @@
47
45
  items: {
48
46
  xtype: 'form',
49
47
  defaultType: 'textfield',
50
- bodyPadding: '15px 0px 0px 10px',
48
+ bodyPadding: '15px 15px 0px 10px',
51
49
  defaults: {
52
50
  listeners: {
53
51
  specialkey: function (field, event) {
@@ -47,37 +47,46 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
47
47
  end
48
48
  end
49
49
 
50
- def self.simple_to_hashstr(s)
51
- pairs = []
52
- keys = Set.new
50
+ def self.simple_to_hash(s)
51
+ result = {}
52
+ save_linenos = {}
53
+ last_key = nil
53
54
  s.lines.each.with_index(1) do |line, idx|
54
55
  next if /\A\s*\z/.match(line)
55
56
  line.chomp!
56
57
  begin
57
- m = /\A\s*([a-z0-9][a-z0-9_]*)\s*=\s*(.*)\s*\z/.match(line)
58
- k, v = m[1], m[2]
59
- v = [v].to_json[1..-2]
60
- raise DupKeyError.new(k, idx) if keys.include?(k)
61
- raise unless /\A['"].*['"]\z/.match(v)
62
- keys << k
58
+ m = /\A\s*([a-z][a-z0-9_]*)\s*=\s*(.*)\s*\z/.match(line)
59
+ if m
60
+ k, v = m[1], m[2]
61
+ raise DupKeyError.new(k, idx) if result.keys.include?(k)
62
+ save_linenos[k] = idx
63
+ result[k] = v
64
+ last_key = k
65
+ else
66
+ raise unless last_key
67
+ result[last_key] += "\n" + line.strip
68
+ end
63
69
  rescue DupKeyError => e
64
70
  raise
65
71
  rescue => e
66
72
  raise "syntax error on line #{idx}"
67
73
  end
68
- pairs << [k, v]
69
74
  end
70
-
71
- kvs = pairs.map { |k, v| %Q("#{k}":#{v}) }.join(",")
72
- "{#{kvs}}"
75
+ result
73
76
  end
74
77
 
75
78
  def self.hash_to_simple(h)
76
79
  return unless h && h.present?
77
- fmt = '%-' + h.keys.map(&:length).max.to_s + 's = %s'
80
+ lhs_wid = h.keys.map(&:length).max
81
+ fmt = "%-#{lhs_wid}s = %s"
82
+ result = []
78
83
  h.map do |k, vstr|
79
- fmt % [k, vstr]
80
- end.join("\n") || ''
84
+ vlines = vstr.lines.map(&:chomp)
85
+ fst = vlines.shift
86
+ result << fmt % [k, fst]
87
+ vlines.each {|l| result << " "*(lhs_wid+3) + l}
88
+ end
89
+ result.join("\n")
81
90
  end
82
91
 
83
92
  def jsonb_getter(c)
@@ -94,12 +103,15 @@ class Marty::BaseRuleView < Marty::McflyGridPanel
94
103
  return r.send(msg, nil) if v.blank?
95
104
 
96
105
  begin
97
- v = ActiveSupport::JSON.decode(
98
- Marty::BaseRuleView.simple_to_hashstr(v))
106
+ final = Marty::BaseRuleView.simple_to_hash(v)
99
107
  rescue => e
100
- v = { "~~ERROR~~": e.message }
108
+ final = { "~~ERROR~~": e.message }
101
109
  end
102
- r.send(msg, v)
110
+
111
+ # ActiveRecord ignores change in json key order
112
+ r.send("#{c}_will_change!") if r[c.to_s].to_a != final.to_a
113
+
114
+ r.send(msg, final)
103
115
  }
104
116
  end
105
117
 
@@ -114,9 +114,9 @@ module Marty; class DataGridView < McflyGridPanel
114
114
  end
115
115
 
116
116
  action :show_grid do |a|
117
- a.text = "Show Grid"
118
- a.icon = :application_view_detail
119
- a.handler = :netzke_show_grid
117
+ a.text = "Show Grid"
118
+ a.icon_cls = "fa fa-th-large glyph"
119
+ a.handler = :netzke_show_grid
120
120
  end
121
121
 
122
122
  endpoint :show_grid do |params|
@@ -33,11 +33,6 @@ class Marty::EventView < Marty::Grid
33
33
  Marty::Event.cleanup
34
34
  end
35
35
 
36
- action :delete do |a|
37
- super(a)
38
- a.icon = :user_delete
39
- end
40
-
41
36
  def default_context_menu
42
37
  []
43
38
  end
@@ -1,4 +1,11 @@
1
- # Netzke Form with Marty permissions
2
1
  class Marty::Form < Netzke::Form::Base
3
2
  extend ::Marty::Permissions
3
+
4
+ client_styles do |c|
5
+ c.require :form
6
+ end
7
+
8
+ def add_cls_to_fields items
9
+ items.map{|i| i + {'label_cls' => 'marty-form-field-label'}}
10
+ end
4
11
  end
@@ -0,0 +1,3 @@
1
+ .marty-form-field-label {
2
+ padding-left: 10px;
3
+ }
@@ -1,27 +1,88 @@
1
1
  class Marty::Grid < ::Netzke::Grid::Base
2
-
3
2
  extend ::Marty::Permissions
4
3
 
5
4
  has_marty_permissions read: :any
6
5
 
7
- def configure_form_window(c)
8
- super
9
-
10
- c.klass = Marty::RecordFormWindow
11
-
12
- # Fix Add in form/Edit in form modal popup width
13
- # Netzke 0.10.1 defaults width to 80% of screen which is too wide
14
- # for a form where the fields are stacked top to bottom
15
- # Netzke 0.8.4 defaulted width to 400px - let's make it a bit wider
16
- c.width = 475
6
+ # parent grid is the grid in which child/linked_components is defined
7
+ # child components are components dependent on the selected parent row
8
+ # linked components will update whenever the parent is updated
9
+ def initialize args, kwargs
10
+ super(args, kwargs)
11
+ client_config[:child_components] = child_components || []
12
+ client_config[:linked_components] = linked_components || []
17
13
  end
18
14
 
19
15
  client_class do |c|
20
- # For some reason the grid update function was removed in Netzke
21
- # 0.10.1. So, add it here.
22
- c.cm_update = l(<<-JS)
16
+ c.init_component = l(<<-JS)
23
17
  function() {
24
- this.store.load();
18
+ this.dockedItems = this.dockedItems || [];
19
+ if (this.paging == 'pagination') {
20
+ this.dockedItems.push({
21
+ xtype: 'pagingtoolbar',
22
+ dock: 'bottom',
23
+ layout: {overflowHandler: 'Menu'},
24
+ listeners: {
25
+ 'beforechange': this.disableDirtyPageWarning ? {} : {
26
+ fn: this.netzkeBeforePageChange, scope: this
27
+ }
28
+ },
29
+ store: this.store,
30
+ items: this.bbar && ["-"].concat(this.bbar)
31
+ });
32
+ } else if (this.bbar) {
33
+ this.dockedItems.push({
34
+ xtype: 'toolbar',
35
+ dock: 'bottom',
36
+ layout: {overflowHandler: 'Menu'},
37
+ items: this.bbar
38
+ });
39
+ }
40
+
41
+ // block creation of toolbars in parent
42
+ delete this.bbar;
43
+ var paging = this.paging
44
+ this.paging = false;
45
+ this.callParent();
46
+ this.paging = paging
47
+
48
+ var me = this;
49
+
50
+ var children = me.serverConfig.child_components || [];
51
+ me.getSelectionModel().on(
52
+ 'selectionchange',
53
+ function(m) {
54
+ var has_sel = m.hasSelection();
55
+ var rid = has_sel ?
56
+ me.getSelectionModel().getSelection()[0].getId() : null
57
+
58
+ me.serverConfig.selected = rid;
59
+
60
+ for (var key in me.actions) {
61
+ // hacky -- assumes our functions start with "do"
62
+ if (key.substring(0, 2) == "do") {
63
+ me.actions[key].setDisabled(!has_sel);
64
+ }
65
+ }
66
+
67
+ for (var child of children) {
68
+ var comp = me.netzkeGetComponentFromParent(child);
69
+ if (comp) {
70
+ comp.serverConfig.parent_id = rid;
71
+ if (comp.reload) { comp.reload() }
72
+ }
73
+ }
74
+ });
75
+
76
+ var store = me.getStore();
77
+ var linked = me.serverConfig.linked_components || [];
78
+ for (var event of ['update', 'netzkerefresh']) {
79
+ store.on(event, function() {
80
+ for (var link of linked) {
81
+ var comp = me.netzkeGetComponentFromParent(link);
82
+ if (comp && comp.reload) { comp.reload() }
83
+ }
84
+ }, this);
85
+ }
25
86
  }
26
87
  JS
27
88
 
@@ -40,21 +101,40 @@ class Marty::Grid < ::Netzke::Grid::Base
40
101
  }
41
102
  JS
42
103
 
104
+ c.reload = l(<<-JS)
105
+ function(opts={}) {
106
+ this.netzkeReloadStore(opts);
107
+ }
108
+ JS
109
+
110
+ c.reload_all = l(<<-JS)
111
+ function() {
112
+ var me = this;
113
+ var children = me.serverConfig.child_components || [];
114
+ this.store.reload();
115
+ for (child of children) {
116
+ var comp = me.netzkeGetComponentFromParent(child);
117
+ if (comp && comp.reload) { comp.reload() }
118
+ }
119
+ }
120
+ JS
121
+
43
122
  c.clear_filters = l(<<-JS)
44
123
  function() {
45
124
  this.filters.clearFilters();
46
125
  }
47
126
  JS
48
- end
49
127
 
50
- component :view_window do |c|
51
- configure_form_window(c)
52
- c.excluded = !allowed_to?(:read)
53
- c.items = [:view_form]
54
- c.title = I18n.t('netzke.grid.base.view_record',
55
- model: model.model_name.human)
128
+ c.netzkeGetComponentFromParent = l(<<-JS)
129
+ function(component_path) {
130
+ return this.netzkeGetParentComponent().netzkeGetComponent(component_path);
131
+ }
132
+ JS
133
+
56
134
  end
57
135
 
136
+ ######################################################################
137
+
58
138
  def class_can?(op)
59
139
  self.class.can_perform_action?(op)
60
140
  end
@@ -78,20 +158,81 @@ class Marty::Grid < ::Netzke::Grid::Base
78
158
  false
79
159
  end
80
160
 
81
- # To add :clear_filters to your app's bbar, add the following lines:
82
- # def default_bbar
83
- # [:clear_filters] + super
84
- # end
85
-
86
- action :clear_filters do |a|
87
- a.text = "X"
88
- a.tooltip = "Clear filters"
89
- a.handler = :clear_filters
90
- end
91
-
92
161
  def get_json_sorter(json_col, field)
93
162
  lambda do |r, dir|
94
163
  r.order("#{json_col} ->> '#{field}' " + dir.to_s)
95
164
  end
96
165
  end
166
+
167
+ action :clear_filters do |a|
168
+ a.tooltip = "Clear filters"
169
+ a.handler = :clear_filters
170
+ a.icon_cls = "fa fa-minus glyph"
171
+ end
172
+
173
+ # cosmetic changes
174
+
175
+ action :add do |a|
176
+ super(a)
177
+ a.icon = nil
178
+ a.icon_cls = "fa fa-plus glyph"
179
+ end
180
+
181
+ action :add_in_form do |a|
182
+ super(a)
183
+ a.icon = nil
184
+ a.icon_cls = "fa fa-plus-square glyph"
185
+ end
186
+
187
+ action :edit do |a|
188
+ super(a)
189
+ a.icon = nil
190
+ a.icon_cls = "fa fa-edit glyph"
191
+ end
192
+
193
+ action :edit_in_form do |a|
194
+ super(a)
195
+ a.icon = nil
196
+ a.icon_cls = "fa fa-pen-square glyph"
197
+ end
198
+
199
+ action :delete do |a|
200
+ super(a)
201
+ a.icon = nil
202
+ a.icon_cls = "fa fa-trash glyph"
203
+ end
204
+
205
+ action :apply do |a|
206
+ super(a)
207
+ a.icon = nil
208
+ a.icon_cls = "fa fa-check glyph"
209
+ end
210
+
211
+ def child_components
212
+ []
213
+ end
214
+
215
+ def linked_components
216
+ []
217
+ end
218
+
219
+ def configure_form_window(c)
220
+ super
221
+
222
+ c.klass = Marty::RecordFormWindow
223
+
224
+ # Fix Add in form/Edit in form modal popup width
225
+ # Netzke 0.10.1 defaults width to 80% of screen which is too wide
226
+ # for a form where the fields are stacked top to bottom
227
+ # Netzke 0.8.4 defaulted width to 400px - let's make it a bit wider
228
+ c.width = 475
229
+ end
230
+
231
+ component :view_window do |c|
232
+ configure_form_window(c)
233
+ c.excluded = !allowed_to?(:read)
234
+ c.items = [:view_form]
235
+ c.title = I18n.t('netzke.grid.base.view_record',
236
+ model: model.model_name.human)
237
+ end
97
238
  end