prosperity 0.0.5 → 0.0.6

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.
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