blazer 1.7.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,17 +12,15 @@
12
12
  </div>
13
13
  </div>
14
14
  <div class="form-group text-right">
15
- <div class="pull-left" style="margin-top: 6px;">
15
+ <div class="pull-left" style="margin-top: 9px;">
16
16
  <%= link_to "Back", :back %>
17
17
  </div>
18
+ <%= link_to "Schema", "#", target: "_blank", id: "view-schema", style: "margin-right: 10px;" %>
18
19
  <%= f.select :data_source, Blazer.data_sources.values.map { |ds| [ds.name, ds.id] }, {}, class: ("hide" if Blazer.data_sources.size == 1), style: "width: 140px;" %>
19
20
  <div id="tables" style="display: inline-block; width: 250px; margin-right: 10px;" class="hide">
20
21
  <%= render partial: "tables" %>
21
22
  </div>
22
23
  <script>
23
- function updatePreviewSelect() {
24
- $("#tables").load("<%= tables_queries_path %>?" + $.param({data_source: $("#query_data_source").val()}));
25
- }
26
24
  updatePreviewSelect();
27
25
  $("#query_data_source").selectize().change(updatePreviewSelect);
28
26
  </script>
@@ -40,6 +38,7 @@
40
38
  <%= f.text_area :description, placeholder: "Optional", style: "height: 80px;", class: "form-control" %>
41
39
  </div>
42
40
  <div class="text-right">
41
+ <%= f.submit "For Enter Press", class: "hide" %>
43
42
  <% if @query.persisted? %>
44
43
  <%= link_to "Delete", query_path(@query), method: :delete, "data-confirm" => "Are you sure?", class: "btn btn-danger" %>
45
44
  <%= f.submit "Fork", class: "btn btn-info" %>
@@ -65,142 +64,7 @@
65
64
  <div id="results"></div>
66
65
 
67
66
  <script>
68
- var editor = ace.edit("editor");
69
- editor.setTheme("ace/theme/twilight");
70
- editor.getSession().setMode("ace/mode/sql");
71
- editor.setOptions({
72
- enableBasicAutocompletion: false,
73
- enableSnippets: false,
74
- enableLiveAutocompletion: false,
75
- highlightActiveLine: false,
76
- fontSize: 12,
77
- minLines: 10
78
- });
79
- editor.renderer.setShowGutter(true);
80
- editor.renderer.setPrintMarginColumn(false);
81
- editor.renderer.setPadding(10);
82
- editor.getSession().setUseWrapMode(true);
83
- editor.commands.addCommand({
84
- name: 'run',
85
- bindKey: {win: 'Ctrl-Enter', mac: 'Command-Enter'},
86
- exec: function(editor) {
87
- $("#run").click();
88
- },
89
- readOnly: false // false if this command should not apply in readOnly mode
90
- });
91
- // fix command+L
92
- editor.commands.removeCommands(["gotoline"]);
93
-
94
- // http://stackoverflow.com/questions/11584061/
95
- function adjustHeight() {
96
- var lines = editor.getSession().getScreenLength();
97
- if (lines < 9) {
98
- lines = 9;
99
- }
100
-
101
- var newHeight = (lines + 1) * 16;
102
- $("#editor").height(newHeight.toString() + "px");
103
- editor.resize();
104
- };
105
-
106
- function getSQL() {
107
- var selectedText = editor.getSelectedText();
108
- var text = selectedText.length < 10 ? editor.getValue() : selectedText;
109
- return text.replace(/\n/g, "\r\n");
110
- }
111
-
112
- function getErrorLine() {
113
- var error_line = /LINE (\d+)/g.exec($("#results").find('.alert-danger').text());
114
-
115
- if (error_line) {
116
- error_line = parseInt(error_line[1], 10);
117
- if (editor.getSelectedText().length >= 10) {
118
- error_line += editor.getSelectionRange().start.row;
119
- }
120
- return error_line;
121
- }
122
- }
123
-
124
- editor.getSession().on("change", adjustHeight);
125
- adjustHeight();
126
- $("#editor").show();
127
- editor.focus();
128
-
129
- var error_line = null;
130
- var runningQuery;
131
67
  var params = <%= raw blazer_json_escape(variable_params.to_json) %>;
132
68
  var previewStatement = <%= raw blazer_json_escape(Hash[Blazer.data_sources.map { |k, v| [k, v.preview_statement] }].to_json) %>;
