acts_as_dashboard 0.3.2 → 0.3.3
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.
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.3.
|
|
1
|
+
0.3.3
|
data/acts_as_dashboard.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{acts_as_dashboard}
|
|
8
|
-
s.version = "0.3.
|
|
8
|
+
s.version = "0.3.3"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Nick Hoffman"]
|
|
12
|
-
s.date = %q{2010-08-
|
|
12
|
+
s.date = %q{2010-08-05}
|
|
13
13
|
s.description = %q{acts_as_dashboard makes it easy to create dashboards in Rails apps. Very little configuration is required. Read the docs to get started.}
|
|
14
14
|
s.email = %q{nick@deadorange.com}
|
|
15
15
|
s.extra_rdoc_files = [
|
|
@@ -1,305 +1,307 @@
|
|
|
1
|
-
// function includeJavaScriptFile(path) {{{
|
|
2
|
-
//
|
|
3
|
-
// Creates a JavaScript <script> element and appends it
|
|
4
|
-
// to the <head>.
|
|
5
|
-
//
|
|
6
|
-
function includeJavaScriptFile(path) {
|
|
7
|
-
// Ensure that we have a non-empty string.'
|
|
8
|
-
if ((typeof(path) != 'string') || (!path))
|
|
9
|
-
{return;}
|
|
10
|
-
|
|
11
|
-
// Ensure that we can find the <head>.
|
|
12
|
-
var head = jQuery('head');
|
|
13
|
-
if (!head)
|
|
14
|
-
{return;}
|
|
15
|
-
|
|
16
|
-
var element = document.createElement('script');
|
|
17
|
-
element.type = 'text/javascript';
|
|
18
|
-
element.src = path;
|
|
19
|
-
|
|
20
|
-
head.append(element);
|
|
21
|
-
|
|
22
|
-
return true;
|
|
23
|
-
} // }}}
|
|
24
|
-
|
|
25
|
-
// function buildTheDashboard() {{{
|
|
26
|
-
//
|
|
27
|
-
// Determines which dashboard widgets to build,
|
|
28
|
-
// builds them, and adds them to the DOM.
|
|
29
|
-
//
|
|
30
|
-
function buildTheDashboard() {
|
|
31
|
-
var parsed_widgets = jQuery.parseJSON(json_widgets);
|
|
32
|
-
|
|
33
|
-
jQuery.each(parsed_widgets, function(index, widget) {
|
|
34
|
-
if (widget.type == 'number')
|
|
35
|
-
{dashboard.addNumberWidget(widget);}
|
|
36
|
-
else if (widget.type == 'short_messages')
|
|
37
|
-
{dashboard.addShortMessagesWidget(widget);}
|
|
38
|
-
else if (widget.type == 'line_graph')
|
|
39
|
-
{dashboard.addLineGraphWidget(widget);}
|
|
40
|
-
});
|
|
41
|
-
} // }}}
|
|
42
|
-
|
|
43
|
-
function createUpdateTimerFor(widget) { // {{{
|
|
44
|
-
$(this).everyTime(widget.update_interval, widget.name, function() {
|
|
45
|
-
widget.updateData();
|
|
46
|
-
});
|
|
47
|
-
} // }}}
|
|
48
|
-
|
|
49
|
-
// Begin Dashboard class. {{{
|
|
50
|
-
var Dashboard = new JS.Class({
|
|
51
|
-
initialize: function(options) { // {{{
|
|
52
|
-
this.basePath = options.basePath;
|
|
53
|
-
|
|
54
|
-
this.numberWidgets = new Array();
|
|
55
|
-
this.shortMessagesWidgets = new Array();
|
|
56
|
-
this.lineGraphWidgets = new Array();
|
|
57
|
-
|
|
58
|
-
this.div = jQuery('#dashboard');
|
|
59
|
-
this.numberWidgetsDiv = this.div.find('.dashboard-numbers');
|
|
60
|
-
this.shortMessagesWidgetsDiv = this.div.find('.dashboard-short-messages');
|
|
61
|
-
this.lineGraphWidgetsDiv = this.div.find('.dashboard-line-graphs');
|
|
62
|
-
}, // }}}
|
|
63
|
-
|
|
64
|
-
addNumberWidget: function(options) { // {{{
|
|
65
|
-
var widget = new NumberWidget(options);
|
|
66
|
-
var templateDiv = this.numberWidgetsDiv.find('.widget-template');
|
|
67
|
-
|
|
68
|
-
var widgetDiv = templateDiv.clone(false)
|
|
69
|
-
.removeClass('widget-template')
|
|
70
|
-
.addClass('number-widget')
|
|
71
|
-
.attr('id', widget.divID())
|
|
72
|
-
.appendTo(this.numberWidgetsDiv);
|
|
73
|
-
|
|
74
|
-
// Set the new div's title.
|
|
75
|
-
widgetDiv.find('.widget-title').html(widget.title);
|
|
76
|
-
|
|
77
|
-
widget.setDataDivTo(widgetDiv.find('.widget-data'));
|
|
78
|
-
widget.updateData();
|
|
79
|
-
|
|
80
|
-
createUpdateTimerFor(widget);
|
|
81
|
-
|
|
82
|
-
this.numberWidgets.push(widget);
|
|
83
|
-
|
|
84
|
-
widgetDiv.show();
|
|
85
|
-
}, // }}}
|
|
86
|
-
|
|
87
|
-
addShortMessagesWidget: function(options) { // {{{
|
|
88
|
-
var widget = new ShortMessagesWidget(options);
|
|
89
|
-
var templateDiv = this.shortMessagesWidgetsDiv.find('.widget-template');
|
|
90
|
-
|
|
91
|
-
var widgetDiv = templateDiv.clone(false)
|
|
92
|
-
.removeClass('widget-template')
|
|
93
|
-
.addClass('short-messages-widget')
|
|
94
|
-
.attr('id', widget.divID())
|
|
95
|
-
.appendTo(this.shortMessagesWidgetsDiv);
|
|
96
|
-
|
|
97
|
-
// Set the new div's title.
|
|
98
|
-
widgetDiv.find('.widget-title').html(widget.title);
|
|
99
|
-
|
|
100
|
-
widget.setDataDivTo(widgetDiv.find('.widget-data'));
|
|
101
|
-
widget.updateData();
|
|
102
|
-
|
|
103
|
-
createUpdateTimerFor(widget);
|
|
104
|
-
|
|
105
|
-
this.shortMessagesWidgets.push(widget);
|
|
106
|
-
|
|
107
|
-
widgetDiv.show();
|
|
108
|
-
}, // }}}
|
|
109
|
-
|
|
110
|
-
addLineGraphWidget: function(options) { // {{{
|
|
111
|
-
var widget = new LineGraphWidget(options);
|
|
112
|
-
var templateDiv = this.lineGraphWidgetsDiv.find('.widget-template');
|
|
113
|
-
|
|
114
|
-
var widgetDiv = templateDiv.clone(false)
|
|
115
|
-
.removeClass('widget-template')
|
|
116
|
-
.addClass('line-graph-widget')
|
|
117
|
-
.attr('id', widget.divID())
|
|
118
|
-
.appendTo(this.lineGraphWidgetsDiv);
|
|
119
|
-
|
|
120
|
-
// Set the new div's title.
|
|
121
|
-
widgetDiv.find('.widget-title').html(widget.title);
|
|
122
|
-
|
|
123
|
-
var dataDiv = widgetDiv.find('.widget-data')
|
|
124
|
-
.attr('id', widget.divID() + '-data');
|
|
125
|
-
|
|
126
|
-
widget.setDataDivTo(dataDiv);
|
|
127
|
-
|
|
128
|
-
widget.updateData();
|
|
129
|
-
|
|
130
|
-
// I don't know why, but setting these properties when dataDiv
|
|
131
|
-
// is initialized fails to work. They work here, though...
|
|
132
|
-
dataDiv.css('height', widget.height)
|
|
133
|
-
dataDiv.css('width', widget.width)
|
|
134
|
-
|
|
135
|
-
createUpdateTimerFor(widget);
|
|
136
|
-
|
|
137
|
-
this.lineGraphWidgets.push(widget);
|
|
138
|
-
|
|
139
|
-
widgetDiv.show();
|
|
140
|
-
} // }}}
|
|
141
|
-
});
|
|
142
|
-
// End Dashboard class. }}}
|
|
143
|
-
|
|
144
|
-
// Begin DashboardWidget class. {{{
|
|
145
|
-
var DashboardWidget = new JS.Class({
|
|
146
|
-
initialize: function(options) {
|
|
147
|
-
this.type = options.type;
|
|
148
|
-
this.name = options.name;
|
|
149
|
-
this.title = options.title;
|
|
150
|
-
this.update_interval = options.update_interval;
|
|
151
|
-
},
|
|
152
|
-
|
|
153
|
-
dataURL: function() {
|
|
154
|
-
return dashboard.basePath + this.name;
|
|
155
|
-
},
|
|
156
|
-
|
|
157
|
-
divID: function() {
|
|
158
|
-
return this.name + '-' + this.type + '-widget';
|
|
159
|
-
},
|
|
160
|
-
|
|
161
|
-
setDataDivTo: function(element) {
|
|
162
|
-
this.dataDiv = element;
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
// End DashboardWidget class. }}}
|
|
166
|
-
|
|
167
|
-
// Begin NumberWidget class. {{{
|
|
168
|
-
var NumberWidget = new JS.Class(DashboardWidget, {
|
|
169
|
-
initialize: function(options) {
|
|
170
|
-
options['type'] = 'number';
|
|
171
|
-
this.callSuper(options);
|
|
172
|
-
},
|
|
173
|
-
|
|
174
|
-
updateData: function() {
|
|
175
|
-
if (!this.dataDiv)
|
|
176
|
-
{return false;}
|
|
177
|
-
|
|
178
|
-
// This is needed so that the dataDiv property is accessible with jQuery.get() .
|
|
179
|
-
var element = this.dataDiv;
|
|
180
|
-
|
|
181
|
-
jQuery.get(this.dataURL(), function(data) {
|
|
182
|
-
element.fadeOut(400, function() {
|
|
183
|
-
element.html(data);
|
|
184
|
-
element.fadeIn();
|
|
185
|
-
});
|
|
186
|
-
}, 'text');
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
// End NumberWidget class. }}}
|
|
190
|
-
|
|
191
|
-
// Begin ShortMessagesWidget class. {{{
|
|
192
|
-
var ShortMessagesWidget = new JS.Class(DashboardWidget, {
|
|
193
|
-
initialize: function(options) {
|
|
194
|
-
options['type'] = 'short_messages';
|
|
195
|
-
this.callSuper(options);
|
|
196
|
-
this.maxDataItems = 5;
|
|
197
|
-
},
|
|
198
|
-
|
|
199
|
-
firstDataItem: function() {
|
|
200
|
-
return this.dataDiv.find('li.widget-data-item:first');
|
|
201
|
-
},
|
|
202
|
-
|
|
203
|
-
dataItemsCount: function() {
|
|
204
|
-
return this.dataDiv.find('li.widget-data-item').length;
|
|
205
|
-
},
|
|
206
|
-
|
|
207
|
-
createDataItem: function() {
|
|
208
|
-
return this.dataDiv.find('li.widget-data-template')
|
|
209
|
-
.clone(false)
|
|
210
|
-
.removeClass('widget-data-template')
|
|
211
|
-
.addClass('widget-data-item');
|
|
212
|
-
},
|
|
213
|
-
|
|
214
|
-
updateData: function() {
|
|
215
|
-
if (!this.dataDiv)
|
|
216
|
-
{return false;}
|
|
217
|
-
|
|
218
|
-
var new_data = '';
|
|
219
|
-
var new_li = this.createDataItem();
|
|
220
|
-
|
|
221
|
-
// We use ajax() instead of get() because the "async" option must
|
|
222
|
-
// be false. If it isn't, we're unable to determine if data was
|
|
223
|
-
// obtained.
|
|
224
|
-
var get_result = jQuery.ajax({
|
|
225
|
-
url: this.dataURL(),
|
|
226
|
-
type: 'GET',
|
|
227
|
-
async: false,
|
|
228
|
-
cache: false,
|
|
229
|
-
dataType: 'text',
|
|
230
|
-
timeout: this.updateInterval,
|
|
231
|
-
success: function(data) {
|
|
232
|
-
new_li.html(data);
|
|
233
|
-
new_data = data;
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
// If no data was obtained, return. Otherwise, an empty list item
|
|
238
|
-
// will be shown.
|
|
239
|
-
if (new_data == '')
|
|
240
|
-
{return false;}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
this.
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
this.
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
jQuery.get(
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
|
|
1
|
+
// function includeJavaScriptFile(path) {{{
|
|
2
|
+
//
|
|
3
|
+
// Creates a JavaScript <script> element and appends it
|
|
4
|
+
// to the <head>.
|
|
5
|
+
//
|
|
6
|
+
function includeJavaScriptFile(path) {
|
|
7
|
+
// Ensure that we have a non-empty string.'
|
|
8
|
+
if ((typeof(path) != 'string') || (!path))
|
|
9
|
+
{return;}
|
|
10
|
+
|
|
11
|
+
// Ensure that we can find the <head>.
|
|
12
|
+
var head = jQuery('head');
|
|
13
|
+
if (!head)
|
|
14
|
+
{return;}
|
|
15
|
+
|
|
16
|
+
var element = document.createElement('script');
|
|
17
|
+
element.type = 'text/javascript';
|
|
18
|
+
element.src = path;
|
|
19
|
+
|
|
20
|
+
head.append(element);
|
|
21
|
+
|
|
22
|
+
return true;
|
|
23
|
+
} // }}}
|
|
24
|
+
|
|
25
|
+
// function buildTheDashboard() {{{
|
|
26
|
+
//
|
|
27
|
+
// Determines which dashboard widgets to build,
|
|
28
|
+
// builds them, and adds them to the DOM.
|
|
29
|
+
//
|
|
30
|
+
function buildTheDashboard() {
|
|
31
|
+
var parsed_widgets = jQuery.parseJSON(json_widgets);
|
|
32
|
+
|
|
33
|
+
jQuery.each(parsed_widgets, function(index, widget) {
|
|
34
|
+
if (widget.type == 'number')
|
|
35
|
+
{dashboard.addNumberWidget(widget);}
|
|
36
|
+
else if (widget.type == 'short_messages')
|
|
37
|
+
{dashboard.addShortMessagesWidget(widget);}
|
|
38
|
+
else if (widget.type == 'line_graph')
|
|
39
|
+
{dashboard.addLineGraphWidget(widget);}
|
|
40
|
+
});
|
|
41
|
+
} // }}}
|
|
42
|
+
|
|
43
|
+
function createUpdateTimerFor(widget) { // {{{
|
|
44
|
+
$(this).everyTime(widget.update_interval, widget.name, function() {
|
|
45
|
+
widget.updateData();
|
|
46
|
+
});
|
|
47
|
+
} // }}}
|
|
48
|
+
|
|
49
|
+
// Begin Dashboard class. {{{
|
|
50
|
+
var Dashboard = new JS.Class({
|
|
51
|
+
initialize: function(options) { // {{{
|
|
52
|
+
this.basePath = options.basePath;
|
|
53
|
+
|
|
54
|
+
this.numberWidgets = new Array();
|
|
55
|
+
this.shortMessagesWidgets = new Array();
|
|
56
|
+
this.lineGraphWidgets = new Array();
|
|
57
|
+
|
|
58
|
+
this.div = jQuery('#dashboard');
|
|
59
|
+
this.numberWidgetsDiv = this.div.find('.dashboard-numbers');
|
|
60
|
+
this.shortMessagesWidgetsDiv = this.div.find('.dashboard-short-messages');
|
|
61
|
+
this.lineGraphWidgetsDiv = this.div.find('.dashboard-line-graphs');
|
|
62
|
+
}, // }}}
|
|
63
|
+
|
|
64
|
+
addNumberWidget: function(options) { // {{{
|
|
65
|
+
var widget = new NumberWidget(options);
|
|
66
|
+
var templateDiv = this.numberWidgetsDiv.find('.widget-template');
|
|
67
|
+
|
|
68
|
+
var widgetDiv = templateDiv.clone(false)
|
|
69
|
+
.removeClass('widget-template')
|
|
70
|
+
.addClass('number-widget')
|
|
71
|
+
.attr('id', widget.divID())
|
|
72
|
+
.appendTo(this.numberWidgetsDiv);
|
|
73
|
+
|
|
74
|
+
// Set the new div's title.
|
|
75
|
+
widgetDiv.find('.widget-title').html(widget.title);
|
|
76
|
+
|
|
77
|
+
widget.setDataDivTo(widgetDiv.find('.widget-data'));
|
|
78
|
+
widget.updateData();
|
|
79
|
+
|
|
80
|
+
createUpdateTimerFor(widget);
|
|
81
|
+
|
|
82
|
+
this.numberWidgets.push(widget);
|
|
83
|
+
|
|
84
|
+
widgetDiv.show();
|
|
85
|
+
}, // }}}
|
|
86
|
+
|
|
87
|
+
addShortMessagesWidget: function(options) { // {{{
|
|
88
|
+
var widget = new ShortMessagesWidget(options);
|
|
89
|
+
var templateDiv = this.shortMessagesWidgetsDiv.find('.widget-template');
|
|
90
|
+
|
|
91
|
+
var widgetDiv = templateDiv.clone(false)
|
|
92
|
+
.removeClass('widget-template')
|
|
93
|
+
.addClass('short-messages-widget')
|
|
94
|
+
.attr('id', widget.divID())
|
|
95
|
+
.appendTo(this.shortMessagesWidgetsDiv);
|
|
96
|
+
|
|
97
|
+
// Set the new div's title.
|
|
98
|
+
widgetDiv.find('.widget-title').html(widget.title);
|
|
99
|
+
|
|
100
|
+
widget.setDataDivTo(widgetDiv.find('.widget-data'));
|
|
101
|
+
widget.updateData();
|
|
102
|
+
|
|
103
|
+
createUpdateTimerFor(widget);
|
|
104
|
+
|
|
105
|
+
this.shortMessagesWidgets.push(widget);
|
|
106
|
+
|
|
107
|
+
widgetDiv.show();
|
|
108
|
+
}, // }}}
|
|
109
|
+
|
|
110
|
+
addLineGraphWidget: function(options) { // {{{
|
|
111
|
+
var widget = new LineGraphWidget(options);
|
|
112
|
+
var templateDiv = this.lineGraphWidgetsDiv.find('.widget-template');
|
|
113
|
+
|
|
114
|
+
var widgetDiv = templateDiv.clone(false)
|
|
115
|
+
.removeClass('widget-template')
|
|
116
|
+
.addClass('line-graph-widget')
|
|
117
|
+
.attr('id', widget.divID())
|
|
118
|
+
.appendTo(this.lineGraphWidgetsDiv);
|
|
119
|
+
|
|
120
|
+
// Set the new div's title.
|
|
121
|
+
widgetDiv.find('.widget-title').html(widget.title);
|
|
122
|
+
|
|
123
|
+
var dataDiv = widgetDiv.find('.widget-data')
|
|
124
|
+
.attr('id', widget.divID() + '-data');
|
|
125
|
+
|
|
126
|
+
widget.setDataDivTo(dataDiv);
|
|
127
|
+
|
|
128
|
+
widget.updateData();
|
|
129
|
+
|
|
130
|
+
// I don't know why, but setting these properties when dataDiv
|
|
131
|
+
// is initialized fails to work. They work here, though...
|
|
132
|
+
dataDiv.css('height', widget.height)
|
|
133
|
+
dataDiv.css('width', widget.width)
|
|
134
|
+
|
|
135
|
+
createUpdateTimerFor(widget);
|
|
136
|
+
|
|
137
|
+
this.lineGraphWidgets.push(widget);
|
|
138
|
+
|
|
139
|
+
widgetDiv.show();
|
|
140
|
+
} // }}}
|
|
141
|
+
});
|
|
142
|
+
// End Dashboard class. }}}
|
|
143
|
+
|
|
144
|
+
// Begin DashboardWidget class. {{{
|
|
145
|
+
var DashboardWidget = new JS.Class({
|
|
146
|
+
initialize: function(options) {
|
|
147
|
+
this.type = options.type;
|
|
148
|
+
this.name = options.name;
|
|
149
|
+
this.title = options.title;
|
|
150
|
+
this.update_interval = options.update_interval;
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
dataURL: function() {
|
|
154
|
+
return dashboard.basePath + this.name;
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
divID: function() {
|
|
158
|
+
return this.name + '-' + this.type + '-widget';
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
setDataDivTo: function(element) {
|
|
162
|
+
this.dataDiv = element;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
// End DashboardWidget class. }}}
|
|
166
|
+
|
|
167
|
+
// Begin NumberWidget class. {{{
|
|
168
|
+
var NumberWidget = new JS.Class(DashboardWidget, {
|
|
169
|
+
initialize: function(options) {
|
|
170
|
+
options['type'] = 'number';
|
|
171
|
+
this.callSuper(options);
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
updateData: function() {
|
|
175
|
+
if (!this.dataDiv)
|
|
176
|
+
{return false;}
|
|
177
|
+
|
|
178
|
+
// This is needed so that the dataDiv property is accessible with jQuery.get() .
|
|
179
|
+
var element = this.dataDiv;
|
|
180
|
+
|
|
181
|
+
jQuery.get(this.dataURL(), function(data) {
|
|
182
|
+
element.fadeOut(400, function() {
|
|
183
|
+
element.html(data);
|
|
184
|
+
element.fadeIn();
|
|
185
|
+
});
|
|
186
|
+
}, 'text');
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
// End NumberWidget class. }}}
|
|
190
|
+
|
|
191
|
+
// Begin ShortMessagesWidget class. {{{
|
|
192
|
+
var ShortMessagesWidget = new JS.Class(DashboardWidget, {
|
|
193
|
+
initialize: function(options) {
|
|
194
|
+
options['type'] = 'short_messages';
|
|
195
|
+
this.callSuper(options);
|
|
196
|
+
this.maxDataItems = 5;
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
firstDataItem: function() {
|
|
200
|
+
return this.dataDiv.find('li.widget-data-item:first');
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
dataItemsCount: function() {
|
|
204
|
+
return this.dataDiv.find('li.widget-data-item').length;
|
|
205
|
+
},
|
|
206
|
+
|
|
207
|
+
createDataItem: function() {
|
|
208
|
+
return this.dataDiv.find('li.widget-data-template')
|
|
209
|
+
.clone(false)
|
|
210
|
+
.removeClass('widget-data-template')
|
|
211
|
+
.addClass('widget-data-item');
|
|
212
|
+
},
|
|
213
|
+
|
|
214
|
+
updateData: function() {
|
|
215
|
+
if (!this.dataDiv)
|
|
216
|
+
{return false;}
|
|
217
|
+
|
|
218
|
+
var new_data = '';
|
|
219
|
+
var new_li = this.createDataItem();
|
|
220
|
+
|
|
221
|
+
// We use ajax() instead of get() because the "async" option must
|
|
222
|
+
// be false. If it isn't, we're unable to determine if data was
|
|
223
|
+
// obtained.
|
|
224
|
+
var get_result = jQuery.ajax({
|
|
225
|
+
url: this.dataURL(),
|
|
226
|
+
type: 'GET',
|
|
227
|
+
async: false,
|
|
228
|
+
cache: false,
|
|
229
|
+
dataType: 'text',
|
|
230
|
+
timeout: this.updateInterval,
|
|
231
|
+
success: function(data) {
|
|
232
|
+
new_li.html(data);
|
|
233
|
+
new_data = data;
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// If no data was obtained, return. Otherwise, an empty list item
|
|
238
|
+
// will be shown.
|
|
239
|
+
if (new_data == '')
|
|
240
|
+
{return false;}
|
|
241
|
+
|
|
242
|
+
// Ensure that we don't show the same data twice in a row.
|
|
243
|
+
if (this.dataDiv.find('li:last-child').html() != new_li.html()) {
|
|
244
|
+
new_li.appendTo(this.dataDiv.find('ul'));
|
|
245
|
+
|
|
246
|
+
// Hide the first list item if we've reached the maximum number of
|
|
247
|
+
// list items to show in this widget.
|
|
248
|
+
if (this.dataItemsCount() > this.maxDataItems) {
|
|
249
|
+
var firstDataItem = this.firstDataItem();
|
|
250
|
+
|
|
251
|
+
firstDataItem.slideUp(400, function() {
|
|
252
|
+
firstDataItem.remove();
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
new_li.slideDown();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
// End ShortMessagesWidget class. }}}
|
|
261
|
+
|
|
262
|
+
// Begin LineGraphWidget class. {{{
|
|
263
|
+
var LineGraphWidget = new JS.Class(DashboardWidget, {
|
|
264
|
+
initialize: function(options) {
|
|
265
|
+
this.height = options.height;
|
|
266
|
+
this.width = options.width;
|
|
267
|
+
this.seriesColours = options.line_colours;
|
|
268
|
+
this.x_axis = options.x_axis;
|
|
269
|
+
|
|
270
|
+
options.type = 'line_graph';
|
|
271
|
+
this.callSuper(options);
|
|
272
|
+
},
|
|
273
|
+
|
|
274
|
+
updateData: function() {
|
|
275
|
+
if (!this.graph)
|
|
276
|
+
{this.createGraph();}
|
|
277
|
+
|
|
278
|
+
// This is needed so that the dataDiv property is accessible with jQuery.get() .
|
|
279
|
+
var graph = this.graph;
|
|
280
|
+
|
|
281
|
+
jQuery.get(this.dataURL(), function(data) {
|
|
282
|
+
graph.series[0].data = data;
|
|
283
|
+
graph.replot({resetAxes: true});
|
|
284
|
+
}, 'json');
|
|
285
|
+
},
|
|
286
|
+
|
|
287
|
+
createGraph: function() {
|
|
288
|
+
includeJavaScriptFile('/javascripts/jqplot-0.9.7/plugins/jqplot.dateAxisRenderer.min.js');
|
|
289
|
+
|
|
290
|
+
var x_axis_format = {};
|
|
291
|
+
if (this.x_axis === 'dates') {
|
|
292
|
+
var x_axis_format = {
|
|
293
|
+
renderer: jQuery.jqplot.DateAxisRenderer,
|
|
294
|
+
tickOptions: {formatString: '%Y-%m-%d'}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
this.graph = jQuery.jqplot(this.dataDiv.attr('id'), [ [] ], {
|
|
299
|
+
seriesColors: this.seriesColours,
|
|
300
|
+
axes: {
|
|
301
|
+
xaxis: x_axis_format
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
// End LineGraphWidget class. }}}
|
|
307
|
+
|
|
@@ -2,7 +2,7 @@ module ActsAsDashboard
|
|
|
2
2
|
module InstanceMethods
|
|
3
3
|
def show
|
|
4
4
|
@json_widgets = dashboard_config.widgets.map {|w| w.attributes}.to_json
|
|
5
|
-
@dashboard_path =
|
|
5
|
+
@dashboard_path = "#{ApplicationController.relative_url_root}/" + self.class.to_s.underscore.sub('_controller', '').singularize + '/widgets/'
|
|
6
6
|
|
|
7
7
|
# @dashboard_css_path = File.join(File.dirname(__FILE__), 'public', 'stylesheets', 'dashboard.css')
|
|
8
8
|
# @dashboard_css = File.open(@dashboard_css_path).read
|
|
@@ -239,19 +239,22 @@ var ShortMessagesWidget = new JS.Class(DashboardWidget, {
|
|
|
239
239
|
if (new_data == '')
|
|
240
240
|
{return false;}
|
|
241
241
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
242
|
+
// Ensure that we don't show the same data twice in a row.
|
|
243
|
+
if (this.dataDiv.find('li:last-child').html() != new_li.html()) {
|
|
244
|
+
new_li.appendTo(this.dataDiv.find('ul'));
|
|
245
|
+
|
|
246
|
+
// Hide the first list item if we've reached the maximum number of
|
|
247
|
+
// list items to show in this widget.
|
|
248
|
+
if (this.dataItemsCount() > this.maxDataItems) {
|
|
249
|
+
var firstDataItem = this.firstDataItem();
|
|
250
|
+
|
|
251
|
+
firstDataItem.slideUp(400, function() {
|
|
252
|
+
firstDataItem.remove();
|
|
253
|
+
});
|
|
254
|
+
}
|
|
248
255
|
|
|
249
|
-
|
|
250
|
-
firstDataItem.remove();
|
|
251
|
-
});
|
|
256
|
+
new_li.slideDown();
|
|
252
257
|
}
|
|
253
|
-
|
|
254
|
-
new_li.slideDown();
|
|
255
258
|
}
|
|
256
259
|
});
|
|
257
260
|
// End ShortMessagesWidget class. }}}
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: acts_as_dashboard
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 21
|
|
5
5
|
prerelease: false
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
8
|
- 3
|
|
9
|
-
-
|
|
10
|
-
version: 0.3.
|
|
9
|
+
- 3
|
|
10
|
+
version: 0.3.3
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Nick Hoffman
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2010-08-
|
|
18
|
+
date: 2010-08-05 00:00:00 -04:00
|
|
19
19
|
default_executable:
|
|
20
20
|
dependencies:
|
|
21
21
|
- !ruby/object:Gem::Dependency
|