prosperity 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/prosperity/application.js.coffee +2 -1
  3. data/app/assets/javascripts/prosperity/graph.js.coffee +74 -59
  4. data/app/assets/stylesheets/prosperity/application.css.scss +2 -1
  5. data/app/assets/stylesheets/prosperity/{graph.css → graph.css.scss} +8 -0
  6. data/app/controllers/prosperity/dashboards_controller.rb +14 -3
  7. data/app/controllers/prosperity/metrics_controller.rb +6 -1
  8. data/app/helpers/prosperity/application_helper.rb +12 -0
  9. data/app/views/layouts/prosperity/application.html.erb +2 -6
  10. data/app/views/prosperity/dashboards/edit.html.erb +5 -0
  11. data/app/views/prosperity/dashboards/index.html.erb +23 -9
  12. data/app/views/prosperity/dashboards/show.html.erb +6 -2
  13. data/lib/prosperity/extractors/base.rb +5 -1
  14. data/lib/prosperity/metric.rb +4 -0
  15. data/lib/prosperity/metrics/option.rb +4 -0
  16. data/lib/prosperity/version.rb +1 -1
  17. data/spec/controllers/prosperity/dashboards_controller_spec.rb +12 -1
  18. data/spec/controllers/prosperity/metrics_controller_spec.rb +6 -0
  19. data/spec/dummy/log/development.log +26773 -0
  20. data/spec/dummy/log/test.log +173 -0
  21. data/spec/dummy/tmp/cache/assets/development/sass/34a577735054231563e7022ea73e1468db9203ba/application.css.scssc +0 -0
  22. data/spec/dummy/tmp/cache/assets/development/sass/34a577735054231563e7022ea73e1468db9203ba/graph.css.scssc +0 -0
  23. data/spec/dummy/tmp/cache/assets/development/sprockets/141de7c3ad5525ad5025adc93847a47a +0 -0
  24. data/spec/dummy/tmp/cache/assets/development/sprockets/197492ed379339e17a0f5d01d3b01b8c +0 -0
  25. data/spec/dummy/tmp/cache/assets/development/sprockets/1c55cf24465f311353197ce336df0178 +0 -0
  26. data/spec/dummy/tmp/cache/assets/development/sprockets/204a30f61e29169229793bc31dd34207 +0 -0
  27. data/spec/dummy/tmp/cache/assets/development/sprockets/210050da208fb75a75b701bfa4e8470f +0 -0
  28. data/spec/dummy/tmp/cache/assets/development/sprockets/27a59e08207d3ae723f2b2b3d22264c3 +0 -0
  29. data/spec/dummy/tmp/cache/assets/development/sprockets/362e15a54951b12cfa5c6ad2c3dda49c +0 -0
  30. data/spec/dummy/tmp/cache/assets/development/sprockets/3be1fec30b381948e1e84408642a618f +0 -0
  31. data/spec/dummy/tmp/cache/assets/development/sprockets/3e6afb4834057e5b5c7e593d0894a8bb +0 -0
  32. data/spec/dummy/tmp/cache/assets/development/sprockets/526534cd50ee53edadd65c1df71398fc +0 -0
  33. data/spec/dummy/tmp/cache/assets/development/sprockets/5f7660fd92b228b2de09f92d54ca6b49 +0 -0
  34. data/spec/dummy/tmp/cache/assets/development/sprockets/6882b260ae69f1594eff540d803e5ac3 +0 -0
  35. data/spec/dummy/tmp/cache/assets/development/sprockets/7eb9384654be8c4fc859b9736c0da9d0 +0 -0
  36. data/spec/dummy/tmp/cache/assets/development/sprockets/828a046f0e7dc2dad0eecfe49d31e14d +0 -0
  37. data/spec/dummy/tmp/cache/assets/development/sprockets/872d17fb6fb4675e5c24b21bdd90bc86 +0 -0
  38. data/spec/dummy/tmp/cache/assets/development/sprockets/8ac3ddd03a0ca38df655faf85c8a054d +0 -0
  39. data/spec/dummy/tmp/cache/assets/development/sprockets/8c8bcb1384dcbb664e642754f197c899 +0 -0
  40. data/spec/dummy/tmp/cache/assets/development/sprockets/a2b14d5c46db32da9183354fb3fcd0bf +0 -0
  41. data/spec/dummy/tmp/cache/assets/development/sprockets/a6d6196cfd275dea0718553a95f997a5 +0 -0
  42. data/spec/dummy/tmp/cache/assets/development/sprockets/aacfd4457155e8607cbe66d5fdaf11b3 +0 -0
  43. data/spec/dummy/tmp/cache/assets/development/sprockets/d94883bc533251c5e4b4821c716ae300 +0 -0
  44. data/spec/dummy/tmp/cache/assets/development/sprockets/e0d03169ae2f0680d574ca2e19129450 +0 -0
  45. data/spec/dummy/tmp/cache/assets/development/sprockets/e76f5e84c165c22920d69c5dafce2fe1 +0 -0
  46. data/spec/dummy/tmp/cache/assets/development/sprockets/f4648036e284d9aa3468f4f7b9bbb967 +0 -0
  47. data/spec/dummy/tmp/cache/assets/test/sass/34a577735054231563e7022ea73e1468db9203ba/application.css.scssc +0 -0
  48. data/spec/dummy/tmp/cache/assets/test/sass/34a577735054231563e7022ea73e1468db9203ba/graph.css.scssc +0 -0
  49. data/spec/dummy/tmp/cache/assets/test/sprockets/141de7c3ad5525ad5025adc93847a47a +0 -0
  50. data/spec/dummy/tmp/cache/assets/test/sprockets/197492ed379339e17a0f5d01d3b01b8c +0 -0
  51. data/spec/dummy/tmp/cache/assets/test/sprockets/1c55cf24465f311353197ce336df0178 +0 -0
  52. data/spec/dummy/tmp/cache/assets/test/sprockets/210050da208fb75a75b701bfa4e8470f +0 -0
  53. data/spec/dummy/tmp/cache/assets/test/sprockets/27a59e08207d3ae723f2b2b3d22264c3 +0 -0
  54. data/spec/dummy/tmp/cache/assets/test/sprockets/362e15a54951b12cfa5c6ad2c3dda49c +0 -0
  55. data/spec/dummy/tmp/cache/assets/test/sprockets/3be1fec30b381948e1e84408642a618f +0 -0
  56. data/spec/dummy/tmp/cache/assets/test/sprockets/3e6afb4834057e5b5c7e593d0894a8bb +0 -0
  57. data/spec/dummy/tmp/cache/assets/test/sprockets/6882b260ae69f1594eff540d803e5ac3 +0 -0
  58. data/spec/dummy/tmp/cache/assets/test/sprockets/7eb9384654be8c4fc859b9736c0da9d0 +0 -0
  59. data/spec/dummy/tmp/cache/assets/test/sprockets/a2b14d5c46db32da9183354fb3fcd0bf +0 -0
  60. data/spec/dummy/tmp/cache/assets/test/sprockets/a6d6196cfd275dea0718553a95f997a5 +0 -0
  61. data/spec/dummy/tmp/cache/assets/test/sprockets/aacfd4457155e8607cbe66d5fdaf11b3 +0 -0
  62. data/spec/dummy/tmp/cache/assets/test/sprockets/d94883bc533251c5e4b4821c716ae300 +0 -0
  63. data/spec/dummy/tmp/cache/assets/test/sprockets/e76f5e84c165c22920d69c5dafce2fe1 +0 -0
  64. data/spec/dummy/tmp/cache/assets/test/sprockets/f4648036e284d9aa3468f4f7b9bbb967 +0 -0
  65. data/vendor/assets/javascripts/morris.min-0.5.js +7 -0
  66. data/vendor/assets/javascripts/raphael-min-2.1.2.js +11 -0
  67. data/vendor/assets/stylesheets/morris.css +2 -0
  68. metadata +56 -4
  69. data/vendor/assets/javascripts/highcharts.js +0 -285
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 740ec9800cffd9ee38910edd8cedebac1f49645c
4
- data.tar.gz: a80cf6f9d7abadcc4f76753e68b21037415bb003
3
+ metadata.gz: 2a2b4fadf928d57f33383ad55b6a989b2dfd8d22
4
+ data.tar.gz: 01781f83c18c0da2e1ea23b94c220d480f523f1c
5
5
  SHA512:
