marty 2.1.5 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +4 -4
- data/app/components/marty/auth_app.rb +3 -3
- data/app/components/marty/auth_app/client/auth_app.js +1 -3
- data/app/components/marty/base_rule_view.rb +32 -20
- data/app/components/marty/data_grid_view.rb +3 -3
- data/app/components/marty/event_view.rb +0 -5
- data/app/components/marty/form.rb +8 -1
- data/app/components/marty/form/client/form.css +3 -0
- data/app/components/marty/grid.rb +174 -33
- data/app/components/marty/import_view.rb +151 -0
- data/app/components/marty/main_auth_app.rb +28 -28
- data/app/components/marty/mcfly_grid_panel.rb +1 -1
- data/app/components/marty/new_posting_form.rb +3 -3
- data/app/components/marty/new_posting_window.rb +5 -6
- data/app/components/marty/posting_grid.rb +2 -2
- data/app/components/marty/posting_window.rb +1 -2
- data/app/components/marty/promise_view.rb +11 -6
- data/app/components/marty/record_form_window.rb +1 -1
- data/app/components/marty/report_form.rb +4 -4
- data/app/components/marty/report_select.rb +1 -1
- data/app/components/marty/script_form.rb +4 -4
- data/app/components/marty/script_grid.rb +2 -2
- data/app/components/marty/script_tester.rb +1 -1
- data/app/components/marty/simple_app.rb +1 -2
- data/app/components/marty/simple_app/client/statusbar_ext.js +1 -1
- data/app/components/marty/tag_grid.rb +1 -1
- data/app/components/marty/user_view.rb +5 -5
- data/app/controllers/marty/job_controller.rb +5 -1
- data/app/models/marty/base.rb +0 -15
- data/app/models/marty/data_grid.rb +1 -1
- data/app/models/marty/log.rb +1 -0
- data/app/models/marty/promise.rb +27 -84
- data/app/models/marty/vw_promise.rb +72 -0
- data/app/views/layouts/marty/application.html.erb +6 -3
- data/config/locales/en.yml +4 -0
- data/db/migrate/410_jsonb_promise_result.rb +9 -0
- data/db/migrate/411_create_vw_promises.rb +26 -0
- data/lib/marty/data_change.rb +3 -4
- data/lib/marty/data_conversion.rb +1 -2
- data/lib/marty/data_importer.rb +13 -14
- data/lib/marty/javascript/{overrides.js → grid_view_in_form.js} +10 -6
- data/lib/marty/mcfly_model.rb +13 -20
- data/lib/marty/monkey.rb +33 -40
- data/lib/marty/promise_job.rb +8 -2
- data/lib/marty/promise_proxy.rb +6 -11
- data/lib/marty/rule_script_set.rb +5 -2
- data/lib/marty/version.rb +1 -1
- data/marty.gemspec +1 -1
- data/other/marty/diagnostic/delayed_job_workers.rb +8 -5
- data/spec/controllers/job_controller_spec.rb +34 -15
- data/spec/dummy/app/components/gemini/my_rule_view.rb +6 -0
- data/spec/dummy/app/models/gemini/helper.rb +2 -2
- data/spec/dummy/config/application.rb +1 -1
- data/spec/features/rule_spec.rb +100 -5
- data/spec/fixtures/csv/rule/MyRule.csv +1 -1
- data/spec/job_helper.rb +2 -4
- data/spec/lib/data_importer_spec.rb +10 -10
- data/spec/lib/delorean_query_spec.rb +13 -2
- data/spec/lib/logger_spec.rb +16 -14
- data/spec/models/data_grid_spec.rb +4 -10
- data/spec/models/promise_spec.rb +8 -8
- data/spec/models/rule_spec.rb +7 -7
- data/spec/spec_helper.rb +1 -1
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8dc054b69b36c3f88865983281fb580a69870469
|
4
|
+
data.tar.gz: e09a7b2ec29e732f516d803fc9c3acec66db98c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 647481fb469e7dc0a979c792eff8dcfab5367bd44e8df5f28cefde2e781c61e16730e8a29262c2cda1f36f04ee82ea18d87000014705df8126b3d4c26dd04512
|
7
|
+
data.tar.gz: dd873fbce7126aa5ae3c947bc091edece040a8854be98be0991c03cdb32dedd4523c2978d8ea7c6c44d25c4f897bece30fe35b9cdcb79ffafb99cdcab1ecc1d0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
marty (2.
|
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.
|
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.
|
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.
|
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.
|
32
|
+
c.icon_cls = "fa fa-sign-in-alt gylph"
|
33
33
|
end
|
34
34
|
|
35
35
|
action :sign_out do |c|
|
36
|
-
c.
|
37
|
-
c.text
|
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
|
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.
|
51
|
-
|
52
|
-
|
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-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
80
|
+
lhs_wid = h.keys.map(&:length).max
|
81
|
+
fmt = "%-#{lhs_wid}s = %s"
|
82
|
+
result = []
|
78
83
|
h.map do |k, vstr|
|
79
|
-
|
80
|
-
|
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
|
-
|
98
|
-
Marty::BaseRuleView.simple_to_hashstr(v))
|
106
|
+
final = Marty::BaseRuleView.simple_to_hash(v)
|
99
107
|
rescue => e
|
100
|
-
|
108
|
+
final = { "~~ERROR~~": e.message }
|
101
109
|
end
|
102
|
-
|
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
|
118
|
-
a.
|
119
|
-
a.handler
|
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|
|
@@ -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
|
@@ -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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
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.
|
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
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|