blazer 1.7.3 → 1.7.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of blazer might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6bdae12ea224ba2311ce33fdbc05dffbbc938cee
4
- data.tar.gz: 635a76501e3608e8a188cdfdc3186b497e6337fd
3
+ metadata.gz: cb091c8d95137cd458bfffee889e305a70dbed00
4
+ data.tar.gz: 338d05021f268691eb51b2861b41eff1a4b9135a
5
5
  SHA512:
6
- metadata.gz: 9e81386804c7030a74a75f959f936e3ff0053c9e8e2a17f78cff84897850942f124a989f7258d429e836b0aeacf8a138f59e47ed5a35ac8686f37ecdfbd77222
7
- data.tar.gz: f1c1da1a30477aae06877313f2130b6a6140962a31c29761938b04fad93baad8cb036fcd79a24f91c52212690f0cecd3dde7d563ecde799370fa61aac2a70353
6
+ metadata.gz: ec12d42ac8fb5618abb2849860178c0ccd3778f8ceef897a3073f9fa9339ddf38149bf39c970bd0c1b12c91e82f88ef27bcd8fcc5b9530f725e20dead78794b1
7
+ data.tar.gz: e863ec4b74f606885ffc15dd095cd5ee14fc9cc2283085fdf2fb04e6cbaaeb83a899cebe9a62eb17399c45f8c28aa2979e1355b308ae15b61cccc097ddde6d56
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 1.7.4
2
+
3
+ - Removed extra dependencies added in 1.7.1
4
+ - Fixed `send_failing_checks` for default Rails 5 ActiveJob adapter
5
+
1
6
  ## 1.7.3
2
7
 
3
8
  - Fixed JavaScript errors
@@ -0,0 +1,23 @@
1
+ var Routes = {
2
+ run_queries_path: function() {
3
+ return rootPath + "queries/run"
4
+ },
5
+ cancel_queries_path: function() {
6
+ return rootPath + "queries/cancel"
7
+ },
8
+ schema_queries_path: function(params) {
9
+ return rootPath + "queries/schema?" + $.param(params)
10
+ },
11
+ tables_queries_path: function(params) {
12
+ return rootPath + "queries/tables?" + $.param(params)
13
+ },
14
+ queries_path: function() {
15
+ return rootPath + "queries"
16
+ },
17
+ query_path: function(id) {
18
+ return rootPath + "queries/" + id
19
+ },
20
+ dashboard_path: function(id) {
21
+ return rootPath + "dashboards/" + id
22
+ }
23
+ }
@@ -151,6 +151,8 @@ input.search:focus {
151
151
  cursor: pointer;
152
152
  color: #d9534f;
153
153
  display: none;
154
+ float: right;
155
+ margin-top: 3px;
154
156
  }
155
157
 