6
- metadata.gz: 3eb35a4e4da0e5c1861d40e50b25a379e6b87e3185a03002acf190a9da328a28f0a03091ad42dcd364420b37556a1fb3a34b00d59ff8e3769100eab5006c8289
7
- data.tar.gz: 503524d35703953d01aab8b262e51f08a7797de5f7f6865eaa4c09cd5ad43c6199702179d3872c3d3b451ea01c61db958ba2371331faf4705d7dcb60dc78e803
6
+ metadata.gz: 78b242530b5999fbdde7a9a1bba6b444a95d6073a143cd9f47d80be04498badcad408b5bbe64fe79d871f09be4588d007f3e7107034a7d4713336781e6a9c214
7
+ data.tar.gz: 8d0875abb61818781caa6445711a0bbb92330838185d920d89937609f26e4f1c2fd0d82ccac8dc33cbad67301dae8878d9ad8d14ca54d4c64b1e09342737ab75
@@ -12,7 +12,8 @@
12
12
  #
13
13
  #= require jquery
14
14
  #= require jquery_ujs
15
- #= require highcharts
15
+ #= require morris.min-0.5
16
+ #= require raphael-min-2.1.2
16
17
  #= require_tree .
17
18
 
18
19
  $ ->
@@ -1,67 +1,82 @@
1
+ class SubGraph
2
+ constructor: (options = {}) ->
3
+ @el = $('<div>', class: 'sub-graph')
4
+ if options.showTitle
5
+ @el.append("<div class='title'>Loading...</div>")
1
6
 
