blazer 2.4.2 → 2.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +64 -0
- data/README.md +155 -57
- data/app/assets/javascripts/blazer/Chart.js +14000 -13979
- data/app/assets/javascripts/blazer/bootstrap.js +300 -97
- data/app/assets/javascripts/blazer/queries.js +12 -1
- data/app/assets/javascripts/blazer/vue.js +10754 -9687
- data/app/assets/stylesheets/blazer/application.css +5 -0
- data/app/assets/stylesheets/blazer/bootstrap-propshaft.css +10 -0
- data/app/assets/stylesheets/blazer/bootstrap-sprockets.css.erb +10 -0
- data/app/assets/stylesheets/blazer/{bootstrap.css.erb → bootstrap.css} +527 -455
- data/app/controllers/blazer/base_controller.rb +45 -45
- data/app/controllers/blazer/dashboards_controller.rb +4 -11
- data/app/controllers/blazer/queries_controller.rb +31 -49
- data/app/models/blazer/query.rb +9 -3
- data/app/views/blazer/_variables.html.erb +5 -4
- data/app/views/blazer/dashboards/_form.html.erb +1 -1
- data/app/views/blazer/dashboards/show.html.erb +6 -4
- data/app/views/blazer/queries/_caching.html.erb +1 -1
- data/app/views/blazer/queries/_form.html.erb +3 -3
- data/app/views/blazer/queries/run.html.erb +5 -3
- data/app/views/blazer/queries/show.html.erb +12 -7
- data/app/views/layouts/blazer/application.html.erb +7 -2
- data/lib/blazer/adapters/athena_adapter.rb +73 -20
- data/lib/blazer/adapters/base_adapter.rb +16 -1
- data/lib/blazer/adapters/bigquery_adapter.rb +14 -3
- data/lib/blazer/adapters/cassandra_adapter.rb +15 -4
- data/lib/blazer/adapters/drill_adapter.rb +10 -0
- data/lib/blazer/adapters/druid_adapter.rb +36 -1
- data/lib/blazer/adapters/elasticsearch_adapter.rb +19 -4
- data/lib/blazer/adapters/hive_adapter.rb +10 -0
- data/lib/blazer/adapters/ignite_adapter.rb +12 -2
- data/lib/blazer/adapters/influxdb_adapter.rb +22 -10
- data/lib/blazer/adapters/mongodb_adapter.rb +4 -0
- data/lib/blazer/adapters/neo4j_adapter.rb +17 -2
- data/lib/blazer/adapters/opensearch_adapter.rb +52 -0
- data/lib/blazer/adapters/presto_adapter.rb +9 -0
- data/lib/blazer/adapters/salesforce_adapter.rb +5 -0
- data/lib/blazer/adapters/snowflake_adapter.rb +9 -0
- data/lib/blazer/adapters/soda_adapter.rb +9 -0
- data/lib/blazer/adapters/spark_adapter.rb +5 -0
- data/lib/blazer/adapters/sql_adapter.rb +41 -4
- data/{app/mailers → lib}/blazer/check_mailer.rb +0 -0
- data/lib/blazer/data_source.rb +90 -8
- data/lib/blazer/engine.rb +1 -4
- data/lib/blazer/result.rb +19 -1
- data/lib/blazer/run_statement.rb +7 -3
- data/lib/blazer/run_statement_job.rb +4 -2
- data/{app/mailers → lib}/blazer/slack_notifier.rb +19 -4
- data/lib/blazer/statement.rb +75 -0
- data/lib/blazer/version.rb +1 -1
- data/lib/blazer.rb +32 -8
- data/lib/generators/blazer/templates/config.yml.tt +2 -2
- data/lib/tasks/blazer.rake +5 -5
- data/licenses/LICENSE-bootstrap.txt +1 -1
- metadata +10 -6
@@ -32,45 +32,34 @@ module Blazer
|
|
32
32
|
|
33
33
|
private
|
34
34
|
|
35
|
-
def process_vars(statement,
|
36
|
-
|
35
|
+
def process_vars(statement, var_params = nil)
|
36
|
+
var_params ||= request.query_parameters
|
37
|
+
(@bind_vars ||= []).concat(statement.variables).uniq!
|
38
|
+
# update in-place so populated in view and consistent across queries on dashboard
|
37
39
|
@bind_vars.each do |var|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
if @success
|
43
|
-
@bind_vars.each do |var|
|
44
|
-
value = params[var].presence
|
45
|
-
if value
|
46
|
-
if ["start_time", "end_time"].include?(var)
|
47
|
-
value = value.to_s.gsub(" ", "+") # fix for Quip bug
|
48
|
-
end
|
49
|
-
|
50
|
-
if var.end_with?("_at")
|
51
|
-
begin
|
52
|
-
value = Blazer.time_zone.parse(value)
|
53
|
-
rescue
|
54
|
-
# do nothing
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
if value =~ /\A\d+\z/
|
59
|
-
value = value.to_i
|
60
|
-
elsif value =~ /\A\d+\.\d+\z/
|
61
|
-
value = value.to_f
|
62
|
-
end
|
63
|
-
end
|
64
|
-
value = Blazer.transform_variable.call(var, value) if Blazer.transform_variable
|
65
|
-
statement.gsub!("{#{var}}", ActiveRecord::Base.connection.quote(value))
|
40
|
+
if !var_params[var]
|
41
|
+
default = statement.data_source.variable_defaults[var]
|
42
|
+
# only add if default exists
|
43
|
+
var_params[var] = default if default
|
66
44
|
end
|
67
45
|
end
|
46
|
+
runnable = @bind_vars.all? { |v| var_params[v] }
|
47
|
+
statement.add_values(var_params) if runnable
|
48
|
+
runnable
|
49
|
+
end
|
50
|
+
|
51
|
+
def refresh_query(query)
|
52
|
+
statement = query.statement_object
|
53
|
+
runnable = process_vars(statement)
|
54
|
+
cohort_analysis_statement(statement) if statement.cohort_analysis?
|
55
|
+
statement.clear_cache if runnable
|
68
56
|
end
|
69
57
|
|
70
58
|
def add_cohort_analysis_vars
|
71
59
|
@bind_vars << "cohort_period" unless @bind_vars.include?("cohort_period")
|
72
|
-
@smart_vars["cohort_period"] = ["day", "week", "month"]
|
73
|
-
|
60
|
+
@smart_vars["cohort_period"] = ["day", "week", "month"] if @smart_vars
|
61
|
+
# TODO create var_params method
|
62
|
+
request.query_parameters["cohort_period"] ||= "week"
|
74
63
|
end
|
75
64
|
|
76
65
|
def parse_smart_variables(var, data_source)
|
@@ -94,22 +83,33 @@ module Blazer
|
|
94
83
|
[smart_var, error]
|
95
84
|
end
|
96
85
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
86
|
+
def cohort_analysis_statement(statement)
|
87
|
+
@cohort_period = params["cohort_period"] || "week"
|
88
|
+
@cohort_period = "week" unless ["day", "week", "month"].include?(@cohort_period)
|
89
|
+
|
90
|
+
# for now
|
91
|
+
@conversion_period = @cohort_period
|
92
|
+
@cohort_days =
|
93
|
+
case @cohort_period
|
94
|
+
when "day"
|
95
|
+
1
|
96
|
+
when "week"
|
97
|
+
7
|
98
|
+
when "month"
|
99
|
+
30
|
100
|
+
end
|
101
|
+
|
102
|
+
statement.apply_cohort_analysis(period: @cohort_period, days: @cohort_days)
|
103
|
+
end
|
104
|
+
|
105
|
+
# TODO allow all keys
|
106
|
+
# or show error message for disallowed keys
|
107
107
|
UNPERMITTED_KEYS = [:controller, :action, :id, :host, :query, :dashboard, :query_id, :query_ids, :table_names, :authenticity_token, :utf8, :_method, :commit, :statement, :data_source, :name, :fork_query_id, :blazer, :run_id, :script_name, :original_script_name]
|
108
108
|
|
109
|
-
|
110
|
-
def variable_params(resource)
|
109
|
+
def variable_params(resource, var_params = nil)
|
111
110
|
permitted_keys = resource.variables - UNPERMITTED_KEYS.map(&:to_s)
|
112
|
-
|
111
|
+
var_params ||= request.query_parameters
|
112
|
+
var_params.slice(*permitted_keys)
|
113
113
|
end
|
114
114
|
helper_method :variable_params
|
115
115
|
|
@@ -21,11 +21,8 @@ module Blazer
|
|
21
21
|
|
22
22
|
def show
|
23
23
|
@queries = @dashboard.dashboard_queries.order(:position).preload(:query).map(&:query)
|
24
|
-
@statements = []
|
25
24
|
@queries.each do |query|
|
26
|
-
|
27
|
-
process_vars(statement, query.data_source)
|
28
|
-
@statements << statement
|
25
|
+
@success = process_vars(query.statement_object)
|
29
26
|
end
|
30
27
|
@bind_vars ||= []
|
31
28
|
|
@@ -48,7 +45,7 @@ module Blazer
|
|
48
45
|
|
49
46
|
def update
|
50
47
|
if update_dashboard(@dashboard)
|
51
|
-
redirect_to dashboard_path(@dashboard, variable_params(@dashboard))
|
48
|
+
redirect_to dashboard_path(@dashboard, params: variable_params(@dashboard))
|
52
49
|
else
|
53
50
|
render_errors @dashboard
|
54
51
|
end
|
@@ -61,13 +58,9 @@ module Blazer
|
|
61
58
|
|
62
59
|
def refresh
|
63
60
|
@dashboard.queries.each do |query|
|
64
|
-
|
65
|
-
statement = query.statement.dup
|
66
|
-
process_vars(statement, query.data_source)
|
67
|
-
Blazer.transform_statement.call(data_source, statement) if Blazer.transform_statement
|
68
|
-
data_source.clear_cache(statement)
|
61
|
+
refresh_query(query)
|
69
62
|
end
|
70
|
-
redirect_to dashboard_path(@dashboard, variable_params(@dashboard))
|
63
|
+
redirect_to dashboard_path(@dashboard, params: variable_params(@dashboard))
|
71
64
|
end
|
72
65
|
|
73
66
|
private
|
@@ -52,28 +52,25 @@ module Blazer
|
|
52
52
|
@query.status = "active" if @query.respond_to?(:status)
|
53
53
|
|
54
54
|
if @query.save
|
55
|
-
redirect_to query_path(@query, variable_params(@query))
|
55
|
+
redirect_to query_path(@query, params: variable_params(@query))
|
56
56
|
else
|
57
57
|
render_errors @query
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
def show
|
62
|
-
@statement = @query.
|
63
|
-
process_vars(@statement
|
62
|
+
@statement = @query.statement_object
|
63
|
+
@success = process_vars(@statement)
|
64
64
|
|
65
65
|
@smart_vars = {}
|
66
66
|
@sql_errors = []
|
67
|
-
data_source = Blazer.data_sources[@query.data_source]
|
68
67
|
@bind_vars.each do |var|
|
69
|
-
smart_var, error = parse_smart_variables(var, data_source)
|
68
|
+
smart_var, error = parse_smart_variables(var, @statement.data_source)
|
70
69
|
@smart_vars[var] = smart_var if smart_var
|
71
70
|
@sql_errors << error if error
|
72
71
|
end
|
73
72
|
|
74
|
-
@query.update!(status: "active") if @query.
|
75
|
-
|
76
|
-
Blazer.transform_statement.call(data_source, @statement) if Blazer.transform_statement
|
73
|
+
@query.update!(status: "active") if @query.respond_to?(:status) && @query.status.in?(["archived", nil])
|
77
74
|
|
78
75
|
add_cohort_analysis_vars if @query.cohort_analysis?
|
79
76
|
end
|
@@ -82,17 +79,25 @@ module Blazer
|
|
82
79
|
end
|
83
80
|
|
84
81
|
def run
|
85
|
-
@statement = params[:statement]
|
86
|
-
# before process_vars
|
87
|
-
@cohort_analysis = Query.new(statement: @statement).cohort_analysis?
|
88
|
-
data_source = params[:data_source]
|
89
|
-
process_vars(@statement, data_source)
|
90
|
-
@only_chart = params[:only_chart]
|
91
|
-
@run_id = blazer_params[:run_id]
|
92
82
|
@query = Query.find_by(id: params[:query_id]) if params[:query_id]
|
83
|
+
|
84
|
+
# use query data source when present
|
85
|
+
# need to update viewable? logic below if this changes
|
93
86
|
data_source = @query.data_source if @query && @query.data_source
|
87
|
+
data_source ||= params[:data_source]
|
94
88
|
@data_source = Blazer.data_sources[data_source]
|
95
89
|
|
90
|
+
@statement = Blazer::Statement.new(params[:statement], @data_source)
|
91
|
+
# before process_vars
|
92
|
+
@cohort_analysis = @statement.cohort_analysis?
|
93
|
+
|
94
|
+
# fallback for now for users with open tabs
|
95
|
+
# TODO remove fallback in future version
|
96
|
+
@var_params = request.request_parameters["variables"] || request.request_parameters
|
97
|
+
@success = process_vars(@statement, @var_params)
|
98
|
+
@only_chart = params[:only_chart]
|
99
|
+
@run_id = blazer_params[:run_id]
|
100
|
+
|
96
101
|
run_cohort_analysis if @cohort_analysis
|
97
102
|
|
98
103
|
# ensure viewable
|
@@ -128,7 +133,7 @@ module Blazer
|
|
128
133
|
|
129
134
|
options = {user: blazer_user, query: @query, refresh_cache: params[:check], run_id: @run_id, async: Blazer.async}
|
130
135
|
if Blazer.async && request.format.symbol != :csv
|
131
|
-
Blazer::RunStatementJob.perform_later(@data_source.id, @statement, options)
|
136
|
+
Blazer::RunStatementJob.perform_later(@data_source.id, @statement.statement, options.merge(values: @statement.values))
|
132
137
|
wait_start = Time.now
|
133
138
|
loop do
|
134
139
|
sleep(0.1)
|
@@ -136,7 +141,7 @@ module Blazer
|
|
136
141
|
break if @result || Time.now - wait_start > 3
|
137
142
|
end
|
138
143
|
else
|
139
|
-
@result = Blazer::RunStatement.new.perform(@
|
144
|
+
@result = Blazer::RunStatement.new.perform(@statement, options)
|
140
145
|
end
|
141
146
|
|
142
147
|
if @result
|
@@ -166,13 +171,8 @@ module Blazer
|
|
166
171
|
end
|
167
172
|
|
168
173
|
def refresh
|
169
|
-
|
170
|
-
@
|
171
|
-
process_vars(@statement, @query.data_source)
|
172
|
-
Blazer.transform_statement.call(data_source, @statement) if Blazer.transform_statement
|
173
|
-
@statement = cohort_analysis_statement(data_source, @statement) if @query.cohort_analysis?
|
174
|
-
data_source.clear_cache(@statement)
|
175
|
-
redirect_to query_path(@query, variable_params(@query))
|
174
|
+
refresh_query(@query)
|
175
|
+
redirect_to query_path(@query, params: variable_params(@query))
|
176
176
|
end
|
177
177
|
|
178
178
|
def update
|
@@ -180,11 +180,12 @@ module Blazer
|
|
180
180
|
@query = Blazer::Query.new
|
181
181
|
@query.creator = blazer_user if @query.respond_to?(:creator)
|
182
182
|
end
|
183
|
+
@query.status = "active" if @query.respond_to?(:status)
|
183
184
|
unless @query.editable?(blazer_user)
|
184
185
|
@query.errors.add(:base, "Sorry, permission denied")
|
185
186
|
end
|
186
187
|
if @query.errors.empty? && @query.update(query_params)
|
187
|
-
redirect_to query_path(@query, variable_params(@query))
|
188
|
+
redirect_to query_path(@query, params: variable_params(@query))
|
188
189
|
else
|
189
190
|
render_errors @query
|
190
191
|
end
|
@@ -281,6 +282,9 @@ module Blazer
|
|
281
282
|
render layout: false
|
282
283
|
end
|
283
284
|
format.csv do
|
285
|
+
# not ideal, but useful for testing
|
286
|
+
raise Error, @error if @error && Rails.env.test?
|
287
|
+
|
284
288
|
send_data csv_data(@columns, @rows, @data_source), type: "text/csv; charset=utf-8; header=present", disposition: "attachment; filename=\"#{@query.try(:name).try(:parameterize).presence || 'query'}.csv\""
|
285
289
|
end
|
286
290
|
end
|
@@ -362,34 +366,12 @@ module Blazer
|
|
362
366
|
end
|
363
367
|
|
364
368
|
def run_cohort_analysis
|
365
|
-
unless @data_source.supports_cohort_analysis?
|
369
|
+
unless @statement.data_source.supports_cohort_analysis?
|
366
370
|
@cohort_error = "This data source does not support cohort analysis"
|
367
371
|
end
|
368
372
|
|
369
373
|
@show_cohort_rows = !params[:query_id] || @cohort_error
|
370
|
-
|
371
|
-
unless @show_cohort_rows
|
372
|
-
@statement = cohort_analysis_statement(@data_source, @statement)
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
def cohort_analysis_statement(data_source, statement)
|
377
|
-
@cohort_period = params["cohort_period"] || "week"
|
378
|
-
@cohort_period = "week" unless ["day", "week", "month"].include?(@cohort_period)
|
379
|
-
|
380
|
-
# for now
|
381
|
-
@conversion_period = @cohort_period
|
382
|
-
@cohort_days =
|
383
|
-
case @cohort_period
|
384
|
-
when "day"
|
385
|
-
1
|
386
|
-
when "week"
|
387
|
-
7
|
388
|
-
when "month"
|
389
|
-
30
|
390
|
-
end
|
391
|
-
|
392
|
-
data_source.cohort_analysis_statement(statement, period: @cohort_period, days: @cohort_days)
|
374
|
+
cohort_analysis_statement(@statement) unless @show_cohort_rows
|
393
375
|
end
|
394
376
|
|
395
377
|
def render_cohort_analysis
|
data/app/models/blazer/query.rb
CHANGED
@@ -8,7 +8,7 @@ module Blazer
|
|
8
8
|
|
9
9
|
validates :statement, presence: true
|
10
10
|
|
11
|
-
scope :active, -> { column_names.include?("status") ? where(status: "active") : all }
|
11
|
+
scope :active, -> { column_names.include?("status") ? where(status: ["active", nil]) : all }
|
12
12
|
scope :named, -> { where.not(name: "") }
|
13
13
|
|
14
14
|
def to_param
|
@@ -35,13 +35,19 @@ module Blazer
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def variables
|
38
|
-
|
38
|
+
# don't require data_source to be loaded
|
39
|
+
variables = Statement.new(statement).variables
|
39
40
|
variables += ["cohort_period"] if cohort_analysis?
|
40
41
|
variables
|
41
42
|
end
|
42
43
|
|
43
44
|
def cohort_analysis?
|
44
|
-
|
45
|
+
# don't require data_source to be loaded
|
46
|
+
Statement.new(statement).cohort_analysis?
|
47
|
+
end
|
48
|
+
|
49
|
+
def statement_object
|
50
|
+
Statement.new(statement, data_source)
|
45
51
|
end
|
46
52
|
end
|
47
53
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
<% if @bind_vars.any? %>
|
2
|
+
<% var_params = request.query_parameters %>
|
2
3
|
<script>
|
3
4
|
<%= blazer_js_var "timeZone", Blazer.time_zone.tzinfo.name %>
|
4
5
|
var now = moment.tz(timeZone)
|
@@ -19,14 +20,14 @@
|
|
19
20
|
<% @bind_vars.each_with_index do |var, i| %>
|
20
21
|
<%= label_tag var, var %>
|
21
22
|
<% if (data = @smart_vars[var]) %>
|
22
|
-
<%= select_tag var, options_for_select([[nil, nil]] + data, selected:
|
23
|
+
<%= select_tag var, options_for_select([[nil, nil]] + data, selected: var_params[var]), style: "margin-right: 20px; width: 200px; display: none;" %>
|
23
24
|
<script>
|
24
25
|
$("#<%= var %>").selectize({
|
25
26
|
create: true
|
26
27
|
});
|
27
28
|
</script>
|
28
29
|
<% elsif var.end_with?("_at") || var == "start_time" || var == "end_time" %>
|
29
|
-
<%= hidden_field_tag var,
|
30
|
+
<%= hidden_field_tag var, var_params[var] %>
|
30
31
|
|
31
32
|
<div class="selectize-control single" style="width: 200px;">
|
32
33
|
<div id="<%= var %>-select" class="selectize-input" style="display: inline-block;">
|
@@ -58,13 +59,13 @@
|
|
58
59
|
})()
|
59
60
|
</script>
|
60
61
|
<% else %>
|
61
|
-
<%= text_field_tag var,
|
62
|
+
<%= text_field_tag var, var_params[var], style: "width: 120px; margin-right: 20px;", autofocus: i == 0 && !var.end_with?("_at") && !var_params[var], class: "form-control" %>
|
62
63
|
<% end %>
|
63
64
|
<% end %>
|
64
65
|
|
65
66
|
<% if date_vars %>
|
66
67
|
<% date_vars.each do |var| %>
|
67
|
-
<%= hidden_field_tag var,
|
68
|
+
<%= hidden_field_tag var, var_params[var] %>
|
68
69
|
<% end %>
|
69
70
|
|
70
71
|
<%= label_tag nil, date_vars.join(" & ") %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= form_for @dashboard, url: (@dashboard.persisted? ? dashboard_path(@dashboard, variable_params(@dashboard)) : dashboards_path(variable_params(@dashboard))), html: {id: "app", class: "small-form"} do |f| %>
|
1
|
+
<%= form_for @dashboard, url: (@dashboard.persisted? ? dashboard_path(@dashboard, params: variable_params(@dashboard)) : dashboards_path(params: variable_params(@dashboard))), html: {id: "app", class: "small-form"} do |f| %>
|
2
2
|
<% if @dashboard.errors.any? %>
|
3
3
|
<div class="alert alert-danger"><%= @dashboard.errors.full_messages.first %></div>
|
4
4
|
<% end %>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
</h3>
|
11
11
|
</div>
|
12
12
|
<div class="col-sm-3 text-right">
|
13
|
-
<%= link_to "Edit", edit_dashboard_path(@dashboard, variable_params(@dashboard)), class: "btn btn-info" %>
|
13
|
+
<%= link_to "Edit", edit_dashboard_path(@dashboard, params: variable_params(@dashboard)), class: "btn btn-info" %>
|
14
14
|
</div>
|
15
15
|
</div>
|
16
16
|
</div>
|
@@ -21,7 +21,7 @@
|
|
21
21
|
<% if @data_sources.any? { |ds| ds.cache_mode != "off" } %>
|
22
22
|
<p class="text-muted" style="float: right;">
|
23
23
|
Some queries may be cached
|
24
|
-
<%= link_to "Refresh", refresh_dashboard_path(@dashboard, variable_params(@dashboard)), method: :post %>
|
24
|
+
<%= link_to "Refresh", refresh_dashboard_path(@dashboard, params: variable_params(@dashboard)), method: :post %>
|
25
25
|
</p>
|
26
26
|
<% end %>
|
27
27
|
|
@@ -33,13 +33,15 @@
|
|
33
33
|
|
34
34
|
<% @queries.each_with_index do |query, i| %>
|
35
35
|
<div class="chart-container">
|
36
|
-
<h4><%= link_to query.friendly_name, query_path(query, variable_params(query)), target: "_blank" %></h4>
|
36
|
+
<h4><%= link_to query.friendly_name, query_path(query, params: variable_params(query)), target: "_blank" %></h4>
|
37
37
|
<div id="chart-<%= i %>" class="chart">
|
38
38
|
<p class="text-muted">Loading...</p>
|
39
39
|
</div>
|
40
40
|
</div>
|
41
41
|
<script>
|
42
|
-
|
42
|
+
<% data = {statement: query.statement, query_id: query.id, data_source: query.data_source, variables: variable_params(query), only_chart: true} %>
|
43
|
+
<% data.merge!(cohort_period: params[:cohort_period]) if params[:cohort_period] %>
|
44
|
+
<%= blazer_js_var "data", data %>
|
43
45
|
|
44
46
|
runQuery(data, function (data) {
|
45
47
|
$("#chart-<%= i %>").html(data)
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<% end %>
|
11
11
|
|
12
12
|
<% if @query && params[:query_id] %>
|
13
|
-
<%= link_to "Refresh", refresh_query_path(@query, variable_params(@query)), method: :post %>
|
13
|
+
<%= link_to "Refresh", refresh_query_path(@query, params: variable_params(@query, @var_params)), method: :post %>
|
14
14
|
<% end %>
|
15
15
|
</p>
|
16
16
|
<% end %>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<% end %>
|
4
4
|
|
5
5
|
<div id="app" v-cloak>
|
6
|
-
<%= form_for @query, url: (@query.persisted? ? query_path(@query, variable_params(@query)) : queries_path(variable_params(@query))), html: {autocomplete: "off"} do |f| %>
|
6
|
+
<%= form_for @query, url: (@query.persisted? ? query_path(@query, params: variable_params(@query)) : queries_path(params: variable_params(@query))), html: {autocomplete: "off"} do |f| %>
|
7
7
|
<div class="row">
|
8
8
|
<div id="statement-box" class="col-xs-8">
|
9
9
|
<div class= "form-group">
|
@@ -67,7 +67,7 @@
|
|
67
67
|
</div>
|
68
68
|
|
69
69
|
<script>
|
70
|
-
<%= blazer_js_var "
|
70
|
+
<%= blazer_js_var "variableParams", variable_params(@query) %>
|
71
71
|
<%= blazer_js_var "previewStatement", Hash[Blazer.data_sources.map { |k, v| [k, (v.preview_statement rescue "")] }] %>
|
72
72
|
|
73
73
|
var app = new Vue({
|
@@ -95,7 +95,7 @@
|
|
95
95
|
this.error = false
|
96
96
|
cancelAllQueries()
|
97
97
|
|
98
|
-
var data =
|
98
|
+
var data = {statement: this.getSQL(), data_source: $("#query_data_source").val(), variables: variableParams}
|
99
99
|
|
100
100
|
var _this = this
|
101
101
|
|
@@ -31,7 +31,7 @@
|
|
31
31
|
|
32
32
|
<% if @query && @result.forecastable? && !params[:forecast] %>
|
33
33
|
·
|
34
|
-
<%= link_to "Forecast", query_path(@query, {forecast: "t"}.merge(variable_params(@query))) %>
|
34
|
+
<%= link_to "Forecast", query_path(@query, params: {forecast: "t"}.merge(variable_params(@query))) %>
|
35
35
|
<% end %>
|
36
36
|
</p>
|
37
37
|
<% end %>
|
@@ -73,12 +73,14 @@
|
|
73
73
|
<% series_library[1] = {borderDash: [8], borderColor: color, pointBackgroundColor: color, backgroundColor: color, pointHoverBackgroundColor: color} %>
|
74
74
|
<% end %>
|
75
75
|
<% if blazer_maps? && @markers.any? %>
|
76
|
-
|
76
|
+
<% map_id = SecureRandom.hex %>
|
77
|
+
<%= content_tag :div, nil, id: map_id, style: "height: #{@only_chart ? 300 : 500}px;" %>
|
77
78
|
<script>
|
78
79
|
<%= blazer_js_var "mapboxAccessToken", Blazer.mapbox_access_token %>
|
79
80
|
<%= blazer_js_var "markers", @markers %>
|
81
|
+
<%= blazer_js_var "mapId", map_id %>
|
80
82
|
L.mapbox.accessToken = mapboxAccessToken;
|
81
|
-
var map = L.mapbox.map(
|
83
|
+
var map = L.mapbox.map(mapId)
|
82
84
|
.addLayer(L.mapbox.styleLayer('mapbox://styles/mapbox/streets-v11'));
|
83
85
|
var featureLayer = L.mapbox.featureLayer().addTo(map);
|
84
86
|
var geojson = [];
|
@@ -1,5 +1,12 @@
|
|
1
1
|
<% blazer_title @query.name %>
|
2
2
|
|
3
|
+
<% if @success %>
|
4
|
+
<% run_data = {statement: @query.statement, query_id: @query.id, data_source: @query.data_source, variables: variable_params(@query)} %>
|
5
|
+
<% run_data.merge!(forecast: "t") if params[:forecast] %>
|
6
|
+
<% run_data.merge!(cohort_period: params[:cohort_period]) if params[:cohort_period] %>
|
7
|
+
<% run_data.transform_keys!(&:to_s) if Rails::VERSION::STRING.to_f == 5.0 %>
|
8
|
+
<% end %>
|
9
|
+
|
3
10
|
<div class="topbar">
|
4
11
|
<div class="container">
|
5
12
|
<div class="row" style="padding-top: 13px;">
|
@@ -10,11 +17,11 @@
|
|
10
17
|
</h3>
|
11
18
|
</div>
|
12
19
|
<div class="col-sm-3 text-right">
|
13
|
-
<%= link_to "Edit", edit_query_path(@query, variable_params(@query)), class: "btn btn-default", disabled: !@query.editable?(blazer_user) %>
|
14
|
-
<%= link_to "Fork", new_query_path(variable_params(@query).merge(fork_query_id: @query.id, data_source: @query.data_source, name: @query.name)), class: "btn btn-info" %>
|
20
|
+
<%= link_to "Edit", edit_query_path(@query, params: variable_params(@query)), class: "btn btn-default", disabled: !@query.editable?(blazer_user) %>
|
21
|
+
<%= link_to "Fork", new_query_path(params: variable_params(@query).merge(fork_query_id: @query.id, data_source: @query.data_source, name: @query.name)), class: "btn btn-info" %>
|
15
22
|
|
16
23
|
<% if !@error && @success %>
|
17
|
-
<%= button_to "Download", run_queries_path(
|
24
|
+
<%= button_to "Download", run_queries_path(format: "csv"), params: run_data, class: "btn btn-primary" %>
|
18
25
|
<% end %>
|
19
26
|
</div>
|
20
27
|
</div>
|
@@ -39,7 +46,7 @@
|
|
39
46
|
|
40
47
|
<%= render partial: "blazer/variables", locals: {action: query_path(@query)} %>
|
41
48
|
|
42
|
-
<pre id="code"><code><%= @statement %></code></pre>
|
49
|
+
<pre id="code"><code><%= @statement.display_statement %></code></pre>
|
43
50
|
|
44
51
|
<% if @success %>
|
45
52
|
<div id="results">
|
@@ -56,9 +63,7 @@
|
|
56
63
|
$("#results").addClass("query-error").html(message)
|
57
64
|
}
|
58
65
|
|
59
|
-
|
60
|
-
<% data.merge!(forecast: "t") if params[:forecast] %>
|
61
|
-
<%= blazer_js_var "data", data %>
|
66
|
+
<%= blazer_js_var "data", run_data %>
|
62
67
|
|
63
68
|
runQuery(data, showRun, showError)
|
64
69
|
</script>
|
@@ -5,8 +5,13 @@
|
|
5
5
|
|
6
6
|
<meta charset="utf-8" />
|
7
7
|
<%= favicon_link_tag "blazer/favicon.png" %>
|
8
|
-
|
9
|
-
|
8
|
+
<% if defined?(Propshaft::Railtie) %>
|
9
|
+
<%= stylesheet_link_tag "blazer/bootstrap-propshaft", "blazer/bootstrap", "blazer/selectize", "blazer/github", "blazer/daterangepicker", "blazer/application" %>
|
10
|
+
<%= javascript_include_tag "blazer/jquery", "blazer/jquery-ujs", "blazer/stupidtable", "blazer/stupidtable-custom-settings", "blazer/jquery.stickytableheaders", "blazer/selectize", "blazer/highlight.min", "blazer/moment", "blazer/moment-timezone-with-data", "blazer/daterangepicker", "blazer/Chart.js", "blazer/chartkick", "blazer/ace/ace", "blazer/ace/ext-language_tools", "blazer/ace/theme-twilight", "blazer/ace/mode-sql", "blazer/ace/snippets/text", "blazer/ace/snippets/sql", "blazer/Sortable", "blazer/bootstrap", "blazer/vue", "blazer/routes", "blazer/queries", "blazer/fuzzysearch", "blazer/application" %>
|
11
|
+
<% else %>
|
12
|
+
<%= stylesheet_link_tag "blazer/application" %>
|
13
|
+
<%= javascript_include_tag "blazer/application" %>
|
14
|
+
<% end %>
|
10
15
|
<script>
|
11
16
|
<%= blazer_js_var "rootPath", root_path %>
|
12
17
|
</script>
|