Kaynağa Gözat

Working dashboards

Andrew Kane 9 yıl önce
ebeveyn
işleme
0a4dcfa10f

+ 1 - 1
app/controllers/blazer/checks_controller.rb

@@ -1,6 +1,6 @@
 module Blazer
   class ChecksController < BaseController
-    before_action :set_check, only: [:show, :edit, :update, :destroy, :run]
+    before_action :set_check, only: [:edit, :update, :destroy, :run]
 
     def index
       @checks = Blazer::Check.joins(:blazer_query).includes(:blazer_query).order("state, blazer_queries.name, blazer_checks.id").to_a

+ 20 - 0
app/controllers/blazer/dashboard_queries_controller.rb

@@ -0,0 +1,20 @@
+module Blazer
+  class DashboardQueriesController < BaseController
+    def create
+      @dashboard_query = Blazer::DashboardQuery.new(dashboard_query_params)
+      @dashboard_query.position = @dashboard_query.blazer_dashboard.blazer_dashboard_queries.maximum(:position).to_i + 1
+
+      if @dashboard_query.save
+        redirect_to dashboard_path(@dashboard_query.blazer_dashboard_id)
+      else
+        raise "boom"
+      end
+    end
+
+    protected
+
+    def dashboard_query_params
+      params.require(:dashboard_query).permit(:blazer_dashboard_id, :blazer_query_id)
+    end
+  end
+end

+ 36 - 0
app/controllers/blazer/dashboards_controller.rb

@@ -0,0 +1,36 @@
+module Blazer
+  class DashboardsController < BaseController
+    before_action :set_dashboard, only: [:show, :edit, :update, :destroy]
+
+    def index
+      @dashboards = Blazer::Dashboard.order(:name)
+    end
+
+    def new
+      @dashboard = Blazer::Dashboard.new
+    end
+
+    def create
+      @dashboard = Blazer::Dashboard.new(dashboard_params)
+
+      if @dashboard.save
+        redirect_to dashboard_path(@dashboard)
+      else
+        render :new
+      end
+    end
+
+    def show
+    end
+
+    protected
+
+    def dashboard_params
+      params.require(:dashboard).permit(:name)
+    end
+
+    def set_dashboard
+      @dashboard = Blazer::Dashboard.find(params[:id])
+    end
+  end
+end

+ 1 - 0
app/controllers/blazer/queries_controller.rb

@@ -46,6 +46,7 @@ module Blazer
     def run
       @statement = params[:statement]
       process_vars(@statement)
+      @only_chart = params[:only_chart]
 
       if @success
         @query = Query.find_by(id: params[:query_id]) if params[:query_id]

+ 12 - 0
app/models/blazer/dashboard.rb

@@ -0,0 +1,12 @@
+module Blazer
+  class Dashboard < ActiveRecord::Base
+    has_many :blazer_dashboard_queries, class_name: "Blazer::DashboardQuery", foreign_key: "blazer_dashboard_id", dependent: :destroy
+    has_many :blazer_queries, class_name: "Blazer::Query", through: :blazer_dashboard_queries
+
+    validates :name, presence: true
+
+    def to_param
+      [id, name.gsub("'", "").parameterize].join("-")
+    end
+  end
+end

+ 9 - 0
app/models/blazer/dashboard_query.rb

@@ -0,0 +1,9 @@
+module Blazer
+  class DashboardQuery < ActiveRecord::Base
+    belongs_to :blazer_dashboard, class_name: "Blazer::Dashboard"
+    belongs_to :blazer_query, class_name: "Blazer::Query"
+
+    validates :blazer_dashboard_id, presence: true
+    validates :blazer_query_id, presence: true
+  end
+end

+ 16 - 0
app/views/blazer/dashboards/_form.html.erb

@@ -0,0 +1,16 @@
+<% if @dashboard.errors.any? %>
+  <div class="alert alert-danger"><%= @dashboard.errors.full_messages.first %></div>
+<% end %>
+
+<%= form_for @dashboard do |f| %>
+  <div class="form-group">
+    <%= f.label :name %>
+    <%= f.text_field :name, class: "form-control" %>
+  </div>
+  <p>
+    <% if @dashboard.persisted? %>
+      <%= link_to "Delete", dashboard_path(@dashboard), method: :delete, "data-confirm" => "Are you sure?", class: "btn btn-danger" %>
+    <% end %>
+    <%= f.submit "Save", class: "btn btn-success" %>
+  </p>
+<% end %>

