c2 0.1.8 → 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- data/app/controllers/c2/reporter/app_controller.rb +6 -0
- data/app/models/c2/reporter/bucket.rb +72 -0
- data/app/models/c2/reporter/report.rb +55 -0
- data/app/stylesheets/c2.scss +3 -0
- data/app/views/c2/reporter/app/_sidebar.html.haml +30 -0
- data/app/views/c2/reporter/app/show.html.haml +34 -0
- data/app/views/layouts/c2.html.haml +6 -11
- data/config/routes.rb +3 -0
- data/public/javascripts/c2/lib/grid.js +96 -0
- metadata +10 -4
@@ -0,0 +1,72 @@
|
|
1
|
+
class C2::Reporter::Bucket
|
2
|
+
attr_accessor :refreshed_at
|
3
|
+
|
4
|
+
attr_accessor :series
|
5
|
+
attr_accessor :series_cache
|
6
|
+
|
7
|
+
def initialize(klass_name, scope_name, *series)
|
8
|
+
@klass_name = klass_name
|
9
|
+
@scope_name = scope_name
|
10
|
+
|
11
|
+
series = [:count] if series.empty?
|
12
|
+
@series = series.inject({}) do |m,v|
|
13
|
+
name, *mutators = *[*v]
|
14
|
+
m[name.to_sym] = {
|
15
|
+
:id => name.to_sym,
|
16
|
+
:name => name.to_s.titleize,
|
17
|
+
:mutators => mutators,
|
18
|
+
:data => []
|
19
|
+
}
|
20
|
+
m
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def klass
|
25
|
+
@klass_cache ||= @klass_name.to_s.classify.constantize
|
26
|
+
end
|
27
|
+
|
28
|
+
def scope
|
29
|
+
self.klass.send(@scope_name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def id
|
33
|
+
@scope_name.to_sym
|
34
|
+
end
|
35
|
+
|
36
|
+
def label
|
37
|
+
@scope_name.to_s.titleize
|
38
|
+
end
|
39
|
+
|
40
|
+
def count
|
41
|
+
self.scope.count
|
42
|
+
end
|
43
|
+
|
44
|
+
def refresh
|
45
|
+
@series_cache = {}
|
46
|
+
started_at = self.scope.min(:created_at) || Time.now
|
47
|
+
self.scope.each do |item|
|
48
|
+
date = (item.created_at || started_at).to_date
|
49
|
+
@series.each do |key,value|
|
50
|
+
data = item.respond_to?(key) ? item.send(key) : 1
|
51
|
+
@series_cache[key] ||= Hash.new(0)
|
52
|
+
@series_cache[key][date] += value[:mutators].inject(data) { |memo,mutator| memo.send(mutator) }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
@series.map do |key,value|
|
56
|
+
value[:start] = started_at.to_date
|
57
|
+
value[:end] = Date.today
|
58
|
+
value[:data] = (value[:start]..value[:end]).map { |d| @series_cache[key][d] }
|
59
|
+
end
|
60
|
+
@refreshed_at = Time.now.utc
|
61
|
+
end
|
62
|
+
|
63
|
+
def as_json(options={})
|
64
|
+
{
|
65
|
+
:id => self.id,
|
66
|
+
:label => self.label,
|
67
|
+
:count => self.count,
|
68
|
+
:series => self.series.map {|k,v| v }
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module C2::Reporter
|
2
|
+
mattr_accessor :reports
|
3
|
+
@@reports = []
|
4
|
+
|
5
|
+
class Report
|
6
|
+
attr_accessor :refreshed_at
|
7
|
+
attr_accessor :buckets
|
8
|
+
attr_accessor :options
|
9
|
+
attr_accessor :meta
|
10
|
+
|
11
|
+
def initialize(klass_name, options={}, &block)
|
12
|
+
@options = options.with_indifferent_access
|
13
|
+
|
14
|
+
@buckets = []
|
15
|
+
@klass_name = klass_name
|
16
|
+
@meta = @options.delete(:meta)
|
17
|
+
|
18
|
+
instance_eval(&block)
|
19
|
+
|
20
|
+
::C2::Reporter.reports.push(self)
|
21
|
+
end
|
22
|
+
|
23
|
+
def klass
|
24
|
+
@klass_cache ||= @klass_name.to_s.classify.constantize
|
25
|
+
end
|
26
|
+
|
27
|
+
def id
|
28
|
+
@klass_name.to_sym
|
29
|
+
end
|
30
|
+
|
31
|
+
def label
|
32
|
+
@klass_name.to_s.pluralize.titleize
|
33
|
+
end
|
34
|
+
|
35
|
+
def refresh
|
36
|
+
@buckets.each(&:refresh)
|
37
|
+
@refreshed_at = Time.now.utc
|
38
|
+
end
|
39
|
+
|
40
|
+
def as_json(options={})
|
41
|
+
{
|
42
|
+
:id => self.id,
|
43
|
+
:label => self.label,
|
44
|
+
:buckets => self.buckets
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def bucket(scope_name, *series)
|
51
|
+
@buckets.push(C2::Reporter::Bucket.new(@klass_name, scope_name, *series))
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
data/app/stylesheets/c2.scss
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
%script{ :'data-template' => 'sidebar', :type => 'text/js-template' }
|
2
|
+
%nav#sitemap.sitemap
|
3
|
+
.header
|
4
|
+
%h3= link_to('Locus of Control', '#/')
|
5
|
+
.body.tree
|
6
|
+
<% collection.each(function(locus) { %>
|
7
|
+
%ul
|
8
|
+
%li.item.section
|
9
|
+
.label{ :'data-depth' => 1 }
|
10
|
+
%a.section{ :href => '#' }
|
11
|
+
%span <%= locus.escape('label') %>
|
12
|
+
%ul
|
13
|
+
%li.item.entries
|
14
|
+
.label{ :'data-depth' => 2 }
|
15
|
+
:plain
|
16
|
+
<a href="<%= locus.entries_path() %>" class="entries">
|
17
|
+
<em class="count"><%= locus.escape('count') %></em>
|
18
|
+
<span>Entries</span>
|
19
|
+
</a>
|
20
|
+
|
21
|
+
<% locus.buckets.each(function(bucket) { %>
|
22
|
+
%li.item.bucket
|
23
|
+
.label{ :'data-depth' => 2 }
|
24
|
+
:plain
|
25
|
+
<a href="<%= bucket.entries_path() %>" class="bucket">
|
26
|
+
<em class="count"><%= bucket.escape('count') %></em>
|
27
|
+
<span><%= bucket.escape('label') %></span>
|
28
|
+
</a>
|
29
|
+
<% }); %>
|
30
|
+
<% }); %>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
.content
|
2
|
+
.header
|
3
|
+
%h1
|
4
|
+
%span.type Reporter
|
5
|
+
%strong Newsroom
|
6
|
+
%a#summation.option{:href => '#'} Σ
|
7
|
+
.body
|
8
|
+
#chart{ :style => "width: 100%; height: 400px; margin-bottom: 40px;" }
|
9
|
+
|
10
|
+
= content_for :back do
|
11
|
+
.content
|
12
|
+
.header
|
13
|
+
%h1
|
14
|
+
%span.type Editing
|
15
|
+
%strong Overview
|
16
|
+
.body
|
17
|
+
%form#entry
|
18
|
+
|
19
|
+
= content_for :sidebar do
|
20
|
+
%nav#sitemap.sitemap
|
21
|
+
.header
|
22
|
+
%nav#sitemap.sitemap
|
23
|
+
.header
|
24
|
+
%h3.current= link_to('Locus of Control', '#/')
|
25
|
+
.body.tree{ 'data-bind' => 'partial: loci#view[menu]'}
|
26
|
+
|
27
|
+
= content_for :head do
|
28
|
+
= include_javascripts :common, :vertebrae, :reporter_lib, :reporter_templates, :reporter_vertebrae
|
29
|
+
|
30
|
+
:javascript
|
31
|
+
$(function(){
|
32
|
+
Reporter.init({ loci: #{ @reports.to_json } });
|
33
|
+
});
|
34
|
+
|
@@ -3,7 +3,7 @@
|
|
3
3
|
%title= params[:controller].split('/').map(&:titleize).join(' ')
|
4
4
|
= csrf_meta_tag
|
5
5
|
|
6
|
-
%link{ :rel => 'stylesheet', :href => '/stylesheets/c2.css', :type => 'text/css', :media => 'screen', :charset => 'utf-8' }
|
6
|
+
%link{ :rel => 'stylesheet', :href => '/stylesheets/compiled/c2.css', :type => 'text/css', :media => 'screen', :charset => 'utf-8' }
|
7
7
|
%script{:src => '/javascripts/c2/lib/Sexy.min.js', :type => 'text/javascript'}
|
8
8
|
|
9
9
|
= yield :head
|
@@ -18,19 +18,14 @@
|
|
18
18
|
%h2=# link_to('Version 0.0.1', '#', :class => 'preview')
|
19
19
|
.url= link_to('Control Yourself!', '#', :class => 'external-link')
|
20
20
|
%ul.links
|
21
|
-
%li
|
22
|
-
|
23
|
-
|
24
|
-
%li= link_to('My profile', '#')
|
25
|
-
%li= link_to('My account', '#')
|
26
|
-
%li= link_to('Log out', '#')
|
27
|
-
%li= link_to('Help & Feedback', '#', :id => 'support-link')
|
28
|
-
%li= link_to('Flip', '#', :class => 'back flip-trigger')
|
21
|
+
%li#user-name= link_to(current_c2_agent_title, '#')
|
22
|
+
%li=# link_to('Help & Feedback', '#', :id => 'support-link')
|
23
|
+
%li=# link_to('Flip', '#', :class => 'back flip-trigger')
|
29
24
|
|
30
25
|
%nav
|
31
26
|
%ul
|
32
|
-
%li.informant.current
|
33
|
-
%li.reports.tab= link_to('Reporter',
|
27
|
+
%li.informant.tab{:class => "#{params[:controller] == 'c2/informant/app' ? 'current' : '' }"}= link_to('Informant', c2_informant_app_path)
|
28
|
+
%li.reports.tab{:class => "#{params[:controller] == 'c2/reporter/app' ? 'current' : '' }"}= link_to('Reporter', c2_reporter_app_path)
|
34
29
|
|
35
30
|
#main-wrapper
|
36
31
|
#sidebar-wrapper
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,96 @@
|
|
1
|
+
/**
|
2
|
+
* Grid theme for Highcharts JS
|
3
|
+
* @author Torstein Hønsi
|
4
|
+
*/
|
5
|
+
|
6
|
+
Highcharts.theme = {
|
7
|
+
colors: ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'],
|
8
|
+
chart: {
|
9
|
+
backgroundColor: {
|
10
|
+
linearGradient: [0, 0, 500, 500],
|
11
|
+
stops: [
|
12
|
+
[0, 'rgb(255, 255, 255)'],
|
13
|
+
[1, 'rgb(240, 240, 255)']
|
14
|
+
]
|
15
|
+
},
|
16
|
+
borderWidth: 2,
|
17
|
+
plotBackgroundColor: 'rgba(255, 255, 255, .9)',
|
18
|
+
plotShadow: true,
|
19
|
+
plotBorderWidth: 1
|
20
|
+
},
|
21
|
+
title: {
|
22
|
+
style: {
|
23
|
+
color: '#000',
|
24
|
+
font: 'bold 16px "Trebuchet MS", Verdana, sans-serif'
|
25
|
+
}
|
26
|
+
},
|
27
|
+
subtitle: {
|
28
|
+
style: {
|
29
|
+
color: '#666666',
|
30
|
+
font: 'bold 12px "Trebuchet MS", Verdana, sans-serif'
|
31
|
+
}
|
32
|
+
},
|
33
|
+
xAxis: {
|
34
|
+
gridLineWidth: 1,
|
35
|
+
lineColor: '#000',
|
36
|
+
tickColor: '#000',
|
37
|
+
labels: {
|
38
|
+
style: {
|
39
|
+
color: '#000',
|
40
|
+
font: '11px Trebuchet MS, Verdana, sans-serif'
|
41
|
+
}
|
42
|
+
},
|
43
|
+
title: {
|
44
|
+
style: {
|
45
|
+
color: '#333',
|
46
|
+
fontWeight: 'bold',
|
47
|
+
fontSize: '12px',
|
48
|
+
fontFamily: 'Trebuchet MS, Verdana, sans-serif'
|
49
|
+
|
50
|
+
}
|
51
|
+
}
|
52
|
+
},
|
53
|
+
yAxis: {
|
54
|
+
minorTickInterval: 'auto',
|
55
|
+
lineColor: '#000',
|
56
|
+
lineWidth: 1,
|
57
|
+
tickWidth: 1,
|
58
|
+
tickColor: '#000',
|
59
|
+
labels: {
|
60
|
+
style: {
|
61
|
+
color: '#000',
|
62
|
+
font: '11px Trebuchet MS, Verdana, sans-serif'
|
63
|
+
}
|
64
|
+
},
|
65
|
+
title: {
|
66
|
+
style: {
|
67
|
+
color: '#333',
|
68
|
+
fontWeight: 'bold',
|
69
|
+
fontSize: '12px',
|
70
|
+
fontFamily: 'Trebuchet MS, Verdana, sans-serif'
|
71
|
+
}
|
72
|
+
}
|
73
|
+
},
|
74
|
+
legend: {
|
75
|
+
itemStyle: {
|
76
|
+
font: '9pt Trebuchet MS, Verdana, sans-serif',
|
77
|
+
color: 'black'
|
78
|
+
|
79
|
+
},
|
80
|
+
itemHoverStyle: {
|
81
|
+
color: '#039'
|
82
|
+
},
|
83
|
+
itemHiddenStyle: {
|
84
|
+
color: 'gray'
|
85
|
+
}
|
86
|
+
},
|
87
|
+
labels: {
|
88
|
+
style: {
|
89
|
+
color: '#99b'
|
90
|
+
}
|
91
|
+
}
|
92
|
+
};
|
93
|
+
|
94
|
+
// Apply the theme
|
95
|
+
var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
|
96
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: c2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 9
|
10
|
+
version: 0.1.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- hexorx
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-10-
|
18
|
+
date: 2011-10-31 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
@@ -118,14 +118,19 @@ files:
|
|
118
118
|
- app/controllers/c2/informant/buckets_controller.rb
|
119
119
|
- app/controllers/c2/informant/entries_controller.rb
|
120
120
|
- app/controllers/c2/informant/locus_controller.rb
|
121
|
+
- app/controllers/c2/reporter/app_controller.rb
|
121
122
|
- app/models/c2/informant/bucket.rb
|
122
123
|
- app/models/c2/informant/form_element.rb
|
123
124
|
- app/models/c2/informant/locus.rb
|
125
|
+
- app/models/c2/reporter/bucket.rb
|
126
|
+
- app/models/c2/reporter/report.rb
|
124
127
|
- app/stylesheets/c2.scss
|
125
128
|
- app/views/c2/informant/app/_entry_index.html.haml
|
126
129
|
- app/views/c2/informant/app/_entry_index_aside.html.haml
|
127
130
|
- app/views/c2/informant/app/_sidebar.html.haml
|
128
131
|
- app/views/c2/informant/app/show.html.haml
|
132
|
+
- app/views/c2/reporter/app/_sidebar.html.haml
|
133
|
+
- app/views/c2/reporter/app/show.html.haml
|
129
134
|
- app/views/layouts/c2.html.haml
|
130
135
|
- config/initializers/c2_inflections.rb
|
131
136
|
- config/mongoid.yml
|
@@ -166,6 +171,7 @@ files:
|
|
166
171
|
- public/javascripts/c2/informant/views/sidebar.js
|
167
172
|
- public/javascripts/c2/lib/Sexy.min.js
|
168
173
|
- public/javascripts/c2/lib/backbone-min.js
|
174
|
+
- public/javascripts/c2/lib/grid.js
|
169
175
|
- public/javascripts/c2/lib/jquery.Sexy.min.js
|
170
176
|
- public/javascripts/c2/lib/jquery.activity-indicator-1.0.0.min.js
|
171
177
|
- public/javascripts/c2/lib/jquery.ba-dotimeout.min.js
|