sensu-dashboard-sonian 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE.txt +20 -0
- data/README.org +4 -0
- data/Rakefile +1 -0
- data/bin/sensu-dashboard +9 -0
- data/lib/sensu-dashboard/app.rb +449 -0
- data/lib/sensu-dashboard/public/css/autoSuggest.css +217 -0
- data/lib/sensu-dashboard/public/css/style.css +177 -0
- data/lib/sensu-dashboard/public/img/cross.png +0 -0
- data/lib/sensu-dashboard/public/img/footer_bg.png +0 -0
- data/lib/sensu-dashboard/public/img/header_bg.png +0 -0
- data/lib/sensu-dashboard/public/img/loading_circle.gif +0 -0
- data/lib/sensu-dashboard/public/img/main_content_bg.png +0 -0
- data/lib/sensu-dashboard/public/img/megaphone_icon.png +0 -0
- data/lib/sensu-dashboard/public/img/megaphone_icon_off.png +0 -0
- data/lib/sensu-dashboard/public/js/FABridge.js +604 -0
- data/lib/sensu-dashboard/public/js/functions.js +379 -0
- data/lib/sensu-dashboard/public/js/jquery-1.5.1.min.js +16 -0
- data/lib/sensu-dashboard/public/js/jquery.autoSuggest.js +375 -0
- data/lib/sensu-dashboard/public/js/jquery.leanModal.min.js +1 -0
- data/lib/sensu-dashboard/public/js/jquery.sortElements.js +69 -0
- data/lib/sensu-dashboard/public/js/jquery.tmpl.min.js +1 -0
- data/lib/sensu-dashboard/public/js/jquery.zclip.min.js +12 -0
- data/lib/sensu-dashboard/public/js/modernizr-1.7.min.js +2 -0
- data/lib/sensu-dashboard/public/js/swfobject.js +4 -0
- data/lib/sensu-dashboard/public/js/web_socket.js +312 -0
- data/lib/sensu-dashboard/public/js/webtoolkit.sha1.js +174 -0
- data/lib/sensu-dashboard/public/swf/WebSocketMain.swf +0 -0
- data/lib/sensu-dashboard/public/swf/ZeroClipboard.swf +0 -0
- data/lib/sensu-dashboard/version.rb +5 -0
- data/lib/sensu-dashboard/views/client_templates.erb +68 -0
- data/lib/sensu-dashboard/views/clients.erb +37 -0
- data/lib/sensu-dashboard/views/event_templates.erb +190 -0
- data/lib/sensu-dashboard/views/index.erb +48 -0
- data/lib/sensu-dashboard/views/layout.erb +124 -0
- data/lib/sensu-dashboard/views/sonian.sass +213 -0
- data/lib/sensu-dashboard/views/stash_templates.erb +44 -0
- data/lib/sensu-dashboard/views/stashes.erb +32 -0
- data/sensu-dashboard.gemspec +22 -0
- metadata +166 -0
Binary file
|
Binary file
|
@@ -0,0 +1,68 @@
|
|
1
|
+
<!-- Client template -->
|
2
|
+
<script id="clientTemplate" type="text/x-jquery-tmpl">
|
3
|
+
<tr id="${name}" rel="leanModal" href="#event_details_modal">
|
4
|
+
<td id="client_id">${name}</td>
|
5
|
+
<td id="environment">${environment}</td>
|
6
|
+
<td id="public_ip">${address}</td>
|
7
|
+
<td id="timestamp">${timestamp}</td>
|
8
|
+
<td id="subscriptions">${subscriptions}</td>
|
9
|
+
</tr>
|
10
|
+
</script>
|
11
|
+
|
12
|
+
<!-- Client details row template -->
|
13
|
+
<script id="clientDetailsRowTemplate" type="text/x-jquery-tmpl">
|
14
|
+
{{each $data}}
|
15
|
+
<div class="event_detail_group">
|
16
|
+
<div class="event_detail">
|
17
|
+
<h1>${capitaliseFirstLetter($index)}</h1>
|
18
|
+
<p id="${$index}">${$value}</p>
|
19
|
+
</div>
|
20
|
+
<!--<div class="copy">Copy</div>-->
|
21
|
+
<div style="clear: both;"></div>
|
22
|
+
</div>
|
23
|
+
{{/each}}
|
24
|
+
</script>
|
25
|
+
|
26
|
+
<script type="text/javascript">
|
27
|
+
fetchClients();
|
28
|
+
|
29
|
+
ws = new WebSocket("ws://" + location.hostname + ":9000");
|
30
|
+
ws.onmessage = function(evt) {
|
31
|
+
fetchClients();
|
32
|
+
}
|
33
|
+
|
34
|
+
$("#remove_client").click(function() {
|
35
|
+
var client = $("#name").html();
|
36
|
+
var cross_img = $("#remove_client").children().first();
|
37
|
+
cross_img.attr("src", "/img/loading_circle.gif");
|
38
|
+
$.ajax({
|
39
|
+
type: 'DELETE',
|
40
|
+
contentType: 'application/json',
|
41
|
+
url: '/client/'+client+'.json',
|
42
|
+
success: function(data, textStatus, xhr) {
|
43
|
+
alert('Client '+client+' is being removed, resolving events...');
|
44
|
+
cross_img.attr("src", "/img/cross.png");
|
45
|
+
$("#lean_overlay").fadeOut(200);
|
46
|
+
$("#event_details_modal").css({'display':'none'});
|
47
|
+
fetchClients();
|
48
|
+
},
|
49
|
+
error: function(xhr, textStatus, errorThrown) {
|
50
|
+
cross_img.attr("src", "/img/cross.png");
|
51
|
+
alert('Client was not found in sensu. This may be due to a delay in a previous removal attempt.');
|
52
|
+
}
|
53
|
+
});
|
54
|
+
});
|
55
|
+
|
56
|
+
$("input[type=text]").autoSuggest("http://" + location.hostname + ":" + location.port + "/clients/autocomplete.json", {
|
57
|
+
startText: "Enter keywords to filter by",
|
58
|
+
selectedItemProp: "name",
|
59
|
+
searchObjProps: "name",
|
60
|
+
selectionAdded: function(elem) {
|
61
|
+
fetchClients();
|
62
|
+
},
|
63
|
+
selectionRemoved: function(elem) {
|
64
|
+
elem.fadeTo("fast", 0, function() { elem.remove(); });
|
65
|
+
fetchClients();
|
66
|
+
}
|
67
|
+
});
|
68
|
+
</script>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<h1>Current Clients <span class="clients_count">(<span id="client_count">0</span>)</span></h1>
|
2
|
+
|
3
|
+
<input type="text" id="autosuggest_filter" style="width: 300px;"/>
|
4
|
+
|
5
|
+
<table id="clients">
|
6
|
+
|
7
|
+
<thead>
|
8
|
+
|
9
|
+
<tr>
|
10
|
+
<th class="col_clients">Client</th>
|
11
|
+
<th class="col_environment">Environment</th>
|
12
|
+
<th class="col_public_ip">Public IP</th>
|
13
|
+
<th class="col_timestamp">Timestamp</th>
|
14
|
+
<th class="col_output">Subscriptions</th>
|
15
|
+
</tr>
|
16
|
+
|
17
|
+
</thead>
|
18
|
+
|
19
|
+
<tbody></tbody>
|
20
|
+
|
21
|
+
</table>
|
22
|
+
|
23
|
+
<div id="event_details_modal" class="event_details_modal">
|
24
|
+
<h1 class="section_title">Actions</h1>
|
25
|
+
<div id="event_actions">
|
26
|
+
<div class="event_detail_group">
|
27
|
+
<div class="event_detail">
|
28
|
+
<div id="remove_client" class="action_btn" style="margin-right: 7px;">
|
29
|
+
<img src="/img/cross.png" style="vertical-align: middle; padding-right: 7px;"/><strong>Remove</strong>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
<div style="clear: both;"></div>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
<h1 class="section_title">Client Data</h1>
|
36
|
+
<div id="client_data"></div>
|
37
|
+
</div>
|
@@ -0,0 +1,190 @@
|
|
1
|
+
<!-- Event template -->
|
2
|
+
<script id="eventTemplate" type="text/x-jquery-tmpl">
|
3
|
+
{{if is_unknown}}
|
4
|
+
<tr class="status3" id="${identifier}" rel="leanModal" href="#event_details_modal">
|
5
|
+
{{else}}
|
6
|
+
<tr class="status${status}" id="${identifier}" rel="leanModal" href="#event_details_modal">
|
7
|
+
{{/if}}
|
8
|
+
<td id="client">${client}</td>
|
9
|
+
<td id="check">${check}</td>
|
10
|
+
<td id="environment">${environment}</td>
|
11
|
+
<td id="output">${output}</td>
|
12
|
+
</tr>
|
13
|
+
</script>
|
14
|
+
|
15
|
+
<!-- Event details row template -->
|
16
|
+
<script id="eventDetailsRowTemplate" type="text/x-jquery-tmpl">
|
17
|
+
<div class="event_detail_group">
|
18
|
+
<div class="event_detail">
|
19
|
+
<h1>Client</h1>
|
20
|
+
<p id="client_id_value">${client}</p>
|
21
|
+
</div>
|
22
|
+
<!--<div class="copy">Copy</div>-->
|
23
|
+
<div style="clear: both;"></div>
|
24
|
+
</div>
|
25
|
+
<div class="event_detail_group">
|
26
|
+
<div class="event_detail">
|
27
|
+
<h1>Check</h1>
|
28
|
+
<p id="check_name_value">${check}</p>
|
29
|
+
</div>
|
30
|
+
<!--<div class="copy">Copy</div>-->
|
31
|
+
<div style="clear: both;"></div>
|
32
|
+
</div>
|
33
|
+
<div class="event_detail_group">
|
34
|
+
<div class="event_detail">
|
35
|
+
<h1>Status</h1>
|
36
|
+
<p>${status}</p>
|
37
|
+
</div>
|
38
|
+
<!--<div class="copy">Copy</div>-->
|
39
|
+
<div style="clear: both;"></div>
|
40
|
+
</div>
|
41
|
+
<div class="event_detail_group">
|
42
|
+
<div class="event_detail">
|
43
|
+
<h1>Output</h1>
|
44
|
+
<p>${output}</p>
|
45
|
+
</div>
|
46
|
+
<!--<div class="copy">Copy</div>-->
|
47
|
+
<div style="clear: both;"></div>
|
48
|
+
</div>
|
49
|
+
<div class="event_detail_group">
|
50
|
+
<div class="event_detail">
|
51
|
+
<h1>Occurrences</h1>
|
52
|
+
<p>${occurrences}</p>
|
53
|
+
</div>
|
54
|
+
<!--<div class="copy">Copy</div>-->
|
55
|
+
<div style="clear: both;"></div>
|
56
|
+
</div>
|
57
|
+
</script>
|
58
|
+
|
59
|
+
<!-- Client details row template -->
|
60
|
+
<script id="clientDetailsRowTemplate" type="text/x-jquery-tmpl">
|
61
|
+
{{each $data}}
|
62
|
+
<div class="event_detail_group">
|
63
|
+
<div class="event_detail">
|
64
|
+
<h1>${capitaliseFirstLetter($index)}</h1>
|
65
|
+
<p>${$value}</p>
|
66
|
+
</div>
|
67
|
+
<!--<div class="copy">Copy</div>-->
|
68
|
+
<div style="clear: both;"></div>
|
69
|
+
</div>
|
70
|
+
{{/each}}
|
71
|
+
</script>
|
72
|
+
|
73
|
+
<script type="text/javascript">
|
74
|
+
fetchEvents();
|
75
|
+
|
76
|
+
ws = new WebSocket("ws://" + location.hostname + ":9000");
|
77
|
+
ws.onmessage = function(evt) {
|
78
|
+
fetchEvents();
|
79
|
+
}
|
80
|
+
|
81
|
+
$("#disable_client_alerts").click(function() {
|
82
|
+
var client_id = $("#client_id_value").html();
|
83
|
+
var alert_img = $("#disable_client_alerts").children().first();
|
84
|
+
|
85
|
+
if(alert_img.attr("src") == "/img/megaphone_icon_off.png") {
|
86
|
+
alert_img.attr("src", "/img/loading_circle.gif");
|
87
|
+
$.ajax({
|
88
|
+
type: 'DELETE',
|
89
|
+
contentType: 'application/json',
|
90
|
+
url: '/stash/silence/'+client_id+'.json',
|
91
|
+
success: function(data, textStatus, xhr) {
|
92
|
+
alert_img.attr("src", "/img/megaphone_icon.png");
|
93
|
+
},
|
94
|
+
error: function(xhr, textStatus, errorThrown) {
|
95
|
+
if(xhr.status == 404) {
|
96
|
+
alert_img.attr("src", "/img/megaphone_icon_off.png");
|
97
|
+
}
|
98
|
+
},
|
99
|
+
dataType: 'json'
|
100
|
+
});
|
101
|
+
} else if(alert_img.attr("src") == "/img/megaphone_icon.png") {
|
102
|
+
alert_img.attr("src", "/img/loading_circle.gif");
|
103
|
+
$.ajax({
|
104
|
+
type: 'POST',
|
105
|
+
contentType: 'application/json',
|
106
|
+
url: '/stash/silence/'+client_id+'.json',
|
107
|
+
success: function(data, textStatus, xhr) {
|
108
|
+
alert_img.attr("src", "/img/megaphone_icon_off.png");
|
109
|
+
},
|
110
|
+
error: function(xhr, textStatus, errorThrown) {
|
111
|
+
},
|
112
|
+
dataType: 'json'
|
113
|
+
});
|
114
|
+
}
|
115
|
+
});
|
116
|
+
|
117
|
+
$("#disable_client_check_alerts").click(function() {
|
118
|
+
var client_id = $("#client_id_value").html();
|
119
|
+
var check_name = $("#check_name_value").html();
|
120
|
+
var alert_img = $("#disable_client_check_alerts").children().first();
|
121
|
+
|
122
|
+
if(alert_img.attr("src") == "/img/megaphone_icon_off.png") {
|
123
|
+
alert_img.attr("src", "/img/loading_circle.gif");
|
124
|
+
$.ajax({
|
125
|
+
type: 'DELETE',
|
126
|
+
contentType: 'application/json',
|
127
|
+
url: '/stash/silence/'+client_id+'/'+check_name+'.json',
|
128
|
+
success: function(data, textStatus, xhr) {
|
129
|
+
alert_img.attr("src", "/img/megaphone_icon.png");
|
130
|
+
},
|
131
|
+
error: function(xhr, textStatus, errorThrown) {
|
132
|
+
if(xhr.status == 404) {
|
133
|
+
alert_img.attr("src", "/img/megaphone_icon_off.png");
|
134
|
+
}
|
135
|
+
},
|
136
|
+
dataType: 'json'
|
137
|
+
});
|
138
|
+
} else if(alert_img.attr("src") == "/img/megaphone_icon.png") {
|
139
|
+
alert_img.attr("src", "/img/loading_circle.gif");
|
140
|
+
$.ajax({
|
141
|
+
type: 'POST',
|
142
|
+
contentType: 'application/json',
|
143
|
+
url: '/stash/silence/'+client_id+'/'+check_name+'.json',
|
144
|
+
success: function(data, textStatus, xhr) {
|
145
|
+
alert_img.attr("src", "/img/megaphone_icon_off.png");
|
146
|
+
},
|
147
|
+
error: function(xhr, textStatus, errorThrown) {
|
148
|
+
},
|
149
|
+
dataType: 'json'
|
150
|
+
});
|
151
|
+
}
|
152
|
+
});
|
153
|
+
|
154
|
+
$("#resolve_event").click(function() {
|
155
|
+
var client = $("#client_id_value").html();
|
156
|
+
var check = $("#check_name_value").html();
|
157
|
+
$.ajax({
|
158
|
+
type: 'POST',
|
159
|
+
contentType: 'application/json',
|
160
|
+
url: '/event/resolve.json',
|
161
|
+
data: JSON.stringify({"client":client, "check":check}),
|
162
|
+
success: function(data, textStatus, xhr) {
|
163
|
+
$("#lean_overlay").fadeOut(200);
|
164
|
+
$("#event_details_modal").css({'display':'none'});
|
165
|
+
fetchEvents();
|
166
|
+
},
|
167
|
+
error: function(xhr, textStatus, errorThrown) {
|
168
|
+
alert('Failed to resolve event');
|
169
|
+
}
|
170
|
+
});
|
171
|
+
});
|
172
|
+
|
173
|
+
$("input[type=text]").autoSuggest("http://" + location.hostname + ":" + location.port + "/autocomplete.json", {
|
174
|
+
startText: "Enter keywords to filter by",
|
175
|
+
selectedItemProp: "name",
|
176
|
+
searchObjProps: "name",
|
177
|
+
selectionAdded: function(elem) {
|
178
|
+
fetchEvents();
|
179
|
+
},
|
180
|
+
selectionRemoved: function(elem) {
|
181
|
+
elem.fadeTo("fast", 0, function() { elem.remove(); });
|
182
|
+
fetchEvents();
|
183
|
+
}
|
184
|
+
});
|
185
|
+
|
186
|
+
$('#filter_unknown_checks').change(function() {
|
187
|
+
filter_unknown_checks = !filter_unknown_checks;
|
188
|
+
fetchEvents();
|
189
|
+
});
|
190
|
+
</script>
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<h1>Current Events <span class="events_count">(<span id="event_count">0</span>)</span></h1>
|
2
|
+
|
3
|
+
<div style="padding-bottom: 7px;">
|
4
|
+
<input type="checkbox" checked="checked" id="filter_unknown_checks" style="margin-right: 7px;"/>Filter Unknown Checks
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<input type="text" id="autosuggest_client_filter" style="width: 300px;"/>
|
8
|
+
|
9
|
+
<table id="events">
|
10
|
+
|
11
|
+
<thead>
|
12
|
+
|
13
|
+
<tr>
|
14
|
+
<th class="col_clients">Client</th>
|
15
|
+
<th class="col_checks">Check</th>
|
16
|
+
<th class="col_environment">Environment</th>
|
17
|
+
<th class="col_output">Output</th>
|
18
|
+
</tr>
|
19
|
+
|
20
|
+
</thead>
|
21
|
+
|
22
|
+
<tbody></tbody>
|
23
|
+
|
24
|
+
</table>
|
25
|
+
|
26
|
+
<div id="event_details_modal" class="event_details_modal">
|
27
|
+
<h1 class="section_title">Actions</h1>
|
28
|
+
<div id="event_actions">
|
29
|
+
<div class="event_detail_group">
|
30
|
+
<div class="event_detail">
|
31
|
+
<div id="disable_client_alerts" class="action_btn" style="margin-right: 7px;">
|
32
|
+
<img src="/img/loading_circle.gif" style="vertical-align: middle; padding-right: 7px;"/><strong>Client</strong>
|
33
|
+
</div>
|
34
|
+
<div id="disable_client_check_alerts" class="action_btn" style="margin-right: 7px;">
|
35
|
+
<img src="/img/loading_circle.gif" style="vertical-align: middle; padding-right: 7px;"/><strong>Check</strong>
|
36
|
+
</div>
|
37
|
+
<div id="resolve_event" class="action_btn" style="margin-right: 7px;">
|
38
|
+
<img src="/img/cross.png" style="vertical-align: middle; padding-right: 7px;"/><strong>Resolve</strong>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
<div style="clear: both;"></div>
|
42
|
+
</div>
|
43
|
+
</div>
|
44
|
+
<h1 class="section_title">Event Data</h1>
|
45
|
+
<div id="event_data"></div>
|
46
|
+
<h1 class="section_title">Client Data</h1>
|
47
|
+
<div id="client_data"></div>
|
48
|
+
</div>
|
@@ -0,0 +1,124 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
|
3
|
+
<!--[if lt IE 7 ]> <html class="ie ie6 no-js" lang="en"> <![endif]-->
|
4
|
+
<!--[if IE 7 ]> <html class="ie ie7 no-js" lang="en"> <![endif]-->
|
5
|
+
<!--[if IE 8 ]> <html class="ie ie8 no-js" lang="en"> <![endif]-->
|
6
|
+
<!--[if IE 9 ]> <html class="ie ie9 no-js" lang="en"> <![endif]-->
|
7
|
+
<!--[if gt IE 9]><!--><html class="no-js" lang="en"><!--<![endif]-->
|
8
|
+
<!-- the "no-js" class is for Modernizr. -->
|
9
|
+
|
10
|
+
<head id="www-sitename-com" data-template-set="html5-reset">
|
11
|
+
|
12
|
+
<meta charset="utf-8">
|
13
|
+
|
14
|
+
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame -->
|
15
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
16
|
+
|
17
|
+
<title>Sensu Dashboard</title>
|
18
|
+
|
19
|
+
<meta name="author" content="Justin Kolberg">
|
20
|
+
<meta name="Copyright" content="Copyright Sonian, Inc. 2011. MIT License.">
|
21
|
+
|
22
|
+
<!-- Mobile Viewport Fix
|
23
|
+
j.mp/mobileviewport & davidbcalhoun.com/2010/viewport-metatag
|
24
|
+
device-width : Occupy full width of the screen in its current orientation
|
25
|
+
initial-scale = 1.0 retains dimensions instead of zooming out if page height > device height
|
26
|
+
maximum-scale = 1.0 retains dimensions instead of zooming in if page width < device width
|
27
|
+
-->
|
28
|
+
<!-- Uncomment to use; use thoughtfully!
|
29
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
|
30
|
+
-->
|
31
|
+
|
32
|
+
<!--<link rel="shortcut icon" href="img/favicon.ico">-->
|
33
|
+
<!-- This is the traditional favicon.
|
34
|
+
- size: 16x16 or 32x32
|
35
|
+
- transparency is OK
|
36
|
+
- see wikipedia for info on browser support: http://mky.be/favicon/ -->
|
37
|
+
|
38
|
+
<!--<link rel="apple-touch-icon" href="img/apple-touch-icon.png">-->
|
39
|
+
<!-- The is the icon for iOS's Web Clip.
|
40
|
+
- size: 57x57 for older iPhones, 72x72 for iPads, 114x114 for iPhone4's retina display (IMHO, just go ahead and use the biggest one)
|
41
|
+
- To prevent iOS from applying its styles to the icon name it thusly: apple-touch-icon-precomposed.png
|
42
|
+
- Transparency is not recommended (iOS will put a black BG behind the icon) -->
|
43
|
+
|
44
|
+
<!-- CSS: screen, mobile & print are all in the same file -->
|
45
|
+
<link rel="stylesheet" href="css/style.css">
|
46
|
+
<link rel="stylesheet" href="css/sonian.css">
|
47
|
+
<link rel="stylesheet" href="css/autoSuggest.css">
|
48
|
+
|
49
|
+
<!-- all our JS is at the bottom of the page, except for Modernizr. -->
|
50
|
+
<script src="js/modernizr-1.7.min.js"></script>
|
51
|
+
|
52
|
+
</head>
|
53
|
+
|
54
|
+
<body>
|
55
|
+
|
56
|
+
<div class="wrapper"><!-- not needed? up to you: http://camendesign.com/code/developpeurs_sans_frontieres -->
|
57
|
+
|
58
|
+
<header>
|
59
|
+
|
60
|
+
<h1><a href="/">Sensu Dashboard</a></h1>
|
61
|
+
|
62
|
+
<nav>
|
63
|
+
|
64
|
+
<ol>
|
65
|
+
<li><a href="/clients">Clients</a></li>
|
66
|
+
<li><a href="/stashes">Stashes</a></li>
|
67
|
+
<li><a href="/">Current Events</a></li>
|
68
|
+
</ol>
|
69
|
+
|
70
|
+
</nav>
|
71
|
+
|
72
|
+
<div style="clear: both;"></div>
|
73
|
+
|
74
|
+
</header>
|
75
|
+
|
76
|
+
<section id="main_content">
|
77
|
+
|
78
|
+
<%= yield %>
|
79
|
+
|
80
|
+
</section>
|
81
|
+
|
82
|
+
<footer>
|
83
|
+
|
84
|
+
<p><small>©
|
85
|
+
Copyright <a href="http://www.sonian.com">Sonian, Inc.</a> 2011.
|
86
|
+
<a href="https://github.com/sonian/sensu-dashboard/blob/master/MIT-LICENSE.txt">License (MIT)</a>
|
87
|
+
</small></p>
|
88
|
+
|
89
|
+
</footer>
|
90
|
+
|
91
|
+
</div>
|
92
|
+
|
93
|
+
<!-- here comes the javascript -->
|
94
|
+
|
95
|
+
<!-- Grab Google CDN's jQuery. fall back to local if necessary -->
|
96
|
+
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
|
97
|
+
<script>window.jQuery || document.write("<script src='js/jquery-1.5.1.min.js'>\x3C/script>")</script>
|
98
|
+
|
99
|
+
<!-- Javascript SHA1 -->
|
100
|
+
<script src="js/webtoolkit.sha1.js"></script>
|
101
|
+
|
102
|
+
<!-- jQuery templates -->
|
103
|
+
<script src="js/jquery.tmpl.min.js"></script>
|
104
|
+
|
105
|
+
<!-- jQuery lean modal -->
|
106
|
+
<script src="js/jquery.leanModal.min.js"></script>
|
107
|
+
|
108
|
+
<!-- jQuery zclip (clipboard support) -->
|
109
|
+
<script type="text/javascript" src="js/jquery.zclip.min.js"></script>
|
110
|
+
|
111
|
+
<!-- this is where we put our custom functions -->
|
112
|
+
<script src="js/functions.js"></script>
|
113
|
+
|
114
|
+
<!-- jQuery sort elements -->
|
115
|
+
<script src="js/jquery.sortElements.js"></script>
|
116
|
+
|
117
|
+
<!-- jQuery auto suggest -->
|
118
|
+
<script src="js/jquery.autoSuggest.js"></script>
|
119
|
+
|
120
|
+
<!-- include other js -->
|
121
|
+
<%= @js %>
|
122
|
+
|
123
|
+
</body>
|
124
|
+
</html>
|