+ 21 - 0
app/views/blazer/dashboards/index.html.erb

@@ -0,0 +1,21 @@
+<% title "Dashboards" %>
+
+<p style="float: right;"><%= link_to "New Dashboard", new_dashboard_path, class: "btn btn-info" %></p>
+<p>
+  <%= link_to "Home", root_path, class: "btn btn-primary", style: "margin-right: 10px;" %>
+</p>
+
+<table class="table">
+  <thead>
+    <tr>
+      <th>Dashboard</th>
+    </tr>
+  </thead>
+  <tbody>
+    <% @dashboards.each do |dashboard| %>
+      <tr>
+        <td><%= link_to dashboard.name, dashboard %></td>
+      </tr>
+    <% end %>
+  </tbody>
+</table>

+ 1 - 0
app/views/blazer/dashboards/new.html.erb

@@ -0,0 +1 @@
+<%= render partial: "form" %>

+ 31 - 0
app/views/blazer/dashboards/show.html.erb

@@ -0,0 +1,31 @@
+<h2><%= @dashboard.name %></h1>
+
+<% @dashboard.blazer_dashboard_queries.order(:position).map(&:blazer_query).each_with_index do |query, i| %>
+  <div style="margin-top: 40px;">
+    <h4 style="text-align: center;"><%= link_to query.name, query_path(query), style: "color: inherit;" %></h4>
+    <div id="chart-<%= i %>" style="height: 300px; text-align: center; line-height: 300px;"></div>
+  </div>
+  <script>
+    $.post("<%= run_queries_path %>", <%= json_escape({statement: query.statement, query_id: query.id, only_chart: true}.to_json).html_safe %>, function (data) {
+      $("#chart-<%= i %>").html(data);
+    });
+  </script>
+<% end %>
+
+<!--
+<h4>Add Query</h2>
+k
+<%= form_for Blazer::DashboardQuery.new do |f| %>
+  <%= f.hidden_field :blazer_dashboard_id, value: @dashboard.id %>
+  <div class="form-group">
+    <%= f.label :blazer_query_id, "Query" %>
+    <div class="hide">
+      <%= f.select :blazer_query_id, Blazer::Query.order(:name).map { |q| [q.name, q.id] }, {include_blank: true} %>
+    </div>
+    <script>
+      $("#dashboard_query_blazer_query_id").selectize().parents(".hide").removeClass("hide");
+    </script>
+  </div>
+  <%= f.submit "Add", class: "btn btn-success" %>
+<% end %>
+-->

+ 1 - 0
app/views/blazer/queries/index.html.erb

@@ -2,6 +2,7 @@
   <div id="header" style="margin-bottom: 20px;">
     <div class="pull-right">
       <%= link_to "New Query", new_query_path, class: "btn btn-info" %>
+      <%= link_to "Dashboards", dashboards_path, class: "btn btn-primary" %>
       <%= link_to "Checks", checks_path, class: "btn btn-primary" %>
     </div>
     <input type="text" placeholder="Start typing a query or person" style="width: 300px; display: inline-block;" autofocus=true class="search form-control" />

+ 46 - 41
app/views/blazer/queries/run.html.erb

@@ -3,59 +3,64 @@
 <% elsif !@success %>
   <div class="alert alert-info">Can’t preview queries with variables...yet!</div>
 <% else %>
-  <p class="text-muted"><%= pluralize(@rows.size, "row") %></p>
+  <% unless @only_chart %>
+    <p class="text-muted"><%= pluralize(@rows.size, "row") %></p>
+  <% end %>
   <% if @rows.any? %>
     <% values = @rows.first.values %>
+    <% chart_id = SecureRandom.hex %>
     <% if values.size >= 2 && values.first.is_a?(Time) && values[1..-1].all?{|v| v.is_a?(Numeric) } %>
       <% time_k = @columns.keys.first %>