2
- class Graph
3
- constructor: (option) ->
4
- @url = option.url
5
- @el = option.el
6
- @$el = $(option.el)
7
-
8
- render: ->
9
- highchartsOptions =
10
- chart:
11
- type: 'line'
12
- renderTo: @el
13
- tooltip:
14
- crosshairs: [true, true]
7
+ @el.find('.title').html(options.label)
8
+
9
+ chartEl = $('<div>', class: 'sub-graph-chart')
10
+ @el.append(chartEl)
11
+
12
+ @data = []
13
+ @chartOptions =
14
+ element: chartEl
15
15
  series: []
16
- xAxis:
17
- type: 'datetime'
18
- dateTimeLabelFormats:
19
- day: '%e of %b'
20
- yAxis: [{}, {}, {}]
21
- title:
22
- text: "Loading..."
23
-
24
- chart = new Highcharts.Chart(highchartsOptions)
25
-
26
- getSeries = (url, axisIndex) =>
27
- $.get url, (json) =>
28
- axisIndex = Math.min(axisIndex, chart.yAxis.length - 1)
29
- serie =
30
- data: json.data
31
- name: json.label
32
- yAxis: axisIndex
33
- pointStart: Date.parse(json.start_time)
34
- pointInterval: json.period_milliseconds
35
-
36
- axisSettings =
37
- title: {text: json.key}
38
- min: Math.min.apply(Math, json.data)
39
- max: Math.max.apply(Math, json.data)
40
-
41
-
42
- if json.key == 'change'
43
- axisSettings = $.extend axisSettings, {
44
- min: 0,
45
- max: Math.max.apply(Math, json.data),
46
- labels: {formatter: -> this.value + '%' },
47
- opposite: true
48
- }
49
-
50
- serie = $.extend serie, {
51
- tooltip: {valueDecimals: 2, valueSuffix: '%'}
52
- }
53
-
54
- chart.yAxis[axisIndex].update(axisSettings)
55
- chart.addSeries(serie)
56
-
57
- $.getJSON @url, (json) ->
58
- chart.setTitle {text: json.title}
16
+ xkey: "x"
17
+ ykeys: []
18
+ labels: []
19
+ smooth: false
20
+ data: @data
21
+
22
+ @chartOptions.postUnits = '%' if options.key == 'change'
23
+
24
+ addSeries: (json) ->
25
+ data = @data
26
+
27
+ start_time = Date.parse(json.start_time)
28
+ for point, i in json.data
29
+ time = start_time + i * json.period_milliseconds
30
+ data[i] ||= {
31
+ x: time
32
+ }
33
+ data[i][json.uid] = point
34
+
35
+ @chartOptions.ykeys.push(json.uid)
36
+ @chartOptions.labels.push(json.uid)
37
+
38
+ @el
59
39
 