133
-
134
-
135
- function queryDone() {
136
- runningQuery = null
137
- $("#run").removeClass("hide")
138
- $("#cancel").addClass("hide")
139
- }
140
-
141
- $("#cancel").click( function (e) {
142
- e.preventDefault()
143
-
144
- cancelQuery(runningQuery)
145
- queryDone()
146
-
147
- $("#results").html("")
148
- })
149
-
150
- $(window).unload(function() {
151
- if (runningQuery) {
152
- remoteCancelQuery(runningQuery)
153
- }
154
- })
155
-
156
- $("#run").click( function (e) {
157
- e.preventDefault();
158
-
159
- $(this).addClass("hide")
160
- $("#cancel").removeClass("hide")
161
-
162
- if (error_line) {
163
- editor.getSession().removeGutterDecoration(error_line - 1, "error");
164
- error_line = null;
165
- }
166
-
167
- $("#results").html('<p class="text-muted">Loading...</p>');
168
-
169
- var data = $.extend({}, params, {statement: getSQL(), data_source: $("#query_data_source").val()});
170
-
171
- runningQuery = {};
172
-
173
- runQuery(data, function (data) {
174
- queryDone()
175
-
176
- $("#results").html(data);
177
-
178
- error_line = getErrorLine();
179
- if (error_line) {
180
- editor.getSession().addGutterDecoration(error_line - 1, "error");
181
- editor.scrollToLine(error_line, true, true, function () {});
182
- editor.gotoLine(error_line, 0, true);
183
- editor.focus();
184
- }
185
- }, function (data) {
186
- // TODO show error
187
- queryDone()
188
- }, runningQuery);
189
- });
190
-
191
- $(document).on("change", "#table_names", function () {
192
- var val = $(this).val();
193
- if (val.length > 0) {
194
- var dataSource = $("#query_data_source").val();
195
- editor.setValue(previewStatement[dataSource].replace("{table}", val), 1);
196
- $("#run").click();
197
- }
198
- });
199
-
200
- $("form.the_form").on("submit", function() {
201
- $("#query_statement").val(editor.getValue());
202
- return true;
203
- });
204
-
205
- preventBackspaceNav();
69
+ showEditor();
206
70
  </script>
@@ -25,7 +25,7 @@
25
25
  </ul>
26
26
  </div>
27
27
  </div>
28
- <input type="text" placeholder="Start typing a query or person" style="width: 300px; display: inline-block;" autofocus=true class="search form-control" />
28
+ <input type="text" v-model="searchTerm" placeholder="Start typing a query or person" style="width: 300px; display: inline-block;" autofocus=true class="search form-control" />
29
29
  </div>
30
30
 
31
31
  <table class="table">
@@ -35,56 +35,107 @@
35
35
  <th style="width: 20%; text-align: right;">Mastermind</th>
36
36
  </tr>
37
37
  </thead>
38
- <tbody class="list">
39
- <tr id="search-item">
38
+ <tbody class="list" v-cloak>
39
+ <tr v-for="query in visibleItems">
40
40
  <td>
41
- <span class="name"></span>
42
- <span class="vars"></span>
43
- <span class="hide"></span>
41
+ <span v-bind:class="{dashboard: query.dashboard}"><a :href="itemPath(query)">{{query.name}}</a></span>
42
+ <span class="vars">{{query.vars}}</span>
44
43
  </td>
45
- <td class="creator"></td>
44
+ <td class="creator">{{query.creator}}</td>
46
45
  </tr>
47
46
  </tbody>
48
47
  </table>
48
+
49
+ <p v-if="more" class="text-muted">Loading...</p>
49
50
  </div>
50
51
 
51
52
  <script>
