sensu-dashboard-sonian 0.9.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/.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>
|