40
+ draw: ->
41
+ # Because of a bug in Morris (https://github.com/morrisjs/morris.js/issues/388)
42
+ # it's not possible to add data on a hidden element. We just redraw the
43
+ # entire thing in the meantime.
44
+ @chart = new Morris.Line(@chartOptions)
45
+
46
+ class Graph
47
+ constructor: (options) ->
48
+ @url = options.url
49
+ @el = options.el
50
+ @$el = $(options.el)
51
+ console.log(@$el)
52
+
53
+ render: =>
54
+ $.getJSON @url, (json) =>
60
55
  for extractor, index in json.extractors
61
- getSeries(extractor.url, index)
62
-
56
+ $.get extractor.url, (line_json) =>
57
+ subgraph = @getSubgraph(label: line_json.label, key: line_json.key)
58
+ subgraph.addSeries(line_json)
59
+
60
+ if @$el.hasClass('dashboard')
61
+ if subgraph.chartOptions.ykeys.length == json.extractors.length
62
+ subgraph.draw()
63
+ else
64
+ subgraph.draw()
65
+
63
66
  @
64
-
67
+
68
+ getSubgraph: (options) =>
69
+ create = (options) =>
70
+ subgraph = new SubGraph(options)
71
+ @$el.append(subgraph.el)
72
+ subgraph
73
+
74
+ # Render 1 subgraph if it's a dashboard graph, mulltiple otherwise.
75
+ if @$el.hasClass('dashboard')
76
+ @subGraph ||= create(options)
77
+ else
78
+ create($.extend(options, showTitle: true))
79
+
65
80
  @Prosperity ||= {}
66
81
  @Prosperity.Graph = Graph
67
82
 
@@ -10,10 +10,11 @@
10
10
  *
11
11
  *= require bootstrap.min
12
12
  *= require bootstrap-theme.min
13
+ *= require morris
13
14
  *= require_self
14
15
  *= require_tree .
15
16
  */
16
17
 
17
18
  .main {
18
19
  padding: 40px 15px;
19
- }
20
+ }
@@ -2,3 +2,11 @@
2
2
  Place all the styles related to the matching controller here.
3
3
  They will automatically be included in application.css.
4
4
  */
5
+
6
+ .sub-graph {
7
+ .title {
8
+ text-align: center;
9
+ font-size: 14px;
10
+ font-weight: bold;
11
+ }
12
+ }
@@ -11,11 +11,11 @@ module Prosperity
11
11
  end
12
12
 
13
13
  def show
14
- @dashboard = Dashboard.find(params[:id])
14
+ dashboard
15
15
  end
16
16
 
17
17
  def edit
18
- @dashboard = Dashboard.find(params[:id])
18
+ dashboard
19
19
  end
20
20
 
21
21
  def create
@@ -23,11 +23,22 @@ module Prosperity
23
23
  @dashboard.title = params.fetch(:dashboard, {})[:title]
24
24
  @dashboard.default = false
25
25
  if @dashboard.save
26
- redirect_to action: :index
26
+ redirect_to edit_dashboard_path(@dashboard)
27
27
  else