156
158
  .list-group li:hover .glyphicon-remove {
@@ -190,3 +192,7 @@ input.search:focus {
190
192
  .chart-container h4 a {
191
193
  color: inherit;
192
194
  }
195
+
196
+ .query-error {
197
+ color: red;
198
+ }
@@ -19,94 +19,87 @@ module Blazer
19
19
  if Blazer.before_action
20
20
  before_action Blazer.before_action.to_sym
21
21
  end
22
- before_action :set_js_routes
23
22
 
24
23
  layout "blazer/application"
25
24
 
26
25
  private
27
26
 
28
- def process_vars(statement, data_source)
29
- (@bind_vars ||= []).concat(extract_vars(statement)).uniq!
30
- @bind_vars.each do |var|
31
- params[var] ||= Blazer.data_sources[data_source].variable_defaults[var]
32
- end
33
- @success = @bind_vars.all? { |v| params[v] }
34
-
35
- if @success
27
+ def process_vars(statement, data_source)
28
+ (@bind_vars ||= []).concat(extract_vars(statement)).uniq!
36
29
  @bind_vars.each do |var|
37
- value = params[var].presence
38
- if value
39
- if ["start_time", "end_time"].include?(var)
40
- value = value.to_s.gsub(" ", "+") # fix for Quip bug
41
- end
30
+ params[var] ||= Blazer.data_sources[data_source].variable_defaults[var]
31
+ end
32
+ @success = @bind_vars.all? { |v| params[v] }
33
+
34
+ if @success
35
+ @bind_vars.each do |var|
36
+ value = params[var].presence
37
+ if value
38
+ if ["start_time", "end_time"].include?(var)
39
+ value = value.to_s.gsub(" ", "+") # fix for Quip bug
40
+ end
42
41
 
43
- if var.end_with?("_at")
44
- begin
45
- value = Blazer.time_zone.parse(value)
46
- rescue
47
- # do nothing
42
+ if var.end_with?("_at")
43
+ begin
44
+ value = Blazer.time_zone.parse(value)
45
+ rescue
46
+ # do nothing
47
+ end
48
48
  end
49
- end
50
49
 
51
- if value =~ /\A\d+\z/
52
- value = value.to_i
53
- elsif value =~ /\A\d+\.\d+\z/
54
- value = value.to_f
50
+ if value =~ /\A\d+\z/
51
+ value = value.to_i
52
+ elsif value =~ /\A\d+\.\d+\z/
53
+ value = value.to_f
54
+ end
55
55
  end
56
+ statement.gsub!("{#{var}}", ActiveRecord::Base.connection.quote(value))
56
57
  end
57
- statement.gsub!("{#{var}}", ActiveRecord::Base.connection.quote(value))
58
58
  end
59
59
  end
60
- end
61
60
 
62
- def parse_smart_variables(var, data_source)
63
- smart_var_data_source =
64
- ([data_source] + Array(data_source.settings["inherit_smart_settings"]).map { |ds| Blazer.data_sources[ds] }).find { |ds| ds.smart_variables[var] }
65
-
66
- if smart_var_data_source
67
- query = smart_var_data_source.smart_variables[var]
68
-
69
- if query.is_a? Hash
70
- smart_var = query.map { |k,v| [v, k] }
71
- elsif query.is_a? Array
72
- smart_var = query.map { |v| [v, v] }
73
- elsif query
74
- result = smart_var_data_source.run_statement(query)
75
- smart_var = result.rows.map { |v| v.reverse }
76
- error = result.error if result.error
61
+ def parse_smart_variables(var, data_source)
62
+ smart_var_data_source =
63
+ ([data_source] + Array(data_source.settings["inherit_smart_settings"]).map { |ds| Blazer.data_sources[ds] }).find { |ds| ds.smart_variables[var] }
64
+
65
+ if smart_var_data_source
66
+ query = smart_var_data_source.smart_variables[var]
67
+
68
+ if query.is_a? Hash
69
+ smart_var = query.map { |k,v| [v, k] }
70
+ elsif query.is_a? Array
71
+ smart_var = query.map { |v| [v, v] }
72
+ elsif query
73
+ result = smart_var_data_source.run_statement(query)
74
+ smart_var = result.rows.map { |v| v.reverse }
75
+ error = result.error if result.error
76
+ end
77
77
  end
78
- end
79
-
80
- [smart_var, error]
81
- end
82
78
 
83
- def extract_vars(statement)
84
- # strip commented out lines
85
- # and regex {1} or {1,2}
86
- statement.gsub(/\-\-.+/, "").gsub(/\/\*.+\*\//m, "").scan(/\{\w*?\}/i).map { |v| v[1...-1] }.reject { |v| /\A\d+(\,\d+)?\z/.match(v) || v.empty? }.uniq
87
- end
88
- helper_method :extract_vars
79
+ [smart_var, error]
80
+ end
89
81
 
90
- def variable_params
91
- params.except(: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).permit!
92
- end
93
- helper_method :variable_params
82
+ def extract_vars(statement)
83
+ # strip commented out lines
84
+ # and regex {1} or {1,2}
85
+ statement.gsub(/\-\-.+/, "").gsub(/\/\*.+\*\//m, "").scan(/\{\w*?\}/i).map { |v| v[1...-1] }.reject { |v| /\A\d+(\,\d+)?\z/.match(v) || v.empty? }.uniq
86
+ end
87
+ helper_method :extract_vars
94
88
 
95
- def blazer_user
96
- send(Blazer.user_method) if Blazer.user_method && respond_to?(Blazer.user_method)
97
- end
98
- helper_method :blazer_user
89
+ def variable_params
90
+ params.except(: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).permit!
91
+ end
92
+ helper_method :variable_params
99
93
 
100
- def render_errors(resource)
101
- @errors = resource.errors
102
- action = resource.persisted? ? :edit : :new
103
- render action, status: :unprocessable_entity
104
- end
94
+ def blazer_user
95
+ send(Blazer.user_method) if Blazer.user_method && respond_to?(Blazer.user_method)
96
+ end
97
+ helper_method :blazer_user
105
98
 
106
- def set_js_routes
107
- gon.push(
108
- root_path: root_path
109
- )
110
- end
99
+ def render_errors(resource)
100
+ @errors = resource.errors
101
+ action = resource.persisted? ? :edit : :new
102
+ render action, status: :unprocessable_entity
103
+ end
111
104
  end
112
105
  end
@@ -45,12 +45,12 @@ module Blazer
45
45
 
46
46
  private
47
47
 
48
- def check_params
49
- params.require(:check).permit(:query_id, :emails, :invert, :check_type, :schedule)
50
- end
48
+ def check_params
49
+ params.require(:check).permit(:query_id, :emails, :invert, :check_type, :schedule)
50
+ end
51
51
 
52
- def set_check
53
- @check = Blazer::Check.find(params[:id])
54
- end
52
+ def set_check
53
+ @check = Blazer::Check.find(params[:id])
54
+ end
55
55
  end
56
56
  end
@@ -69,37 +69,37 @@ module Blazer
69
69
  redirect_to dashboard_path(@dashboard, variable_params)
70
70
  end
71
71
 
72
- protected
72
+ private
73
73
 
74
- def dashboard_params
75
- params.require(:dashboard).permit(:name)
76
- end
74
+ def dashboard_params
75
+ params.require(:dashboard).permit(:name)
76
+ end
77
77
 
78
- def set_dashboard
79
- @dashboard = Blazer::Dashboard.find(params[:id])
80
- end
78
+ def set_dashboard
79
+ @dashboard = Blazer::Dashboard.find(params[:id])
80
+ end
81
81
 
82
- def update_dashboard(dashboard)
83
- dashboard.assign_attributes(dashboard_params)
84
- Blazer::Dashboard.transaction do
85
- if params[:query_ids].is_a?(Array)
86
- query_ids = params[:query_ids].map(&:to_i)
87
- @queries = Blazer::Query.find(query_ids).sort_by { |q| query_ids.index(q.id) }
88
- end
89
- if dashboard.save
90
- if @queries
91
- @queries.each_with_index do |query, i|
92
- dashboard_query = dashboard.dashboard_queries.where(query_id: query.id).first_or_initialize
93
- dashboard_query.position = i
94
- dashboard_query.save!
95
- end
96
- if dashboard.persisted?
97
- dashboard.dashboard_queries.where.not(query_id: query_ids).destroy_all
82
+ def update_dashboard(dashboard)
83
+ dashboard.assign_attributes(dashboard_params)
84
+ Blazer::Dashboard.transaction do
85
+ if params[:query_ids].is_a?(Array)
86
+ query_ids = params[:query_ids].map(&:to_i)
87
+ @queries = Blazer::Query.find(query_ids).sort_by { |q| query_ids.index(q.id) }
88
+ end
89
+ if dashboard.save
90
+ if @queries
91
+ @queries.each_with_index do |query, i|
92
+ dashboard_query = dashboard.dashboard_queries.where(query_id: query.id).first_or_initialize
93
+ dashboard_query.position = i
94
+ dashboard_query.save!
95
+ end
96
+ if dashboard.persisted?
97
+ dashboard.dashboard_queries.where.not(query_id: query_ids).destroy_all
98
+ end
98
99
  end
100
+ true
99
101
  end
100
- true
101
102
  end
102
103
  end
103
- end
104
104
  end
105
105
  end
@@ -26,12 +26,6 @@ module Blazer
26
26
  dashboard: true
27
27
  }
28
28
  end
29
-
30
- gon.push(
31
- dashboards: @dashboards,
32
- queries: @queries,
33
- more: @more
34
- )
35
29
  end
36
30
 
37
31
  def index
@@ -194,138 +188,138 @@ module Blazer
194
188
 
195
189
  private
196
190
 
197
- def continue_run
198
- render json: {run_id: @run_id, timestamp: @timestamp}, status: :accepted
199
- end
200
-
201
- def render_run
202
- @checks = @query ? @query.checks.order(:id) : []
203
-
204
- @first_row = @rows.first || []
205
- @column_types = []
206
- if @rows.any?
207
- @columns.each_with_index do |column, i|
208
- @column_types << (
209
- case @first_row[i]
210
- when Integer
211
- "int"
212
- when Float, BigDecimal
213
- "float"
214
- else
215
- "string-ins"
216
- end
217
- )
218
- end
191
+ def continue_run
192
+ render json: {run_id: @run_id, timestamp: @timestamp}, status: :accepted
219
193
  end
220
194
 
221
- @filename = @query.name.parameterize if @query
222
- @min_width_types = @columns.each_with_index.select { |c, i| @first_row[i].is_a?(Time) || @first_row[i].is_a?(String) || @data_source.smart_columns[c] }.map(&:last)
223
-
224
- @boom = @result.boom if @result
225
-
226
- @linked_columns = @data_source.linked_columns
227
-
228
- @markers = []
229
- [["latitude", "longitude"], ["lat", "lon"], ["lat", "lng"]].each do |keys|
230
- lat_index = @columns.index(keys.first)
231
- lon_index = @columns.index(keys.last)
232
- if lat_index && lon_index
233
- @markers =
234
- @rows.select do |r|
235
- r[lat_index] && r[lon_index]
236
- end.map do |r|
237
- {
238
- title: r.each_with_index.map{ |v, i| i == lat_index || i == lon_index ? nil : "<strong>#{@columns[i]}:</strong> #{v}" }.compact.join("<br />").truncate(140),
239
- latitude: r[lat_index],
240
- longitude: r[lon_index]
241
- }
242
- end
195
+ def render_run
196
+ @checks = @query ? @query.checks.order(:id) : []
197
+
198
+ @first_row = @rows.first || []
199
+ @column_types = []
200
+ if @rows.any?
201
+ @columns.each_with_index do |column, i|
202
+ @column_types << (
203
+ case @first_row[i]
204
+ when Integer
205
+ "int"
206
+ when Float, BigDecimal
207
+ "float"
208
+ else
209
+ "string-ins"
210
+ end
211
+ )
212
+ end
243
213
  end
244
- end
245
214
 
246
- respond_to do |format|
247
- format.html do
248
- render layout: false
215
+ @filename = @query.name.parameterize if @query
216
+ @min_width_types = @columns.each_with_index.select { |c, i| @first_row[i].is_a?(Time) || @first_row[i].is_a?(String) || @data_source.smart_columns[c] }.map(&:last)
217
+
218
+ @boom = @result.boom if @result
219
+
220
+ @linked_columns = @data_source.linked_columns
221
+
222
+ @markers = []
223
+ [["latitude", "longitude"], ["lat", "lon"], ["lat", "lng"]].each do |keys|
224
+ lat_index = @columns.index(keys.first)
225
+ lon_index = @columns.index(keys.last)
226
+ if lat_index && lon_index
227
+ @markers =
228
+ @rows.select do |r|
229
+ r[lat_index] && r[lon_index]
230
+ end.map do |r|
231
+ {
232
+ title: r.each_with_index.map{ |v, i| i == lat_index || i == lon_index ? nil : "<strong>#{@columns[i]}:</strong> #{v}" }.compact.join("<br />").truncate(140),
233
+ latitude: r[lat_index],
234
+ longitude: r[lon_index]
235
+ }
236
+ end
237
+ end
249
238
  end
250
- format.csv do
251
- 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\""
239
+
240
+ respond_to do |format|
241
+ format.html do
242
+ render layout: false
243
+ end
244
+ format.csv do
245
+ 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\""
246
+ end
252
247
  end
253
248
  end
254
- end
255
249
 
256
- def set_queries(limit = nil)
257
- @my_queries =
258
- if limit && blazer_user && !params[:filter] && Blazer.audit
259
- queries_by_ids(Blazer::Audit.where(user_id: blazer_user.id).where("created_at > ?", 30.days.ago).where("query_id IS NOT NULL").group(:query_id).order("count_all desc").count.keys)
260
- else
261
- []
262
- end
250
+ def set_queries(limit = nil)
251
+ @my_queries =
252
+ if limit && blazer_user && !params[:filter] && Blazer.audit
253
+ queries_by_ids(Blazer::Audit.where(user_id: blazer_user.id).where("created_at > ?", 30.days.ago).where("query_id IS NOT NULL").group(:query_id).order("count_all desc").count.keys)
254
+ else
255
+ []
256
+ end
263
257
 
264
- @queries = Blazer::Query.named.select(:id, :name, :creator_id, :statement)
265
- @queries = @queries.includes(:creator) if Blazer.user_class
258
+ @queries = Blazer::Query.named.select(:id, :name, :creator_id, :statement)
259
+ @queries = @queries.includes(:creator) if Blazer.user_class
266
260
 
267
- if blazer_user && params[:filter] == "mine"
268
- @queries = @queries.where(creator_id: blazer_user.id).reorder(updated_at: :desc)
269
- elsif blazer_user && params[:filter] == "viewed" && Blazer.audit
270
- @queries = queries_by_ids(Blazer::Audit.where(user_id: blazer_user.id).order(created_at: :desc).limit(500).pluck(:query_id).uniq)
271
- else
272
- @queries = @queries.where("id NOT IN (?)", @my_queries.map(&:id)) if @my_queries.any?
273
- @queries = @queries.limit(limit) if limit
274
- @queries = @queries.order(:name)
275
- end
276
- @queries = @queries.to_a
261
+ if blazer_user && params[:filter] == "mine"
262
+ @queries = @queries.where(creator_id: blazer_user.id).reorder(updated_at: :desc)
263
+ elsif blazer_user && params[:filter] == "viewed" && Blazer.audit
264
+ @queries = queries_by_ids(Blazer::Audit.where(user_id: blazer_user.id).order(created_at: :desc).limit(500).pluck(:query_id).uniq)
265
+ else
266
+ @queries = @queries.where("id NOT IN (?)", @my_queries.map(&:id)) if @my_queries.any?
267
+ @queries = @queries.limit(limit) if limit
268
+ @queries = @queries.order(:name)
269
+ end
270
+ @queries = @queries.to_a
277
271
 
278
- @more = limit && @queries.size >= limit
272
+ @more = limit && @queries.size >= limit
279
273
 
280
- @queries = (@my_queries + @queries).select { |q| !q.name.to_s.start_with?("#") || q.try(:creator).try(:id) == blazer_user.try(:id) }
274
+ @queries = (@my_queries + @queries).select { |q| !q.name.to_s.start_with?("#") || q.try(:creator).try(:id) == blazer_user.try(:id) }
281
275
 
282
- @queries =
283
- @queries.map do |q|
284
- {
285
- id: q.id,
286
- name: q.name,
287
- creator: blazer_user && q.try(:creator) == blazer_user ? "You" : q.try(:creator).try(Blazer.user_name),
288
- vars: extract_vars(q.statement).join(", "),
289
- to_param: q.to_param
290
- }
291
- end
292
- end
276
+ @queries =
277
+ @queries.map do |q|
278
+ {
279
+ id: q.id,
280
+ name: q.name,
281
+ creator: blazer_user && q.try(:creator) == blazer_user ? "You" : q.try(:creator).try(Blazer.user_name),
282
+ vars: extract_vars(q.statement).join(", "),
283
+ to_param: q.to_param
284
+ }
285
+ end
286
+ end
293
287
 
294
- def queries_by_ids(favorite_query_ids)
295
- queries = Blazer::Query.named.where(id: favorite_query_ids)
296
- queries = queries.includes(:creator) if Blazer.user_class
297
- queries = queries.index_by(&:id)
298
- favorite_query_ids.map { |query_id| queries[query_id] }.compact
299
- end
288
+ def queries_by_ids(favorite_query_ids)
289
+ queries = Blazer::Query.named.where(id: favorite_query_ids)
290
+ queries = queries.includes(:creator) if Blazer.user_class
291
+ queries = queries.index_by(&:id)
292
+ favorite_query_ids.map { |query_id| queries[query_id] }.compact
293
+ end
300
294
 
301
- def set_query
302
- @query = Blazer::Query.find(params[:id].to_s.split("-").first)
303
- end
295
+ def set_query
296
+ @query = Blazer::Query.find(params[:id].to_s.split("-").first)
297
+ end
304
298
 
305
- def query_params
306
- params.require(:query).permit(:name, :description, :statement, :data_source)
307
- end
299
+ def query_params
300
+ params.require(:query).permit(:name, :description, :statement, :data_source)
301
+ end
308
302
 
309
- def blazer_params
310
- params[:blazer] || {}
311
- end
303
+ def blazer_params
304
+ params[:blazer] || {}
305
+ end
312
306
 
313
- def csv_data(columns, rows, data_source)
314
- CSV.generate do |csv|
315
- csv << columns
316
- rows.each do |row|
317
- csv << row.each_with_index.map { |v, i| v.is_a?(Time) ? blazer_time_value(data_source, columns[i], v) : v }
307
+ def csv_data(columns, rows, data_source)
308
+ CSV.generate do |csv|
309
+ csv << columns
310
+ rows.each do |row|
311
+ csv << row.each_with_index.map { |v, i| v.is_a?(Time) ? blazer_time_value(data_source, columns[i], v) : v }
312
+ end
318
313
  end
319
314
  end
320
- end
321
315
 
322
- def blazer_time_value(data_source, k, v)
323
- data_source.local_time_suffix.any? { |s| k.ends_with?(s) } ? v.to_s.sub(" UTC", "") : v.in_time_zone(Blazer.time_zone)
324
- end
325
- helper_method :blazer_time_value
316
+ def blazer_time_value(data_source, k, v)
317
+ data_source.local_time_suffix.any? { |s| k.ends_with?(s) } ? v.to_s.sub(" UTC", "") : v.in_time_zone(Blazer.time_zone)
318
+ end
319
+ helper_method :blazer_time_value
326
320
 
327
- def blazer_run_id
328
- params[:run_id].to_s.gsub(/[^a-z0-9\-]/i, "")
329
- end
321
+ def blazer_run_id
322
+ params[:run_id].to_s.gsub(/[^a-z0-9\-]/i, "")
323
+ end
330
324
  end
331
325
  end
@@ -32,6 +32,10 @@ module Blazer
32
32
  ENV["MAPBOX_ACCESS_TOKEN"].present?
33
33
  end
34
34
 
35
+ def blazer_js_var(name, value)
36
+ "var #{name} = #{blazer_json_escape(value.to_json)}".html_safe
37
+ end
38
+
35
39
  JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003e', '<' => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
36
40
  JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
37
41
 
@@ -44,24 +44,24 @@
44
44
  </div>
45
45
 
46
46
  <script>
47
- var timeZone = "<%= Blazer.time_zone.tzinfo.name %>";
48
- var format = "YYYY-MM-DD";
49
- var now = moment.tz(timeZone);
47
+ <%= blazer_js_var "timeZone", Blazer.time_zone.tzinfo.name %>
48
+ var format = "YYYY-MM-DD"
49
+ var now = moment.tz(timeZone)
50
50
 
51
51
  function dateStr(daysAgo) {
52
- return now.clone().subtract(daysAgo || 0, "days").format(format);
52
+ return now.clone().subtract(daysAgo || 0, "days").format(format)
53
53
  }
54
54
 
55
55
  function toDate(time) {
56
- return moment.tz(time.format(format), timeZone);
56
+ return moment.tz(time.format(format), timeZone)
57
57
  }
58
58
 
59
59
  function setTimeInputs(start, end) {
60
- $("#start_time").val(toDate(start).utc().format());
61
- $("#end_time").val(toDate(end).endOf("day").utc().format());
60
+ $("#start_time").val(toDate(start).utc().format())
61
+ $("#end_time").val(toDate(end).endOf("day").utc().format())
62
62
  }
63
63
 
64
- $('#reportrange').daterangepicker(
64
+ $("#reportrange").daterangepicker(
65
65
  {
66
66
  ranges: {
67
67
  "Today": [dateStr(), dateStr()],
@@ -76,23 +76,23 @@
76
76
  opens: "right"
77
77
  },
78
78
  function(start, end) {
79
- setTimeInputs(start, end);
80
- submitIfCompleted($("#start_time").closest("form"));
79
+ setTimeInputs(start, end)
80
+ submitIfCompleted($("#start_time").closest("form"))
81
81
  }
82
- ).on('apply.daterangepicker', function(ev, picker) {
83
- setTimeInputs(picker.startDate, picker.endDate);
84
- $('#reportrange span').html(toDate(picker.startDate).format('MMMM D, YYYY') + ' - ' + toDate(picker.endDate).format('MMMM D, YYYY'));
82
+ ).on("apply.daterangepicker", function(ev, picker) {
83
+ setTimeInputs(picker.startDate, picker.endDate)
84
+ $("#reportrange span").html(toDate(picker.startDate).format("MMMM D, YYYY") + " - " + toDate(picker.endDate).format("MMMM D, YYYY"))
85
85
  })
86
86
 
87
87
  if ($("#start_time").val().length > 0) {
88
- var picker = $("#reportrange").data('daterangepicker');
89
- picker.setStartDate(moment.tz($("#start_time").val(), timeZone));
90
- picker.setEndDate(moment.tz($("#end_time").val(), timeZone));
91
- $("#reportrange").trigger('apply.daterangepicker', picker)
88
+ var picker = $("#reportrange").data("daterangepicker")
89
+ picker.setStartDate(moment.tz($("#start_time").val(), timeZone))
90
+ picker.setEndDate(moment.tz($("#end_time").val(), timeZone))
91
+ $("#reportrange").trigger("apply.daterangepicker", picker)
92
92
  } else {
93
- var picker = $("#reportrange").data('daterangepicker');
94
- $("#reportrange").trigger('apply.daterangepicker', picker);
95
- submitIfCompleted($("#start_time").closest("form"));
93
+ var picker = $("#reportrange").data("daterangepicker")
94
+ $("#reportrange").trigger("apply.daterangepicker", picker)
95
+ submitIfCompleted($("#start_time").closest("form"))
96
96
  }
97
97
  </script>
98
98
  <% end %>
@@ -6,15 +6,22 @@
6
6
  <% if @error %>
7
7
  <p><%= @error %></p>
8
8
  <% elsif @rows_count > 0 && @check_type == "bad_data" %>
9
- <p><%= pluralize(@rows_count, "row") %></p>
10
- <p><strong>Sample</strong></p>
9
+ <p>
10
+ <% if @rows_count <= 10 %>
11
+ <%= pluralize(@rows_count, "row") %>
12
+ <% else %>
13
+ Showing 10 of <%= @rows_count %> rows
14
+ <% end %>
15
+ </p>
11
16
  <table style="width: 100%; border-spacing: 0; border-collapse: collapse;">
12
17
  <thead>
13
- <% @columns.first(5).each do |column| %>
14
- <th style="padding: 8px; line-height: 1.4; text-align: left; vertical-align: bottom; border-bottom: 2px solid #ddd; width: <%= (100 / @columns.size).round(2) %>%;">
15
- <%= column %>
16
- </th>
17
- <% end %>
18
+ <tr>
19
+ <% @columns.first(5).each do |column| %>
20
+ <th style="padding: 8px; line-height: 1.4; text-align: left; vertical-align: bottom; border-bottom: 2px solid #ddd; width: <%= (100 / @columns.size).round(2) %>%;">
21
+ <%= column %>
22
+ </th>
23
+ <% end %>
24
+ </tr>
18
25
  </thead>
19
26
  <tbody>
20
27
  <% @rows.first(10).each do |row| %>
@@ -32,6 +39,9 @@
32
39
  <% end %>
33
40
  </tbody>
34
41
  </table>
42
+ <% if @columns.size > 5 %>
43
+ <p style="color: #999;">Only first 5 columns shown</p>
44
+ <% end %>
35
45
  <% end %>
36
46
  </body>
37
47
  </html>
@@ -13,8 +13,8 @@
13
13
  <%= f.select :query_id, [], {include_blank: true} %>
14
14
  </div>
15
15
  <script>
16
- var queries = <%= blazer_json_escape(Blazer::Query.named.order(:name).select("id, name").map { |q| {text: q.name, value: q.id} }.to_json).html_safe %>;
17
- var items = <%= blazer_json_escape([@check.query_id].compact.to_json).html_safe %>;
16
+ <%= blazer_js_var "queries", Blazer::Query.named.order(:name).select("id, name").map { |q| {text: q.name, value: q.id} } %>
17
+ <%= blazer_js_var "items", [@check.query_id].compact %>
18
18
 
19
19
  $("#check_query_id").selectize({options: queries, items: items, highlight: false, maxOptions: 100}).parents(".hide").removeClass("hide");
20
20
  </script>
@@ -2,46 +2,26 @@
2
2
  <div class="alert alert-danger"><%= @dashboard.errors.full_messages.first %></div>
3
3
  <% end %>
4
4
 
5
- <%= form_for @dashboard, url: (@dashboard.persisted? ? dashboard_path(@dashboard, variable_params) : dashboards_path(variable_params)) do |f| %>
5
+ <%= form_for @dashboard, url: (@dashboard.persisted? ? dashboard_path(@dashboard, variable_params) : dashboards_path(variable_params)), html: {id: "app"} do |f| %>
6
6
  <div class="form-group">
7
7
  <%= f.label :name %>
8
8
  <%= f.text_field :name, class: "form-control" %>
9
9
  </div>
10
- <div class="form-group <%= "hide" if (@queries || @dashboard.queries).empty? %>">
10
+ <div class="form-group" v-if="queries.length">
11
11
  <%= f.label :charts %>
12
- <ul class="list-group">
13
- <% (@queries || @dashboard.dashboard_queries.order(:position).map(&:query)).each do |query| %>
14
- <li class="list-group-item">
15
- <span class="glyphicon glyphicon-remove" aria-hidden="true" style="float: right; margin-top: 3px;"></span>
16
- <%= query.name %>
17
- <%= hidden_field_tag "query_ids[]", query.id %>
18
- </li>
19
- <% end %>
12
+ <ul id="queries" class="list-group">
13
+ <li class="list-group-item" v-for="(query, index) in queries" :key="query.id" v-cloak>
14
+ <span class="glyphicon glyphicon-remove" aria-hidden="true" v-on:click="remove(index)"></span>
15
+ {{ query.name }}
16
+ <input type="hidden" name="query_ids[]" :value="query.id">
17
+ </li>
20
18
  </ul>
21
19
  </div>
22
- <div class="form-group">
20
+ <div class="form-group" v-cloak>
23
21
  <%= f.label :query_id, "Add Chart" %>
24
- <div class="hide">
25
- <%= select_tag :query_id, nil, {include_blank: true, placeholder: "Select chart"} %>
26
- </div>
27
- <script>
28
- var queries = <%= blazer_json_escape(Blazer::Query.named.order(:name).select("id, name").map { |q| {text: q.name, value: q.id} }.to_json).html_safe %>;
29
- $("#query_id").selectize({options: queries, highlight: false, maxOptions: 100}).parents(".hide").removeClass("hide");
30
- $("#query_id").change( function () {
31
- var $option = $(this).find("option:selected");
32
- if ($option.val() !== "") {
33
- var $li = $("<li></li>");
34
- $li.addClass("list-group-item");
35
- $li.text($option.text());
36
- $li.prepend('<span class="glyphicon glyphicon-remove" aria-hidden="true" style="float: right; margin-top: 3px;"></span><input type="hidden" name="query_ids[]" id="query_ids_" value="' + $option.val() + '">');
37
- $(".list-group").append($li);
38
- $(this)[0].selectize.setValue("");
39
- $(".form-group").removeClass("hide");
40
- }
41
- });
42
- </script>
22
+ <%= select_tag :query_id, nil, {include_blank: true, placeholder: "Select chart"} %>
43
23
  </div>
44
- <p>
24
+ <p style="padding-bottom: 140px;" v-cloak>
45
25
  <% if @dashboard.persisted? %>
46
26
  <%= link_to "Delete", dashboard_path(@dashboard), method: :delete, "data-confirm" => "Are you sure?", class: "btn btn-danger"%>
47
27
  <% end %>
@@ -51,8 +31,46 @@
51
31
  <% end %>
52
32
 
53
33
  <script>
54
- $(".list-group").on("click", ".glyphicon-remove", function () {
55
- $(this).parents("li:first").remove();
56
- });
57
- Sortable.create($(".list-group").get(0));
34
+ <%= blazer_js_var "queries", Blazer::Query.named.order(:name).select("id, name").map { |q| {text: q.name, value: q.id} } %>
35
+ <%= blazer_js_var "dashboardQueries", @queries || @dashboard.dashboard_queries.order(:position).map(&:query) %>
36
+
37
+ var app = new Vue({
38
+ el: "#app",
39
+ data: {
40
+ queries: dashboardQueries
41
+ },
42
+ methods: {
43
+ remove: function(index) {
44
+ this.queries.splice(index, 1)
45
+ }
46
+ },
47
+ mounted: function() {
48
+ $("#query_id").selectize({
49
+ options: queries,
50
+ highlight: false,
51
+ maxOptions: 100,
52
+ onChange: function(val) {
53
+ if (val) {
54
+ var item = this.getItem(val)
55
+
56
+ // if duplicate query is added, remove the first one
57
+ for (var i = 0; i < app.queries.length; i++) {
58
+ if (app.queries[i].id == val) {
59
+ app.queries.splice(i, 1)
60
+ break
61
+ }
62
+ }
63
+
64
+ app.queries.push({id: val, name: item.text()})
65
+ this.setValue("")
66
+ }
67
+ }
68
+ })
69
+ }
70
+ })
71
+ Sortable.create($("#queries").get(0), {
72
+ onEnd: function(e) {
73
+ app.queries.splice(e.newIndex, 0, app.queries.splice(e.oldIndex, 1)[0])
74
+ }
75
+ })
58
76
  </script>
@@ -35,13 +35,13 @@
35
35
  </div>
36
36
  </div>
37
37
  <script>
38
- var data = <%= blazer_json_escape({statement: query.statement, query_id: query.id, only_chart: true}.to_json).html_safe %>;
38
+ <%= blazer_js_var "data", {statement: query.statement, query_id: query.id, only_chart: true} %>
39
39
 
40
40
  runQuery(data, function (data) {
41
- $("#chart-<%= i %>").html(data);
42
- $("#chart-<%= i %> table").stupidtable();
41
+ $("#chart-<%= i %>").html(data)
42
+ $("#chart-<%= i %> table").stupidtable()
43
43
  }, function (message) {
44
- $("#chart-<%= i %>").css("color", "red").html(message);
44
+ $("#chart-<%= i %>").addClass("query-error").html(message)
45
45
  });
46
46
  </script>
47
47
  <% 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) : queries_path(variable_params)), html: {class: "the_form", autocomplete: "off"} do |f| %>
6
+ <%= form_for @query, url: (@query.persisted? ? query_path(@query, variable_params) : queries_path(variable_params)), 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">
@@ -60,19 +60,20 @@
60
60
 
61
61
  <div id="results">
62
62
  <p class="text-muted" v-if="running">Loading...</p>
63
- <div id="results-html" v-if="!running"></div>
63
+ <div id="results-html" v-if="!running" :class="{ 'query-error': error }"></div>
64
64
  </div>
65
65
  </div>
66
66
 
67
67
  <script>
68
- var params = <%= raw blazer_json_escape(variable_params.to_json) %>;
69
- var previewStatement = <%= raw blazer_json_escape(Hash[Blazer.data_sources.map { |k, v| [k, v.preview_statement] }].to_json) %>;
68
+ <%= blazer_js_var "params", variable_params %>
69
+ <%= blazer_js_var "previewStatement", Hash[Blazer.data_sources.map { |k, v| [k, v.preview_statement] }] %>
70
70
 
71
71
  var app = new Vue({
72
72
  el: "#app",
73
73
  data: {
74
74
  running: false,
75
75
  results: "",
76
+ error: false,
76
77
  dataSource: "",
77
78
  selectize: null,
78
79
  editorHeight: "180px"
@@ -86,6 +87,7 @@
86
87
  run: function(e) {
87
88
  this.running = true
88
89
  this.results = ""
90
+ this.error = false
89
91
  cancelAllQueries()
90
92
 
91
93
  var data = $.extend({}, params, {statement: this.getSQL(), data_source: $("#query_data_source").val()})
@@ -105,6 +107,7 @@
105
107
  }
106
108
  }, function (data) {
107
109
  _this.running = false
110
+ _this.error = true
108
111
  _this.showResults(data)
109
112
  })
110
113
  },
@@ -114,14 +117,18 @@
114
117
  },
115
118
  updateDataSource: function(dataSource) {
116
119
  this.dataSource = dataSource
117
- var _this = this
120
+ var selectize = this.selectize
121
+ selectize.clearOptions()
122
+
123
+ if (this.tablesXhr) {
124
+ this.tablesXhr.abort()
125
+ }
118
126
 
119
- $.getJSON(Routes.tables_queries_path({data_source: this.dataSource}), function(data) {
127
+ this.tablesXhr = $.getJSON(Routes.tables_queries_path({data_source: this.dataSource}), function(data) {
120
128
  var newOptions = []
121
129
  for (var i = 0; i < data.length; i++) {
122
130
  newOptions.push({text: data[i], value: data[i]})
123
131
  }
124
- var selectize = _this.selectize
125
132
  selectize.clearOptions()
126
133
  selectize.addOption(newOptions)
127
134
  selectize.refreshOptions(false)
@@ -38,7 +38,7 @@
38
38
  <tbody class="list" v-cloak>
39
39
  <tr v-for="query in visibleItems">
40
40
  <td>
41
- <a :href="itemPath(query)" :class="{dashboard: query.dashboard}">{{ query.name }}</a>
41
+ <a :href="itemPath(query)" :class="{ dashboard: query.dashboard }">{{ query.name }}</a>
42
42
  <span class="vars">{{ query.vars }}</span>
43
43
  </td>
44
44
  <td class="creator">{{ query.creator }}</td>
@@ -50,6 +50,10 @@
50
50
  </div>
51
51
 
52
52
  <script>
53
+ <%= blazer_js_var "dashboards", @dashboards %>
54
+ <%= blazer_js_var "queries", @queries %>
55
+ <%= blazer_js_var "more", @more %>
56
+
53
57
  var prepareSearch = function (list) {
54
58
  var i, q, searchStr
55
59
  for (i = 0; i < list.length; i++) {
@@ -70,17 +74,17 @@
70
74
  el: "#queries",
71
75
  data: {
72
76
  searchTerm: "",
73
- more: gon.more,
77
+ more: more,
74
78
  updateCounter: 0
75
79
  },
76
80
  created: function() {
77
- this.listItems = gon.dashboards.concat(gon.queries)
81
+ this.listItems = dashboards.concat(queries)
78
82
 
79
83
  prepareSearch(this.listItems)
80
84
 
81
85
  this.queryIds = {}
82
- for (i = 0; i < gon.queries.length; i++) {
83
- this.queryIds[gon.queries[i].id] = true
86
+ for (i = 0; i < queries.length; i++) {
87
+ this.queryIds[queries[i].id] = true
84
88
  }
85
89
 
86
90
  if (this.more) {
@@ -51,7 +51,7 @@
51
51
  <script>
52
52
  L.mapbox.accessToken = '<%= ENV["MAPBOX_ACCESS_TOKEN"] %>';
53
53
  var map = L.mapbox.map('map', 'ankane.ioo8nki0');
54
- var markers = <%= blazer_json_escape(@markers.to_json).html_safe %>;
54
+ <%= blazer_js_var "markers", @markers %>
55
55
  var featureLayer = L.mapbox.featureLayer().addTo(map);
56
56
  var geojson = [];
57
57
  for (var i = 0; i < markers.length; i++) {
@@ -48,17 +48,17 @@
48
48
 
49
49
  <script>
50
50
  function showRun(data) {
51
- $("#results").html(data);
52
- $("#results table").stupidtable().stickyTableHeaders({fixedOffset: 60});
51
+ $("#results").html(data)
52
+ $("#results table").stupidtable().stickyTableHeaders({fixedOffset: 60})
53
53
  }
54
54
 
55
55
  function showError(message) {
56
- $("#results").css("color", "red").html(message);
56
+ $("#results").addClass("query-error").html(message)
57
57
  }
58
58
 
59
- var data = <%= blazer_json_escape(variable_params.merge(statement: @statement, query_id: @query.id).to_json).html_safe %>;
59
+ <%= blazer_js_var "data", variable_params.merge(statement: @statement, query_id: @query.id) %>
60
60
 
61
- runQuery(data, showRun, showError);
61
+ runQuery(data, showRun, showError)
62
62
  </script>
63
63
  <% end %>
64
64
 
@@ -7,7 +7,9 @@
7
7
 
8
8
  <%= stylesheet_link_tag "blazer/application" %>
9
9
  <%= javascript_include_tag "blazer/application" %>
10
- <%= Gon::Base.render_data %>
10
+ <script>
11
+ <%= blazer_js_var "rootPath", root_path %>
12
+ </script>
11
13
  <% if blazer_maps? %>
12
14
  <%= stylesheet_link_tag "https://api.mapbox.com/mapbox.js/v2.4.0/mapbox.css" %>
13
15
  <%= javascript_include_tag "https://api.mapbox.com/mapbox.js/v2.4.0/mapbox.js" %>
data/blazer.gemspec CHANGED
@@ -20,8 +20,6 @@ Gem::Specification.new do |spec|
20
20
  spec.add_dependency "rails"
21
21
  spec.add_dependency "chartkick"
22
22
  spec.add_dependency "safely_block", ">= 0.1.1"
23
- spec.add_dependency "js-routes"
24
- spec.add_dependency "gon"
25
23
 
26
24
  spec.add_development_dependency "bundler", "~> 1.7"
27
25
  spec.add_development_dependency "rake", "~> 10.0"
data/lib/blazer.rb CHANGED
@@ -2,8 +2,6 @@ require "csv"
2
2
  require "yaml"
3
3
  require "chartkick"
4
4
  require "safely/core"
5
- require "js-routes"
6
- require "gon"
7
5
  require "blazer/version"
8
6
  require "blazer/data_source"
9
7
  require "blazer/result"
@@ -78,6 +76,13 @@ module Blazer
78
76
  ]
79
77
  ds.default = ds.values.first
80
78
  ds
79
+
80
+ # TODO Blazer 2.0
81
+ # ds2 = Hash.new { |hash, key| raise Blazer::Error, "Unknown data source: #{key}" }
82
+ # ds.each do |k, v|
83
+ # ds2[k] = v
84
+ # end
85
+ # ds2
81
86
  end
82
87
  end
83
88
 
@@ -138,7 +143,9 @@ module Blazer
138
143
  end
139
144
 
140
145
  emails.each do |email, checks|
141
- Blazer::CheckMailer.failing_checks(email, checks).deliver_later
146
+ Safely.safely do
147
+ Blazer::CheckMailer.failing_checks(email, checks).deliver_now
148
+ end
142
149
  end
143
150
  end
144
151
  end
@@ -1,3 +1,3 @@
1
1
  module Blazer
2
- VERSION = "1.7.3"
2
+ VERSION = "1.7.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blazer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.3
4
+ version: 1.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-01 00:00:00.000000000 Z
11
+ date: 2016-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -52,34 +52,6 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.1.1
55
- - !ruby/object:Gem::Dependency
56
- name: js-routes
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: gon
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
55
  - !ruby/object:Gem::Dependency
84
56
  name: bundler
85
57
  requirement: !ruby/object:Gem::Requirement
@@ -147,7 +119,7 @@ files:
147
119
  - app/assets/javascripts/blazer/moment-timezone.js
148
120
  - app/assets/javascripts/blazer/moment.js
149
121
  - app/assets/javascripts/blazer/queries.js
150
- - app/assets/javascripts/blazer/routes.js.erb
122
+ - app/assets/javascripts/blazer/routes.js
151
123
  - app/assets/javascripts/blazer/selectize.js
152
124
  - app/assets/javascripts/blazer/stupidtable.js
153
125
  - app/assets/javascripts/blazer/vue.js
@@ -1,26 +0,0 @@
1
- <%#= JsRoutes.generate(engine: Blazer::Engine, prefix: Blazer::Engine.app.url_helpers.root_path) %>
2
-
3
- // temp fix
4
- var Routes = {
5
- run_queries_path: function() {
6
- return gon.root_path + "queries/run"
7
- },
8
- cancel_queries_path: function() {
9
- return gon.root_path + "queries/cancel"
10
- },
11
- schema_queries_path: function(params) {
12
- return gon.root_path + "queries/schema?data_source=" + params.data_source
13
- },
14
- tables_queries_path: function(params) {
15
- return gon.root_path + "queries/tables?data_source=" + params.data_source
16
- },
17
- queries_path: function() {
18
- return gon.root_path + "queries"
19
- },
20
- query_path: function(id) {
21
- return gon.root_path + "queries/" + id
22
- },
23
- dashboard_path: function(id) {
24
- return gon.root_path + "dashboards/" + id
25
- }
26
- }