-      <%= line_chart @columns.keys[1..-1].map{|k| {name: k, data: @rows.map{|r| [r[time_k], r[k]] }} } %>
+      <%= line_chart @columns.keys[1..-1].map{|k| {name: k, data: @rows.map{|r| [r[time_k], r[k]] }} }, id: chart_id %>
     <% elsif values.size == 3 && values.first.is_a?(Time) && values[1].is_a?(String) && values[2].is_a?(Numeric) %>
       <% keys = @columns.keys %>
-      <%= line_chart @rows.group_by { |v| v[keys[1]] }.map { |name, v| {name: name, data: v.map { |v2| [v2[keys[0]], v2[keys[2]]] } } } %>
+      <%= line_chart @rows.group_by { |v| v[keys[1]] }.map { |name, v| {name: name, data: v.map { |v2| [v2[keys[0]], v2[keys[2]]] } } }, id: chart_id %>
     <% elsif values.size == 2 && values.first.is_a?(String) && values.last.is_a?(Numeric) %>
-      <%= pie_chart @rows.map(&:values), library: {sliceVisibilityThreshold: 1 / 40.0} %>
+      <%= pie_chart @rows.map(&:values), library: {sliceVisibilityThreshold: 1 / 40.0}, id: chart_id %>
     <% end %>
 
-    <% header_width = 100 / @rows.first.keys.size.to_f %>
-    <table class="table">
-      <thead>
-        <tr>
-          <% @columns.each do |key, type| %>
-            <th style="width: <%= header_width %>%;" data-sort="<%= type %>">
-              <div style="min-width: <%= @min_width_types.include?(key) ? 180 : 60 %>px;">
-                <%= key %>
-              </div>
-            </th>
-          <% end %>
-        </tr>
-      </thead>
-      <tbody>
-        <% @rows.each do |row| %>
+    <% unless @only_chart %>
+      <% header_width = 100 / @rows.first.keys.size.to_f %>
+      <table class="table">
+        <thead>
           <tr>
-            <% row.each do |k, v| %>
-              <td>
-                <% if v.is_a?(Time) %>
-                  <% v = v.in_time_zone(Blazer.time_zone) %>
-                <% end %>
-
-                <% unless v.nil? %>
-                  <% if v == "" %>
-                    <div class="text-muted">empty string</div>
-                  <% elsif @linked_columns[k] %>
-                    <%= link_to format_value(k, v), @linked_columns[k].gsub("{value}", u(v.to_s)), target: "_blank" %>
-                  <% else %>
-                    <%= format_value(k, v) %>
+            <% @columns.each do |key, type| %>
+              <th style="width: <%= header_width %>%;" data-sort="<%= type %>">
+                <div style="min-width: <%= @min_width_types.include?(key) ? 180 : 60 %>px;">
+                  <%= key %>
+                </div>
+              </th>
+            <% end %>
+          </tr>
+        </thead>
+        <tbody>
+          <% @rows.each do |row| %>
+            <tr>
+              <% row.each do |k, v| %>
+                <td>
+                  <% if v.is_a?(Time) %>
+                    <% v = v.in_time_zone(Blazer.time_zone) %>
                   <% end %>
 
-                  <% if v2 = (@boom[k] || {})[v] %>
-                    <div class="text-muted"><%= v2 %></div>
+                  <% unless v.nil? %>
+                    <% if v == "" %>
+                      <div class="text-muted">empty string</div>
+                    <% elsif @linked_columns[k] %>
+                      <%= link_to format_value(k, v), @linked_columns[k].gsub("{value}", u(v.to_s)), target: "_blank" %>
+                    <% else %>
+                      <%= format_value(k, v) %>
+                    <% end %>
+
+                    <% if v2 = (@boom[k] || {})[v] %>
+                      <div class="text-muted"><%= v2 %></div>
+                    <% end %>
                   <% end %>
-                <% end %>
-              </td>
-            <% end %>
-          </tr>
-        <% end %>
-      </tbody>
-    </table>
+                </td>
+              <% end %>
+            </tr>
+          <% end %>
+        </tbody>
+      </table>
+    <% end %>
   <% end %>
 <% end %>

+ 2 - 0
config/routes.rb

@@ -5,5 +5,7 @@ Blazer::Engine.routes.draw do
   resources :checks, except: [:show] do
     get :run, on: :member
   end
+  resources :dashboards
+  resources :dashboard_queries, only: [:create, :destroy]
   root to: "queries#index"
 end