28
28
  flash[:error] = @dashboard.errors.full_messages.to_sentence
29
29
  render action: :new
30
30
  end
31
31
  end
32
+
33
+ def destroy
34
+ dashboard.destroy
35
+ redirect_to action: 'index'
36
+ end
37
+
38
+ private
39
+
40
+ def dashboard
41
+ @dashboard ||= Dashboard.find(params[:id])
42
+ end
32
43
  end
33
44
  end
@@ -36,7 +36,11 @@ module Prosperity
36
36
  end
37
37
 
38
38
  def data
39
- ext_klass = Metric.extractors[params.fetch(:extractor, "interval")]
39
+ ext_name = params.fetch(:extractor, "interval")
40
+ ext_klass = Metric.extractors.fetch(ext_name) do
41
+ render_json_error "Could not find extractor #{ext_name} for #{@metric}. Possible values are #{Metric.extractors.keys.join(", ")}.", 404
42
+ return
43
+ end
40
44
 
41
45
  p = Prosperity::Periods::ALL.fetch(period)
42
46
  ext = ext_klass.new(@metric, option, start_time, end_time, p)
@@ -44,6 +48,7 @@ module Prosperity
44
48
  json = {
45
49
  data: ext.to_a,
46
50
  key: ext.key,
51
+ uid: ext.uid,
47
52
  label: ext.label,
48
53
  start_time: p.actual_start_time(start_time).iso8601,
49
54
  end_time: p.actual_end_time(end_time).iso8601,
@@ -7,5 +7,17 @@ module Prosperity
7
7
  def link_to_metric(metric)
8
8
  link_to metric.new.title, metric_path(id: metric.name)
9
9
  end
10
+
11
+ def navbar_item(name, url, *controllers)
12
+ classes = []
13
+
14
+ if controllers.any?{ |c| controller.is_a?(c) }
15
+ classes << 'active'
16
+ end
17
+
18
+ content_tag(:li, class: classes) do
19
+ link_to name, url
20
+ end
21
+ end
10
22
  end
11
23
  end
@@ -27,12 +27,8 @@
27
27
  </div>
28
28
  <div class="collapse navbar-collapse">
29
29
  <ul class="nav navbar-nav">
30
- <li class="active">
31
- <a href="<%= dashboards_path %>">Dashboards</a>
32
- </li>
33
- <li>
34
- <a href="<%= metrics_path %>">All Metrics</a>
35
- </li>
30
+ <%= navbar_item 'Dashboards', dashboards_path, Prosperity::DashboardsController, Prosperity::GraphsController %>
31
+ <%= navbar_item 'Browse Metrics', metrics_path, Prosperity::MetricsController %>
36
32
  </ul>
37
33
  </div>
38
34
  </div>
@@ -22,3 +22,8 @@
22
22
  <% end %>
23
23
 
24
24
  <%= link_to "Add New Graph", new_graph_path, class: 'btn btn-primary' %>
25
+
26
+ <p>
27
+ <%= link_to "View Dashboard", @dashboard, class: 'btn' %>
28
+ </p>
29
+
@@ -1,15 +1,29 @@
1
1
  <h1>Dashboards</h1>
2
2
 
3
3
  <p>
4
- <ul>
5
- <% for dashboard in @dashboards %>
6
- <li>
7
- <%= link_to dashboard.title, dashboard_path(dashboard) %>
8
- -
9
- <%= link_to 'edit', edit_dashboard_path(dashboard) %>
10
- </li>
11
- <% end %>
12
- </ul>
4
+ <% if @dashboards.present? %>
5
+ <table class="table">
6
+ <thead>
7
+ <tr>
8
+ <th>Dashboard</th>
9
+ <th></th>
10
+ </tr>
11
+ </thead>
12
+ <tbody>
13
+ <% for dashboard in @dashboards %>
14
+ <tr>
15
+ <td> <%= link_to dashboard.title, dashboard_path(dashboard) %> </td>
16
+ <td>
17
+ <%= link_to 'Edit', edit_dashboard_path(dashboard), class: 'btn btn-primary' %>
18
+ <%= link_to 'Delete', dashboard_path(dashboard), method: 'delete', class: 'btn btn-danger' %>
19
+ </td>
20
+ </tr>
21
+ <% end %>
22
+ </body>
23
+ </table>
24
+ <% else %>
25
+ You currently don't have any dashboard. Click the button bellow to create your first!
26
+ <% end %>
13
27
  </p>
14
28
 
15
29
  <a href="<%= new_dashboard_path %>" class="btn btn-primary">New Dashboard</a>
@@ -5,10 +5,14 @@
5
5
  <%= submit_tag "Update", class: 'btn btn-primary' %>
6
6
  <% end %>
7
7
 
8
+ <% if @dashboard.graphs.empty? %>
9
+ <p>No Graphs</p>
10
+ <% end %>
11
+
8
12
  <% @dashboard.graphs.each do |graph| %>
9
- <div class="graph">
13
+ <div class="graph dashboard-graph">
10
14
  <h2><%= graph.title %></h2>
11
15
 
12
- <div class="metric" data-url="<%= graph_path(graph, start_time: start_time) %>"></div>
16
+ <div class="metric dashboard" data-url="<%= graph_path(graph, start_time: start_time) %>"></div>
13
17
  </div>
14
18
  <% end %>
@@ -1,5 +1,5 @@
1
1
  module Prosperity
2
- class Extractors::Base
2
+ class Extractors::Base
3
3
  attr_reader :metric, :start_time, :end_time, :period, :option
4
4
 
5
5
  def initialize(metric, option, start_time, end_time, period)
@@ -15,6 +15,10 @@ module Prosperity
15
15
  self.class.key
16
16
  end
17
17
 
18
+ def uid
19
+ "#{@metric.to_s.underscore}_#{@option}_#{key}"
20
+ end
21
+
18
22
  def label
19
23
  "#{metric.title} by #{key} with option #{option}"
20
24
  end
@@ -112,6 +112,10 @@ module Prosperity
112
112
  self.class.name
113
113
  end
114
114
 
115
+ def to_s
116
+ id
117
+ end
118
+
115
119
  def sql?
116
120
  self.class.sql?
117
121
  end
@@ -6,6 +6,10 @@ module Prosperity
6
6
  @name = name
7
7
  @block = block
8
8
  end
9
+
10
+ def to_s
11
+ name
12
+ end
9
13
  end
10
14
  end
11
15
 
@@ -1,3 +1,3 @@
1
1
  module Prosperity
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -41,7 +41,9 @@ module Prosperity
41
41
  expect do
42
42
  post 'create', dashboard: {title: 'test'}
43
43
  end.to change(Dashboard, :count).by(1)
44
- response.should redirect_to(action: :index)
44
+ dashboard = assigns(:dashboard)
45
+ dashboard.should be_a(Dashboard)
46
+ response.should redirect_to(edit_dashboard_path(dashboard))
45
47
  end
46
48
 
47
49
  it "should handle validation error" do
@@ -50,5 +52,14 @@ module Prosperity
50
52
  flash[:error].should be_present
51
53
  end
52
54
  end
55
+
56
+ describe "DELETE 'destroy'" do
57
+ it "deleted the dashboard" do
58
+ delete 'destroy', id: dashboard.id
59
+ response.should redirect_to(dashboards_path)
60
+
61
+ Dashboard.find_by(id: dashboard.id).should be_nil
62
+ end
63
+ end
53
64
  end
54
65
  end
@@ -95,6 +95,12 @@ module Prosperity
95
95
  response.code.to_i.should == 404
96
96
  json['error'].should be_present
97
97
  end
98
+
99
+ it "returns 404 for a known metric, but unknowd extractor" do
100
+ get :data, id: metric.id, extractor: 'does-not-exist', format: 'json'
101
+ response.code.to_i.should == 404
102
+ json['error'].should be_present
103
+ end
98
104
  end
99
105
  end
100
106
  end