_form.html.erb 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <% if @query.errors.any? %>
  2. <div class="alert alert-danger"><%= @query.errors.full_messages.first %></div>
  3. <% end %>
  4. <%= form_for @query, url: (@query.persisted? ? query_path(@query, variable_params) : queries_path(variable_params)), html: {class: "the_form", autocomplete: "off"} do |f| %>
  5. <div class="row">
  6. <div class="col-xs-8">
  7. <div class= "form-group">
  8. <%= f.hidden_field :statement %>
  9. <div id="editor-container">
  10. <div id="editor"><%= @query.statement %></div>
  11. </div>
  12. </div>
  13. <div class="form-group text-right">
  14. <div class="pull-left" style="margin-top: 6px;">
  15. <%= link_to "Back", :back %>
  16. <% if Blazer.data_sources.size == 1 %>
  17. <span class="text-muted" style="margin-left: 20px;"> Use {start_time} and {end_time} for time ranges</span>
  18. <% end %>
  19. </div>
  20. <%= 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;" %>
  21. <div id="tables" style="display: inline-block; width: 260px; margin-right: 10px;" class="hide">
  22. <%= render partial: "tables" %>
  23. </div>
  24. <script>
  25. function updatePreviewSelect() {
  26. $("#tables").load("<%= tables_queries_path %>?" + $.param({data_source: $("#query_data_source").val()}));
  27. }
  28. updatePreviewSelect();
  29. $("#query_data_source").selectize().change(updatePreviewSelect);
  30. </script>
  31. <%= link_to "Run", "#", class: "btn btn-info", id: "run", style: "vertical-align: top;" %>
  32. </div>
  33. </div>
  34. <div class="col-xs-4">
  35. <div class="form-group">
  36. <%= f.label :name %>
  37. <%= f.text_field :name, class: "form-control" %>
  38. </div>
  39. <div class="form-group">
  40. <%= f.label :description %>
  41. <%= f.text_area :description, placeholder: "Optional", style: "height: 80px;", class: "form-control" %>
  42. </div>
  43. <div class="text-right">
  44. <% if @query.persisted? %>
  45. <%= link_to "Delete", query_path(@query), method: :delete, "data-confirm" => "Are you sure?", class: "btn btn-danger" %>
  46. <%= f.submit "Fork", class: "btn btn-info" %>
  47. <% end %>
  48. <%= f.submit @query.persisted? ? "Update" : "Create", class: "btn btn-success" %>
  49. </div>
  50. </div>
  51. </div>
  52. <% end %>
  53. <div id="results"></div>
  54. <script>
  55. var editor = ace.edit("editor");
  56. editor.setTheme("ace/theme/twilight");
  57. editor.getSession().setMode("ace/mode/sql");
  58. editor.setOptions({
  59. enableBasicAutocompletion: false,
  60. enableSnippets: false,
  61. enableLiveAutocompletion: false,
  62. highlightActiveLine: false,
  63. fontSize: 12,
  64. minLines: 10
  65. });
  66. editor.renderer.setShowGutter(true);
  67. editor.renderer.setPrintMarginColumn(false);
  68. editor.renderer.setPadding(10);
  69. editor.getSession().setUseWrapMode(true);
  70. editor.commands.addCommand({
  71. name: 'run',
  72. bindKey: {win: 'Ctrl-Enter', mac: 'Command-Enter'},
  73. exec: function(editor) {
  74. $("#run").click();
  75. },
  76. readOnly: false // false if this command should not apply in readOnly mode
  77. });
  78. // http://stackoverflow.com/questions/11584061/
  79. function adjustHeight() {
  80. var lines = editor.getSession().getScreenLength();
  81. if (lines < 9) {
  82. lines = 9;
  83. }
  84. var newHeight = (lines + 1) * 16;
  85. $("#editor").height(newHeight.toString() + "px");
  86. editor.resize();
  87. };
  88. editor.getSession().on("change", adjustHeight);
  89. adjustHeight();
  90. $("#editor").show();
  91. editor.focus();
  92. var error_line = null;
  93. var xhr;
  94. var params = <%= raw blazer_json_escape(variable_params.to_json) %>;
  95. $("#run").click(function (e) {
  96. e.preventDefault();
  97. if (error_line) {
  98. editor.getSession().removeGutterDecoration(error_line - 1, "error");
  99. error_line = null;
  100. }
  101. $("#results").html('<p class="text-muted">Loading...</p>');
  102. if (xhr) {
  103. xhr.abort();
  104. }
  105. xhr = $.post("<%= run_queries_path %>", $.extend({}, params, {statement: editor.getValue().replace(/\n/g, "\r\n"), data_source: $("#query_data_source").val()}), function (data) {
  106. $("#results").html(data);
  107. error_line = /LINE (\d+)/g.exec($("#results").find('.alert-danger').text());
  108. if (error_line) {
  109. error_line = parseInt(error_line[1], 10);
  110. editor.getSession().addGutterDecoration(error_line - 1, "error");
  111. editor.scrollToLine(error_line, true, true, function () {});
  112. editor.gotoLine(error_line, 0, true);
  113. editor.focus();
  114. }
  115. });
  116. });
  117. if ($("#query_statement").val() != "") {
  118. $("#run").click();
  119. }
  120. $(document).on("change", "#table_names", function () {
  121. var val = $(this).val();
  122. if (val.length > 0) {
  123. editor.setValue("SELECT * FROM " + val + " LIMIT 10");
  124. $("#run").click();
  125. }
  126. });
  127. $("form.the_form").on("submit", function() {
  128. $("#query_statement").val(editor.getValue());
  129. return true;
  130. });
  131. </script>