marty 8.5.0 → 9.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintignore +1 -0
- data/.eslintrc.js +26 -0
- data/.gitignore +3 -0
- data/.gitlab-ci.yml +7 -0
- data/.prettierignore +14 -0
- data/.rubocop_todo.yml +1 -1
- data/Dockerfile.dummy +3 -0
- data/Makefile +1 -0
- data/app/assets/javascripts/marty/cable.js +7 -3
- data/app/assets/javascripts/marty/extjs/extensions/datetime_field/component.js +401 -0
- data/app/assets/javascripts/marty/extjs/extensions/datetime_field/field.js +140 -0
- data/app/assets/javascripts/marty/extjs/extensions/marty.js +845 -781
- data/app/assets/stylesheets/marty/codemirror/codemirror.css +215 -77
- data/app/assets/stylesheets/marty/codemirror/delorean.css +2 -2
- data/app/assets/stylesheets/marty/dark_mode.css +13 -3
- data/app/components/marty/auth_app/client/auth_app.js +107 -102
- data/app/components/marty/base_rule_view/client/base_rule_view.js +10 -8
- data/app/components/marty/data_grid_view/client/data_grid_edit.js +534 -519
- data/app/components/marty/form/client/form.js +3 -3
- data/app/components/marty/grid/client/grid.js +110 -87
- data/app/components/marty/import_view/client/import_view.js +18 -18
- data/app/components/marty/live_search_grid_panel/client/live_search_grid_panel.js +14 -13
- data/app/components/marty/main_auth_app/client/main_auth_app.js +42 -42
- data/app/components/marty/mcfly_grid_panel/client/mcfly_grid_panel.js +27 -18
- data/app/components/marty/new_posting_form/client/new_posting_form.js +3 -3
- data/app/components/marty/panel/client/panel.js +3 -3
- data/app/components/marty/posting_grid/client/posting_grid.js +24 -18
- data/app/components/marty/promise_view/client/promise_view.css +12 -12
- data/app/components/marty/promise_view/client/promise_view.js +46 -38
- data/app/components/marty/report_form/client/report_form.js +30 -28
- data/app/components/marty/report_select/client/report_select.js +28 -23
- data/app/components/marty/reporting/client/reporting.js +3 -3
- data/app/components/marty/script_form/client/script_form.js +29 -23
- data/app/components/marty/script_tester/client/script_tester.js +4 -5
- data/app/components/marty/scripting/client/scripting.js +40 -36
- data/app/components/marty/simple_app/client/simple_app.js +33 -24
- data/app/components/marty/simple_app/client/statusbar_ext.js +1 -1
- data/app/controllers/marty/rpc_controller.rb +3 -0
- data/app/models/marty/promise.rb +10 -2
- data/app/services/marty/data_grid/constraint.rb +2 -1
- data/app/services/marty/jobs/schedule.rb +2 -2
- data/app/services/marty/promises/delorean/create.rb +9 -2
- data/app/services/marty/promises/ruby/create.rb +7 -2
- data/config/initializers/delayed_job_config.rb +1 -0
- data/delorean/blame_report.dl +50 -58
- data/delorean/enum_report.dl +2 -3
- data/delorean/{marty_fields.dl → fields.dl} +16 -0
- data/delorean/styles.dl +216 -0
- data/delorean/table_report.dl +4 -4
- data/lib/marty/monkey.rb +17 -0
- data/lib/marty/promise_job.rb +9 -0
- data/lib/marty/promise_ruby_job.rb +8 -0
- data/lib/marty/version.rb +1 -1
- data/make-lint.mk +19 -0
- data/package.json +16 -0
- data/prettier.config.js +6 -0
- data/spec/controllers/diagnostic/controller_spec.rb +0 -1
- data/spec/controllers/rpc_controller_spec.rb +21 -7
- data/spec/dummy/delorean/data_report.dl +4 -4
- data/spec/dummy/delorean/fields.dl +1 -0
- data/spec/features/data_grid_spec.rb +37 -1
- data/spec/job_helper.rb +6 -0
- data/spec/lib/data_blame_spec.rb +4 -4
- data/spec/lib/data_importer_spec.rb +6 -4
- data/spec/models/promise_spec.rb +31 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/download_helper.rb +53 -49
- data/spec/support/json_helper.rb +11 -0
- data/spec/support/shared_connection_db_helpers.rb +1 -0
- data/spec/support/suite.rb +20 -14
- data/yarn.lock +967 -0
- metadata +16 -4
- data/spec/dummy/delorean/marty_fields.dl +0 -1
@@ -1,44 +1,50 @@
|
|
1
|
-
{
|
2
|
-
setActionModes
|
1
|
+
({
|
2
|
+
setActionModes(a) {
|
3
3
|
this.actions.apply.setDisabled(!a["save"]);
|
4
4
|
// style input field text based on whether it is editable
|
5
|
-
this.getForm()
|
6
|
-
"
|
5
|
+
this.getForm()
|
6
|
+
.findField("body")
|
7
|
+
.editor.setOption("readOnly", !a["save"]);
|
7
8
|
},
|
8
9
|
|
9
|
-
getScriptId
|
10
|
-
return this.getForm()
|
10
|
+
getScriptId() {
|
11
|
+
return this.getForm()
|
12
|
+
.findField("id")
|
13
|
+
.getValue();
|
11
14
|
},
|
12
15
|
|
13
|
-
setLineError
|
14
|
-
|
16
|
+
setLineError(idx) {
|
15
17
|
idx -= 1;
|
16
|
-
|
18
|
+
const editor = this.getForm().findField("body").editor;
|
17
19
|
|
18
20
|
if (idx > -1) {
|
19
|
-
|
20
|
-
editor.markText(
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
const line = editor.getLine(idx);
|
22
|
+
editor.markText(
|
23
|
+
{
|
24
|
+
line: idx,
|
25
|
+
ch: 0
|
26
|
+
},
|
27
|
+
{
|
28
|
+
line: idx,
|
29
|
+
ch: line.length
|
30
|
+
},
|
31
|
+
{
|
32
|
+
className: "errorline"
|
33
|
+
}
|
34
|
+
);
|
29
35
|
}
|
30
36
|
editor.refresh();
|
31
37
|
},
|
32
38
|
|
33
|
-
refreshParent
|
39
|
+
refreshParent(script_name) {
|
34
40
|
this.netzkeGetParentComponent().scriptRefresh(script_name);
|
35
41
|
},
|
36
42
|
|
37
|
-
netzkeOnDoPrint
|
43
|
+
netzkeOnDoPrint(_params) {
|
38
44
|
this.server.doPrint(this.getScriptId());
|
39
45
|
},
|
40
46
|
|
41
|
-
getReport
|
47
|
+
getReport(report_path) {
|
42
48
|
window.location = report_path;
|
43
49
|
}
|
44
|
-
}
|
50
|
+
});
|
@@ -1,62 +1,66 @@
|
|
1
|
-
{
|
2
|
-
initComponent
|
3
|
-
|
1
|
+
({
|
2
|
+
initComponent() {
|
3
|
+
const me = this;
|
4
4
|
me.callParent();
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
const tag_grid = me.netzkeGetComponent("tag_grid").getView();
|
7
|
+
const script_grid = me.netzkeGetComponent("script_grid").getView();
|
8
|
+
const script_form = me.netzkeGetComponent("script_form");
|
9
9
|
|
10
|
-
tag_grid.getSelectionModel().on(
|
11
|
-
|
10
|
+
tag_grid.getSelectionModel().on(
|
11
|
+
"selectionchange",
|
12
|
+
function(self, records) {
|
13
|
+
if (records[0] == null) return;
|
12
14
|
|
13
|
-
|
14
|
-
return;
|
15
|
-
|
16
|
-
var tag_id = records[0].get('id');
|
15
|
+
const tag_id = records[0].get("id");
|
17
16
|
me.server.selectTag({
|
18
|
-
tag_id
|
17
|
+
tag_id
|
19
18
|
});
|
20
19
|
script_grid.getStore().load();
|
21
|
-
|
20
|
+
const script_name = null;
|
22
21
|
script_form.server.netzkeLoad({
|
23
|
-
script_name
|
22
|
+
script_name
|
24
23
|
});
|
25
|
-
},
|
26
|
-
|
27
|
-
|
28
|
-
function (self, records) {
|
24
|
+
},
|
25
|
+
me
|
26
|
+
);
|
29
27
|
|
30
|
-
|
31
|
-
|
28
|
+
script_grid.getSelectionModel().on(
|
29
|
+
"selectionchange",
|
30
|
+
function(self, records) {
|
31
|
+
if (script_grid.getStore().isLoading() == true) return;
|
32
32
|
|
33
|
-
if (records[0] == null)
|
34
|
-
return;
|
33
|
+
if (records[0] == null) return;
|
35
34
|
|
36
|
-
|
35
|
+
const script_name = records[0].get("name");
|
37
36
|
me.server.selectScript({
|
38
|
-
script_name
|
37
|
+
script_name
|
39
38
|
});
|
40
39
|
script_form.server.netzkeLoad({
|
41
|
-
script_name
|
40
|
+
script_name
|
42
41
|
});
|
43
|
-
},
|
42
|
+
},
|
43
|
+
me
|
44
|
+
);
|
44
45
|
},
|
45
46
|
|
46
|
-
scriptRefresh
|
47
|
+
scriptRefresh(script_name) {
|
47
48
|
if (!script_name) {
|
48
49
|
this.server.selectScript({});
|
49
50
|
this.netzkeReload();
|
50
51
|
} else {
|
51
52
|
this.server.selectScript({
|
52
|
-
script_name
|
53
|
+
script_name
|
53
54
|
});
|
54
|
-
this.netzkeGetComponent(
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
this.netzkeGetComponent("tag_grid")
|
56
|
+
.getStore()
|
57
|
+
.load();
|
58
|
+
this.netzkeGetComponent("script_grid")
|
59
|
+
.getStore()
|
60
|
+
.load();
|
61
|
+
this.netzkeGetComponent("script_form").server.netzkeLoad({
|
62
|
+
script_name
|
58
63
|
});
|
59
64
|
}
|
60
|
-
}
|
61
|
-
|
62
|
-
}
|
65
|
+
}
|
66
|
+
});
|
@@ -1,21 +1,23 @@
|
|
1
|
-
{
|
1
|
+
({
|
2
2
|
initComponent() {
|
3
3
|
this.callParent();
|
4
4
|
|
5
5
|
this.mainPanel = this.down('panel[itemId="main_panel"]');
|
6
6
|
this.menuBar = this.down('container[itemId="menu_bar"]');
|
7
|
-
|
7
|
+
const statusBar = (this.statusBar = this.down(
|
8
|
+
'container[itemId="status_bar"]'
|
9
|
+
));
|
8
10
|
|
9
11
|
// Setting the "busy" indicator for Ajax requests
|
10
|
-
Ext.Ajax.on(
|
12
|
+
Ext.Ajax.on("beforerequest", function() {
|
11
13
|
statusBar.showBusy();
|
12
14
|
});
|
13
15
|
|
14
|
-
Ext.Ajax.on(
|
16
|
+
Ext.Ajax.on("requestcomplete", function() {
|
15
17
|
statusBar.hideBusy();
|
16
18
|
});
|
17
19
|
|
18
|
-
Ext.Ajax.on(
|
20
|
+
Ext.Ajax.on("requestexception", function() {
|
19
21
|
statusBar.hideBusy();
|
20
22
|
});
|
21
23
|
|
@@ -26,7 +28,7 @@
|
|
26
28
|
setRouting() {
|
27
29
|
this.router = Ext.util.History;
|
28
30
|
this.router.init();
|
29
|
-
this.router.on(
|
31
|
+
this.router.on("change", this.loadRoute, this);
|
30
32
|
},
|
31
33
|
|
32
34
|
loadRoute(token) {
|
@@ -41,7 +43,7 @@
|
|
41
43
|
|
42
44
|
afterRender() {
|
43
45
|
this.callParent();
|
44
|
-
|
46
|
+
const currentToken = this.router.getToken();
|
45
47
|
if (typeof currentToken == "string" && currentToken.length > 0) {
|
46
48
|
this.loadRoute(currentToken);
|
47
49
|
}
|
@@ -55,43 +57,50 @@
|
|
55
57
|
this.router.add(action.name.underscore());
|
56
58
|
},
|
57
59
|
|
58
|
-
onToggleConfigMode(
|
60
|
+
onToggleConfigMode(_params) {
|
59
61
|
this.toggleConfigMode();
|
60
62
|
},
|
61
63
|
|
62
|
-
netzkeInitComponentCallback() {
|
63
|
-
},
|
64
|
+
netzkeInitComponentCallback() {},
|
64
65
|
|
65
66
|
// FIXME: move to netzke
|
66
67
|
netzkeCallEndpoint(action) {
|
67
|
-
const selected = this.getSelectionModel()
|
68
|
+
const selected = this.getSelectionModel()
|
69
|
+
.getSelection()
|
70
|
+
.map((r) => r.id);
|
68
71
|
const endpointName = action.endpointName || action.name;
|
69
72
|
|
70
|
-
const camelCasedEndpointName = endpointName.replace(
|
71
|
-
|
72
|
-
(g) => g[1].toUpperCase()
|
73
|
+
const camelCasedEndpointName = endpointName.replace(/_([a-z])/g, (g) =>
|
74
|
+
g[1].toUpperCase()
|
73
75
|
);
|
74
76
|
|
75
|
-
const requireConfirmation =
|
77
|
+
const requireConfirmation =
|
78
|
+
action.requireConfirmation || action.confirmationMessage;
|
76
79
|
|
77
80
|
const handlerFunction = this.server[camelCasedEndpointName];
|
78
81
|
|
79
82
|
if (!requireConfirmation) {
|
80
|
-
return handlerFunction(selected, () => {
|
81
|
-
|
83
|
+
return handlerFunction(selected, () => {
|
84
|
+
this.unmask();
|
85
|
+
});
|
86
|
+
}
|
82
87
|
|
83
88
|
const confirmationTitle = action.confirmationTitle || action.name;
|
84
|
-
const confirmationMessage = action.confirmationMessage ||
|
85
|
-
const inProgressMessage = action.inProgressMessage ||
|
89
|
+
const confirmationMessage = action.confirmationMessage || "Are you sure?";
|
90
|
+
const inProgressMessage = action.inProgressMessage || "In progress...";
|
86
91
|
|
87
92
|
return Ext.Msg.confirm(
|
88
93
|
confirmationTitle,
|
89
94
|
Ext.String.format(confirmationMessage),
|
90
|
-
(btn,
|
91
|
-
if (btn !== "yes") {
|
95
|
+
(btn, _value, _cfg) => {
|
96
|
+
if (btn !== "yes") {
|
97
|
+
return null;
|
98
|
+
}
|
92
99
|
this.mask(inProgressMessage);
|
93
|
-
return handlerFunction(selected, () => {
|
100
|
+
return handlerFunction(selected, () => {
|
101
|
+
this.unmask();
|
102
|
+
});
|
94
103
|
}
|
95
104
|
);
|
96
|
-
}
|
97
|
-
}
|
105
|
+
}
|
106
|
+
});
|
@@ -34,6 +34,9 @@ class Marty::RpcController < ActionController::Base
|
|
34
34
|
api.log(result, log_params, request)
|
35
35
|
end
|
36
36
|
|
37
|
+
# Do not expose backtrace in case of error
|
38
|
+
next result.except('backtrace', :backtrace) if result.is_a?(Hash)
|
39
|
+
|
37
40
|
result
|
38
41
|
rescue StandardError => e
|
39
42
|
Marty::Logger.log('rpc_controller', 'failure', e.message)
|
data/app/models/marty/promise.rb
CHANGED
@@ -150,7 +150,7 @@ class Marty::Promise < Marty::Base
|
|
150
150
|
# timeout error.
|
151
151
|
if !last.start_dt
|
152
152
|
# log "TO11 #{Process.pid} #{last}"
|
153
|
-
return { 'error' =>
|
153
|
+
return { 'error' => self.class.never_started_message(last) }
|
154
154
|
end
|
155
155
|
end
|
156
156
|
|
@@ -163,7 +163,7 @@ class Marty::Promise < Marty::Base
|
|
163
163
|
last = latest
|
164
164
|
|
165
165
|
if !last.end_dt
|
166
|
-
return { 'error' =>
|
166
|
+
return { 'error' => self.class.timeout_message(last) }
|
167
167
|
end
|
168
168
|
end
|
169
169
|
|
@@ -227,5 +227,13 @@ class Marty::Promise < Marty::Base
|
|
227
227
|
|
228
228
|
{ 'error' => exception.message, 'backtrace' => exception.backtrace }
|
229
229
|
end
|
230
|
+
|
231
|
+
def never_started_message(promise)
|
232
|
+
"promise #{promise.id} timed out (never started)"
|
233
|
+
end
|
234
|
+
|
235
|
+
def timeout_message(promise)
|
236
|
+
"promise #{promise.id} timed out (didn't end)"
|
237
|
+
end
|
230
238
|
end
|
231
239
|
end
|
@@ -55,7 +55,7 @@ module Marty
|
|
55
55
|
err = nil
|
56
56
|
begin
|
57
57
|
cvt_val = cvt && !data_v.class.in?(rt) ?
|
58
|
-
DataGrid.parse_fvalue(pt, data_v, dt, klass)
|
58
|
+
DataGrid.parse_fvalue(pt, data_v, dt, klass)&.first :
|
59
59
|
data_v
|
60
60
|
rescue StandardError => e
|
61
61
|
err = e.message
|
@@ -63,6 +63,7 @@ module Marty
|
|
63
63
|
next res << [:type, x, y] if err
|
64
64
|
|
65
65
|
res << [:constraint, x, y] unless
|
66
|
+
cvt_val.nil? ||
|
66
67
|
chks.map { |op, chk_val| cvt_val.send(op, chk_val) }.all? { |v| v }
|
67
68
|
end
|
68
69
|
end
|
@@ -5,10 +5,10 @@ module Marty
|
|
5
5
|
|
6
6
|
delorean_fn :call, sig: 0 do
|
7
7
|
glob = Rails.root.join('app', 'jobs', '**', '*_job.rb')
|
8
|
-
Dir.glob(glob).each { |f| require f }
|
8
|
+
Dir.glob(glob).sort.each { |f| require f }
|
9
9
|
|
10
10
|
glob2 = Marty.root.join('app', 'jobs', '**', '*_job.rb')
|
11
|
-
Dir.glob(glob2).each { |f| require f }
|
11
|
+
Dir.glob(glob2).sort.each { |f| require f }
|
12
12
|
|
13
13
|
Delayed::Job.where.not(cron: nil).each(&:destroy!)
|
14
14
|
|
@@ -41,10 +41,17 @@ module Marty
|
|
41
41
|
node_name,
|
42
42
|
params,
|
43
43
|
args,
|
44
|
-
hook
|
44
|
+
hook,
|
45
|
+
# FIXME: should we use default timeout if not specified
|
46
|
+
# Do we want to limit job execution time with that?
|
47
|
+
promise_params['p_timeout']
|
45
48
|
)
|
46
49
|
|
47
|
-
job = Delayed::Job.enqueue(
|
50
|
+
job = Delayed::Job.enqueue(
|
51
|
+
promise_job,
|
52
|
+
priority: priority,
|
53
|
+
queue: promise_params['p_queue'] ||
|
54
|
+
Delayed::Worker.default_queue_name)
|
48
55
|
rescue StandardError => e
|
49
56
|
# log "CALLERR #{exc}"
|
50
57
|
res = ::Delorean::Engine.grok_runtime_exception(e)
|
@@ -37,10 +37,15 @@ module Marty
|
|
37
37
|
module_name,
|
38
38
|
method_name,
|
39
39
|
method_args,
|
40
|
-
hook
|
40
|
+
hook,
|
41
|
+
promise_params['p_timeout']
|
41
42
|
)
|
42
43
|
|
43
|
-
job = Delayed::Job.enqueue(
|
44
|
+
job = Delayed::Job.enqueue(
|
45
|
+
promise_job,
|
46
|
+
priority: priority,
|
47
|
+
queue: promise_params['p_queue'] ||
|
48
|
+
Delayed::Worker.default_queue_name)
|
44
49
|
rescue StandardError => e
|
45
50
|
res = { 'error' => e.message }
|
46
51
|
promise.set_start
|
@@ -0,0 +1 @@
|
|
1
|
+
Delayed::Worker.default_queue_name = 'default'
|
data/delorean/blame_report.dl
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
-
import
|
1
|
+
import Fields
|
2
2
|
import Styles
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
DateField1: Fields::DatetimeField
|
5
|
+
field_label = "Date 1"
|
6
|
+
name = "dt1"
|
7
|
+
|
8
|
+
DateField2: Fields::DatetimeField
|
9
|
+
field_label = "Date 2"
|
10
|
+
name = "dt2"
|
8
11
|
|
9
12
|
StyleRow:
|
10
13
|
profile =?
|
@@ -56,12 +59,12 @@ StyleGroup:
|
|
56
59
|
]
|
57
60
|
|
58
61
|
ModelRows:
|
59
|
-
klass
|
60
|
-
|
61
|
-
|
62
|
-
ids
|
62
|
+
klass =?
|
63
|
+
dt1 =?
|
64
|
+
dt2 =?
|
65
|
+
ids =?
|
63
66
|
|
64
|
-
groups = Marty::DataChange.changes(
|
67
|
+
groups = Marty::DataChange.changes(dt1, dt2, klass, ids)
|
65
68
|
|
66
69
|
headers = ["Group ID", "Created", "By", "Deleted", "By"] +
|
67
70
|
Marty::DataChange.class_headers(klass)
|
@@ -84,36 +87,31 @@ ModelRows:
|
|
84
87
|
count = row_groups.length
|
85
88
|
ws = if count > 0 then [klass, rows] else nil
|
86
89
|
|
87
|
-
OptionalIDsField:
|
90
|
+
OptionalIDsField: Fields::TextField
|
88
91
|
field_label = "Group IDs (optional)"
|
89
92
|
name = "restrict_to_ids"
|
90
93
|
|
91
94
|
DataBlameReport:
|
92
95
|
title = "Data Blame Report"
|
93
96
|
|
94
|
-
|
95
|
-
|
96
|
-
t1 = posting1.created_dt
|
97
|
-
|
98
|
-
pt_name2 =?
|
99
|
-
posting2 =? Marty::Posting.lookup(pt_name2)
|
100
|
-
t2 = posting2.created_dt
|
97
|
+
dt1 =?
|
98
|
+
dt2 =?
|
101
99
|
|
102
|
-
class_list =?
|
100
|
+
class_list =? []
|
103
101
|
restrict_to_ids =? nil
|
104
102
|
|
105
103
|
form = [
|
106
|
-
|
107
|
-
|
108
|
-
|
104
|
+
DateField1,
|
105
|
+
DateField2,
|
106
|
+
Fields::ClassListField,
|
109
107
|
OptionalIDsField
|
110
108
|
]
|
111
109
|
|
112
|
-
ts = if Marty::Helper.infinity_dt(
|
113
|
-
then [
|
114
|
-
else if Marty::Helper.infinity_dt(
|
115
|
-
then [
|
116
|
-
else [
|
110
|
+
ts = if Marty::Helper.infinity_dt(dt1)
|
111
|
+
then [dt2, dt1]
|
112
|
+
else if Marty::Helper.infinity_dt(dt2)
|
113
|
+
then [dt1, dt2]
|
114
|
+
else [dt1, dt2].sort
|
117
115
|
|
118
116
|
sanitized = if class_list
|
119
117
|
then Marty::DataChange.sanitize_classes(class_list)
|
@@ -128,7 +126,7 @@ DataBlameReport:
|
|
128
126
|
else true
|
129
127
|
|
130
128
|
result = ids_check && [
|
131
|
-
ModelRows(
|
129
|
+
ModelRows(dt1 = ts[0], dt2 = ts[1], klass = klass,
|
132
130
|
ids = ids).ws
|
133
131
|
for klass in sanitized
|
134
132
|
].compact
|
@@ -136,11 +134,11 @@ DataBlameReport:
|
|
136
134
|
format = "xlsx"
|
137
135
|
|
138
136
|
ModelSummaryRow:
|
139
|
-
klass
|
140
|
-
|
141
|
-
|
137
|
+
klass =?
|
138
|
+
dt1 =?
|
139
|
+
dt2 =?
|
142
140
|
|
143
|
-
r = Marty::DataChange.change_summary(
|
141
|
+
r = Marty::DataChange.change_summary(dt1, dt2, klass)
|
144
142
|
cr = r['created']
|
145
143
|
up = r['updated']
|
146
144
|
dl = r['deleted']
|
@@ -150,22 +148,17 @@ ModelSummaryRow:
|
|
150
148
|
DataBlameReportSummary:
|
151
149
|
title = "Summary Data Blame Report"
|
152
150
|
|
153
|
-
|
154
|
-
|
155
|
-
t1 = posting1.created_dt
|
156
|
-
|
157
|
-
pt_name2 =?
|
158
|
-
posting2 =? Marty::Posting.lookup(pt_name2)
|
159
|
-
t2 = posting2.created_dt
|
151
|
+
dt1 =?
|
152
|
+
dt2 =?
|
160
153
|
|
161
154
|
form = [
|
162
|
-
|
163
|
-
|
155
|
+
DateField1,
|
156
|
+
DateField2,
|
164
157
|
]
|
165
158
|
|
166
|
-
|
167
|
-
["
|
168
|
-
["
|
159
|
+
dates = [
|
160
|
+
["Date 1", dt1,],
|
161
|
+
["Date 2", dt2,],
|
169
162
|
]
|
170
163
|
|
171
164
|
hrow = [
|
@@ -173,18 +166,18 @@ DataBlameReportSummary:
|
|
173
166
|
Styles::Style.m_hdr_style0,
|
174
167
|
]
|
175
168
|
|
176
|
-
ts = if Marty::Helper.infinity_dt(
|
177
|
-
then [
|
178
|
-
else if Marty::Helper.infinity_dt(
|
179
|
-
then [
|
180
|
-
else [
|
169
|
+
ts = if Marty::Helper.infinity_dt(dt1)
|
170
|
+
then [dt2, dt1]
|
171
|
+
else if Marty::Helper.infinity_dt(dt2)
|
172
|
+
then [dt1, dt2]
|
173
|
+
else [dt1, dt2].sort
|
181
174
|
|
182
175
|
rows = [
|
183
|
-
ModelSummaryRow(
|
176
|
+
ModelSummaryRow(dt1 = ts[0], dt2 = ts[1], klass = klass).ws
|
184
177
|
for klass in Marty::DataChange.class_list
|
185
178
|
].compact
|
186
179
|
|
187
|
-
header = [["row", r, {"style" : [Styles::Style.s_hdr]}] for r in
|
180
|
+
header = [["row", r, {"style" : [Styles::Style.s_hdr]}] for r in dates]
|
188
181
|
result = [[title,[hrow] + rows, {"widths" : [30]}], ["Parameters", header]]
|
189
182
|
format = "xlsx"
|
190
183
|
|
@@ -192,21 +185,20 @@ DeadReferenceReport:
|
|
192
185
|
title = "Dead Reference Report"
|
193
186
|
|
194
187
|
class_list =? false
|
195
|
-
|
196
|
-
posting =? Marty::Posting.lookup(pt_name)
|
188
|
+
date =?
|
197
189
|
|
198
190
|
sanitized = if class_list
|
199
191
|
then Marty::DataChange.sanitize_classes(class_list)
|
200
192
|
else Marty::DataChange.class_list
|
201
193
|
|
202
194
|
form = [
|
203
|
-
|
204
|
-
|
195
|
+
Fields::DateField,
|
196
|
+
Fields::ClassListField,
|
205
197
|
]
|
206
198
|
|
207
199
|
result = [
|
208
200
|
[[[klass, attr, obj].flatten for obj in list]
|
209
|
-
for attr, list in Marty::DataChange.dead_refs(
|
201
|
+
for attr, list in Marty::DataChange.dead_refs(date,
|
210
202
|
klass)].flatten(1)
|
211
203
|
for klass in sanitized
|
212
204
|
].flatten(1)
|
@@ -226,7 +218,7 @@ DataImportParam:
|
|
226
218
|
}
|
227
219
|
height = 600
|
228
220
|
|
229
|
-
CommaSepField:
|
221
|
+
CommaSepField: Fields::CheckboxField
|
230
222
|
name = "comma_sep"
|
231
223
|
field_label = "Comma Separated"
|
232
224
|
|
@@ -260,7 +252,7 @@ DiffReport:
|
|
260
252
|
]
|
261
253
|
|
262
254
|
form = [
|
263
|
-
|
255
|
+
Fields::ClassField,
|
264
256
|
DataImportParam,
|
265
257
|
CommaSepField,
|
266
258
|
]
|