52
- var options = {
53
- valueNames: ["name", "vars", "hide", "creator"],
54
- item: "search-item",
55
- page: 200,
56
- indexAsync: true
57
- };
58
- var dashboardValues = <%= blazer_json_escape(@dashboards.to_json).html_safe %>;
59
- var queryValues = <%= blazer_json_escape(@queries.to_json).html_safe %>;
60
- var queryList = new List("queries", options, dashboardValues);
61
- queryList.add(queryValues);
62
-
63
- var queryIds = {};
64
- for (var i = 0; i < queryValues.length; i++) {
65
- queryIds[queryValues[i].id] = true;
53
+ var prepareSearch = function (list) {
54
+ var i, q
55
+ for (i = 0; i < list.length; i++) {
56
+ q = list[i]
57
+ q.searchStr = prepareQuery(q.name + q.creator)
58
+ }
66
59
  }
67
- </script>
68
60
 
69
- <% if @more %>
70
- <p id="loading" class="text-muted">Loading...</p>
71
- <script>
72
- $.getJSON("<%= queries_path %>", function (data) {
73
- var i, j, newValues, val, size = 500;
74
- $("#loading").remove();
75
- for (i = 0; i < data.length / size; i++) {
76
- newValues = [];
77
- for (j = 0; j < size; j++) {
78
- val = data[i * size + j];
79
- if (!val) {
80
- break;
61
+ var prepareQuery = function (str) {
62
+ return str.toLowerCase().replace(/\W+/g, "")
63
+ }
64
+
65
+ var app = new Vue({
66
+ el: "#queries",
67
+ data: {
68
+ searchTerm: "",
69
+ more: gon.more,
70
+ updateCounter: 0
71
+ },
72
+ created: function() {
73
+ this.listItems = gon.dashboards.concat(gon.queries)
74
+
75
+ prepareSearch(this.listItems)
76
+
77
+ this.queryIds = {}
78
+ for (i = 0; i < gon.queries.length; i++) {
79
+ this.queryIds[gon.queries[i].id] = true
80
+ }
81
+
82
+ if (this.more) {
83
+ var _this = this
84
+
85
+ $.getJSON(Routes.blazer_queries_path(), function (data) {
86
+ var i, j, newValues, val, size = 500;
87
+
88
+ var newValues = []
89
+ for (j = 0; j < data.length; j++) {
90
+ val = data[j]
91
+ if (val && !_this.queryIds[val.id]) {
92
+ newValues.push(val)
93
+ }
81
94
  }
82
- if (!queryIds[val.id]) {
83
- newValues.push(val);
95
+
96
+ prepareSearch(newValues)
97
+
98
+ _this.listItems = _this.listItems.concat(newValues)
99
+ _this.more = false
100
+ // hack to get to update
101
+ _this.updateCounter++
102
+ })
103
+ }
104
+ },
105
+ computed: {
106
+ visibleItems: function () {
107
+ // hack to get to update
108
+ this.updateCounter
109
+
110
+ var pageSize = 200
111
+ var q, i
112
+
113
+ if (this.searchTerm.length > 0) {
114
+ var term = prepareQuery(this.searchTerm)
115
+ var items = []
116
+ for (i = 0; i < this.listItems.length; i++) {
117
+ q = this.listItems[i]
118
+ if (q.searchStr.indexOf(term) !== -1) {
119
+ items.push(q)
120
+ if (items.length == pageSize) {
121
+ break
122
+ }
123
+ }
84
124
  }
125
+ return items
126
+ } else {
127
+ return this.listItems.slice(0, pageSize)
128
+ }
129
+ }
130
+ },
131
+ methods: {
132
+ itemPath: function (item) {
133
+ if (item.dashboard) {
134
+ return Routes.blazer_dashboard_path(item.to_param)
135
+ } else {
136
+ return Routes.blazer_query_path(item.to_param)
85
137
  }
86
- queryList.add(newValues);
87
138
  }
88
- });
89
- </script>
90
- <% end %>
139
+ }
140
+ })
141
+ </script>
@@ -37,105 +37,9 @@
37
37
  <p><%= @query.description %></p>
38
38
  <% end %>
39
39
 
40
- <% if @bind_vars.any? %>
41
- <form id="bind" method="get" action="<%= query_path(@query, variable_params) %>" class="form-inline" style="margin-bottom: 10px;">
42
- <% date_vars = ["start_time", "end_time"] %>
43
- <% if (date_vars - @bind_vars).empty? %>
44
- <% @bind_vars = @bind_vars - date_vars %>
45
- <% else %>
46
- <% date_vars = nil %>
47
- <% end %>
40
+ <%= render partial: "blazer/variables", locals: {action: query_path(@query)} %>
48
41
 
49
- <% @bind_vars.each_with_index do |var, i| %>
50
- <%= label_tag var, var %>
51
- <% if (data = @smart_vars[var]) %>
52
- <%= select_tag var, options_for_select([[nil, nil]] + data, selected: params[var]), style: "margin-right: 20px; width: 200px; display: none;" %>
53
- <script>
54
- $("#<%= var %>").selectize({
55
- create: true
56
- });
57
- </script>
58
- <% else %>
59
- <%= text_field_tag var, params[var], style: "width: 120px; margin-right: 20px;", autofocus: i == 0 && !var.end_with?("_at") && !params[var], class: "form-control" %>
60
- <% if var.end_with?("_at") %>
61
- <script>
62
- $("#<%= var %>").daterangepicker({singleDatePicker: true, locale: {format: "YYYY-MM-DD"}});
63
- </script>
64
- <% end %>
65
- <% end %>
66
- <% end %>
67
-
68
- <% if date_vars %>
69
- <% date_vars.each do |var| %>
70
- <%= hidden_field_tag var, params[var] %>
71
- <% end %>
72
-
73
- <%= label_tag nil, date_vars.join(" & ") %>
74
- <div class="selectize-control single" style="width: 300px;">
75
- <div id="reportrange" class="selectize-input" style="display: inline-block;">
76
- <span>Select a time range</span>
77
- </div>
78
- </div>
79
-
80
- <script>
81
- var timeZone = "<%= Blazer.time_zone.tzinfo.name %>";
82
- var format = "YYYY-MM-DD";
83
- var now = moment.tz(timeZone);
84
-
85
- function dateStr(daysAgo) {
86
- return now.clone().subtract(daysAgo || 0, "days").format(format);
87
- }
88
-
89
- function toDate(time) {
90
- return moment.tz(time.format(format), timeZone);
91
- }
92
-
93
- function setTimeInputs(start, end) {
94
- $("#start_time").val(toDate(start).utc().format());
95
- $("#end_time").val(toDate(end).endOf("day").utc().format());
96
- }
97
-
98
- $('#reportrange').daterangepicker(
99
- {
100
- ranges: {
101
- "Today": [dateStr(), dateStr()],
102
- "Last 7 Days": [dateStr(6), dateStr()],
103
- "Last 30 Days": [dateStr(29), dateStr()]
104
- },
105
- locale: {
106
- format: format
107
- },
108
- startDate: dateStr(29),
109
- endDate: dateStr(),
110
- opens: "right"
111
- },
112
- function(start, end) {
113
- setTimeInputs(start, end);
114
- submitIfCompleted($("#start_time").closest("form"));
115
- }
116
- ).on('apply.daterangepicker', function(ev, picker) {
117
- setTimeInputs(picker.startDate, picker.endDate);
118
- $('#reportrange span').html(toDate(picker.startDate).format('MMMM D, YYYY') + ' - ' + toDate(picker.endDate).format('MMMM D, YYYY'));
119
- })
120
-
121
- if ($("#start_time").val().length > 0) {
122
- var picker = $("#reportrange").data('daterangepicker');
123
- picker.setStartDate(moment.tz($("#start_time").val(), timeZone));
124
- picker.setEndDate(moment.tz($("#end_time").val(), timeZone));
125
- $("#reportrange").trigger('apply.daterangepicker', picker)
126
- } else {
127
- var picker = $("#reportrange").data('daterangepicker');
128
- $("#reportrange").trigger('apply.daterangepicker', picker);
129
- submitIfCompleted($("#start_time").closest("form"));
130
- }
131
- </script>
132
- <% end %>
133
-
134
- <input type="submit" class="btn btn-success" value="Run" style="vertical-align: top;" />
135
- </form>
136
- <% end %>
137
-
138
- <pre style="max-height: 236px; overflow: hidden;" onclick="this.style.maxHeight = 'none';"><code><%= @statement %></code></pre>
42
+ <pre id="code"><code><%= @statement %></code></pre>
139
43
 
140
44
  <% if @success %>
141
45
  <div id="results">
@@ -163,13 +67,7 @@
163
67
  // do not highlight really long queries
164
68
  // this can lead to performance issues
165
69
  if ($("code").text().length < 10000) {
166
- hljs.initHighlightingOnLoad();
70
+ hljs.highlightBlock(document.getElementById("code"));
167
71
  }
168
72
  </script>
169
73
  <% end %>
170
-
171
- <script>
172
- $(".form-inline input, .form-inline select").change( function () {
173
- submitIfCompleted($(this).closest("form"));
174
- });
175
- </script>
@@ -7,10 +7,7 @@
7
7
 
8
8
  <%= stylesheet_link_tag "blazer/application" %>
9
9
  <%= javascript_include_tag "blazer/application" %>
10
- <script>
11
- var runQueriesPath = <%= run_queries_path.to_json.html_safe %>;
12
- var cancelQueriesPath = <%= cancel_queries_path.to_json.html_safe %>;
13
- </script>
10
+ <%= Gon::Base.render_data %>
14
11
  <% if blazer_maps? %>
15
12
  <%= stylesheet_link_tag "https://api.mapbox.com/mapbox.js/v2.4.0/mapbox.css" %>
16
13
  <%= javascript_include_tag "https://api.mapbox.com/mapbox.js/v2.4.0/mapbox.js" %>