riemann-dash 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/riemann/dash/controller/index.rb +46 -1
- data/lib/riemann/dash/public/dash.js +6 -3
- data/lib/riemann/dash/public/persistence.js +2 -2
- data/lib/riemann/dash/public/subs.js +117 -12
- data/lib/riemann/dash/public/toastr.css +174 -0
- data/lib/riemann/dash/public/toastr.js +207 -0
- data/lib/riemann/dash/public/util.js +31 -0
- data/lib/riemann/dash/public/views/gauge.js +4 -4
- data/lib/riemann/dash/public/views/grid.js +11 -11
- data/lib/riemann/dash/public/views/title.js +4 -2
- data/lib/riemann/dash/version.rb +1 -1
- data/lib/riemann/dash/views/css.scss +83 -57
- data/lib/riemann/dash/views/index.erubis +200 -6
- data/lib/riemann/dash.rb +7 -38
- metadata +35 -66
- data/lib/riemann/dash/controller/websockets.rb +0 -50
- data/lib/riemann/dash/helper/renderer.rb +0 -266
- data/lib/riemann/dash/views/websockets.erubis +0 -201
@@ -1,5 +1,50 @@
|
|
1
1
|
class Riemann::Dash
|
2
|
+
require 'multi_json'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'set'
|
5
|
+
|
6
|
+
WS_CONFIG_FILE = "config/config.json"
|
7
|
+
|
2
8
|
get '/' do
|
3
|
-
erb :index
|
9
|
+
erb :index, :layout => false
|
10
|
+
end
|
11
|
+
|
12
|
+
get '/config', :provides => 'json' do
|
13
|
+
if File.exists? WS_CONFIG_FILE
|
14
|
+
send_file WS_CONFIG_FILE, :type => :json
|
15
|
+
else
|
16
|
+
MultiJson.encode({})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
post '/config' do
|
21
|
+
# Read update
|
22
|
+
request.body.rewind
|
23
|
+
update = MultiJson.decode(request.body.read)
|
24
|
+
|
25
|
+
# Read old config
|
26
|
+
if File.exists? WS_CONFIG_FILE
|
27
|
+
old = MultiJson.decode File.read WS_CONFIG_FILE
|
28
|
+
else
|
29
|
+
old = {}
|
30
|
+
end
|
31
|
+
|
32
|
+
new = {}
|
33
|
+
|
34
|
+
# Server
|
35
|
+
new['server'] = update['server'] or old['server']
|
36
|
+
|
37
|
+
p update['workspaces']
|
38
|
+
new['workspaces'] = update['workspaces'] or old['workspaces']
|
39
|
+
|
40
|
+
# Save new config
|
41
|
+
FileUtils.mkdir_p 'config'
|
42
|
+
File.open(WS_CONFIG_FILE, 'w') do |f|
|
43
|
+
f.write(MultiJson.encode(new))
|
44
|
+
end
|
45
|
+
|
46
|
+
# Return current config
|
47
|
+
content_type "application/json"
|
48
|
+
MultiJson.encode(new)
|
4
49
|
end
|
5
50
|
end
|
@@ -59,7 +59,7 @@ dash = (function() {
|
|
59
59
|
var stash = function() {
|
60
60
|
var currentIndex = currentWorkspaceIndex();
|
61
61
|
if (currentIndex != null) {
|
62
|
-
console.log(util.merge(currentWorkspace(), {view: currentView.json()}));
|
62
|
+
//console.log(util.merge(currentWorkspace(), {view: currentView.json()}));
|
63
63
|
workspaces[currentIndex] =
|
64
64
|
util.merge(currentWorkspace(), {view: currentView.json()});
|
65
65
|
}
|
@@ -149,8 +149,11 @@ dash = (function() {
|
|
149
149
|
server: toolbar.server(),
|
150
150
|
workspaces: workspaces
|
151
151
|
},
|
152
|
-
function() {
|
153
|
-
function(xhr,
|
152
|
+
function() { toastr.info("Configuration saved.") },
|
153
|
+
function(xhr, msg) {
|
154
|
+
console.log("Error saving config", msg);
|
155
|
+
toastr.error("Error saving config: " + msg);
|
156
|
+
}
|
154
157
|
);
|
155
158
|
}
|
156
159
|
|
@@ -3,7 +3,7 @@ var persistence = (function() {
|
|
3
3
|
// Saves configuration to persistent store. Calls success() or error() when
|
4
4
|
// complete.
|
5
5
|
var save = function(config, success, error) {
|
6
|
-
jQuery.ajax('/
|
6
|
+
jQuery.ajax('/config', {
|
7
7
|
type: 'POST',
|
8
8
|
success: success,
|
9
9
|
error: error,
|
@@ -15,7 +15,7 @@ var persistence = (function() {
|
|
15
15
|
|
16
16
|
// Returns configuration from persistent store.
|
17
17
|
var load = function(success, error) {
|
18
|
-
jQuery.ajax('/
|
18
|
+
jQuery.ajax('/config', {
|
19
19
|
type: 'GET',
|
20
20
|
success: success,
|
21
21
|
error: error,
|
@@ -1,23 +1,74 @@
|
|
1
1
|
var subs = (function() {
|
2
|
-
|
2
|
+
// What server shall we connect to by default?
|
3
|
+
var server;
|
4
|
+
|
5
|
+
// Subscription ID counter.
|
6
|
+
var id_counter = -1;
|
7
|
+
|
8
|
+
// Subscriptions
|
9
|
+
var subs = {};
|
10
|
+
|
11
|
+
// Switch to turn on/off event processing
|
3
12
|
var active = true;
|
13
|
+
|
14
|
+
// Error queue for notification
|
15
|
+
var errorQueue = [];
|
4
16
|
|
17
|
+
// Instrumentation
|
5
18
|
var load1 = profile.load(1000);
|
6
19
|
var load5 = profile.load(5000);
|
7
20
|
|
8
|
-
//
|
9
|
-
var
|
10
|
-
|
11
|
-
|
12
|
-
var ws = new WebSocket(uri);
|
13
|
-
var $ws = $(ws);
|
21
|
+
// Get a new subscription ID.
|
22
|
+
var newId = function() {
|
23
|
+
return id_counter += 1;
|
24
|
+
}
|
14
25
|
|
26
|
+
// Close a subscription's websocket channel.
|
27
|
+
var close = function(sub) {
|
28
|
+
if (sub.ws == null) {
|
29
|
+
return sub;
|
30
|
+
}
|
31
|
+
sub.ws.close();
|
32
|
+
sub.ws == null;
|
33
|
+
return sub;
|
34
|
+
}
|
35
|
+
|
36
|
+
// Closes a subscription and deletes it from the subscription manager.
|
37
|
+
var unsubscribe = function(sub) {
|
38
|
+
delete subs[sub.id];
|
39
|
+
close(sub);
|
40
|
+
}
|
41
|
+
|
42
|
+
// Unsubscribe from all subscriptions.
|
43
|
+
var unsubscribeAll = function() {
|
44
|
+
_.each(subs, unsubscribe);
|
45
|
+
}
|
46
|
+
|
47
|
+
// Open a subscription's websocket channel.
|
48
|
+
var open = function(sub) {
|
49
|
+
if (sub.ws != null && sub.ws.readyState != WebSocket.CLOSED) {
|
50
|
+
return sub;
|
51
|
+
}
|
52
|
+
|
53
|
+
var f = sub.f;
|
54
|
+
var queryString = "query=" + encodeURI(sub.query);
|
55
|
+
var uri = "ws://" + server + "/index?subscribe=true&" + queryString;
|
56
|
+
sub.ws = new WebSocket(uri);
|
57
|
+
var $ws = $(sub.ws);
|
58
|
+
|
15
59
|
$ws.bind('open', function() {
|
16
|
-
console.log("
|
60
|
+
console.log("Socket opened", sub.query);
|
61
|
+
});
|
62
|
+
|
63
|
+
$ws.bind('close', function(e) {
|
64
|
+
console.log("Socket closed", sub.query);
|
65
|
+
sub.ws = null;
|
17
66
|
});
|
18
67
|
|
19
|
-
$ws.bind('
|
20
|
-
console.log("
|
68
|
+
$ws.bind('error', function(e) {
|
69
|
+
console.log("Socket error", sub.query);
|
70
|
+
errorQueue.push(e);
|
71
|
+
ws.close();
|
21
72
|
});
|
22
73
|
|
23
74
|
$ws.bind('message', function(e) {
|
@@ -29,14 +80,68 @@ var subs = (function() {
|
|
29
80
|
load5(t1, Date.now());
|
30
81
|
});
|
31
82
|
|
32
|
-
|
33
|
-
return ws;
|
83
|
+
return sub;
|
34
84
|
}
|
35
85
|
|
86
|
+
// Add a subscription. Returns a subscription object. Subscriptions are
|
87
|
+
// opened immediately.
|
88
|
+
var subscribe = function(query, f) {
|
89
|
+
var sub = {
|
90
|
+
id: newId(),
|
91
|
+
query: query,
|
92
|
+
f: f,
|
93
|
+
ws: null
|
94
|
+
}
|
95
|
+
subs[sub.id] = sub;
|
96
|
+
open(sub);
|
97
|
+
return sub;
|
98
|
+
}
|
99
|
+
|
100
|
+
// Reconnect all inactive subs.
|
101
|
+
var converge = function() {
|
102
|
+
var closed = _.filter(subs, function(sub) {
|
103
|
+
return (sub.ws == null || sub.ws.readyState == WebSocket.CLOSED);
|
104
|
+
});
|
105
|
+
if (_.isEmpty(closed)) {
|
106
|
+
// Done here.
|
107
|
+
return;
|
108
|
+
}
|
109
|
+
|
110
|
+
// Display reconnection notice
|
111
|
+
toastr.warning(_.size(closed) + " lost connections");
|
112
|
+
|
113
|
+
// Reopen
|
114
|
+
_.each(closed, function(sub) {
|
115
|
+
open(sub);
|
116
|
+
});
|
117
|
+
}
|
118
|
+
|
119
|
+
var notifyErrors = function() {
|
120
|
+
if (errorQueue.length == 0) {
|
121
|
+
return;
|
122
|
+
}
|
123
|
+
_.warning(errorQueue.length + " socket errors");
|
124
|
+
errorQueue.length = 0;
|
125
|
+
converge();
|
126
|
+
}
|
127
|
+
|
128
|
+
// Periodically notify of errors.
|
129
|
+
window.setInterval(notifyErrors, 100);
|
130
|
+
|
131
|
+
// Periodically converge.
|
132
|
+
setInterval(converge, 6000);
|
133
|
+
|
134
|
+
// When terminating, close all connections.
|
135
|
+
$(window).unload(unsubscribeAll);
|
136
|
+
|
36
137
|
return {
|
37
138
|
subscribe: subscribe,
|
139
|
+
unsubscribe: unsubscribe,
|
140
|
+
unsubscribeAll: unsubscribeAll,
|
141
|
+
converge: converge,
|
38
142
|
load1: load1,
|
39
143
|
load5: load5,
|
144
|
+
subs: function() { return subs; },
|
40
145
|
enable: function() { active = true; console.log("Subs enabled."); },
|
41
146
|
disable: function() { active = false; console.log("Subs disabled."); },
|
42
147
|
toggle: function() {
|
@@ -0,0 +1,174 @@
|
|
1
|
+
.toast-title
|
2
|
+
{
|
3
|
+
font-weight: bold;
|
4
|
+
}
|
5
|
+
|
6
|
+
.toast-message
|
7
|
+
{
|
8
|
+
-ms-word-wrap: break-word;
|
9
|
+
word-wrap: break-word;
|
10
|
+
}
|
11
|
+
|
12
|
+
.toast-message a,
|
13
|
+
.toast-message label
|
14
|
+
{
|
15
|
+
color: #FFF;
|
16
|
+
}
|
17
|
+
|
18
|
+
.toast-message a:hover
|
19
|
+
{
|
20
|
+
color: #CCC;
|
21
|
+
text-decoration: none;
|
22
|
+
}
|
23
|
+
|
24
|
+
.toast-top-left
|
25
|
+
{
|
26
|
+
left: 12px;
|
27
|
+
top: 12px;
|
28
|
+
}
|
29
|
+
|
30
|
+
.toast-bottom-right
|
31
|
+
{
|
32
|
+
bottom: 12px;
|
33
|
+
right: 12px;
|
34
|
+
}
|
35
|
+
|
36
|
+
.toast-bottom-left
|
37
|
+
{
|
38
|
+
bottom: 12px;
|
39
|
+
left: 12px;
|
40
|
+
}
|
41
|
+
|
42
|
+
#toast-container
|
43
|
+
{
|
44
|
+
position: fixed;
|
45
|
+
z-index: 9999;
|
46
|
+
}
|
47
|
+
|
48
|
+
#toast-container > div
|
49
|
+
{
|
50
|
+
background-position: 15px center;
|
51
|
+
background-repeat: no-repeat;
|
52
|
+
-moz-border-radius: 3px 3px 3px 3px;
|
53
|
+
-webkit-border-radius: 3px 3px 3px 3px;
|
54
|
+
border-radius: 3px 3px 3px 3px;
|
55
|
+
-moz-box-shadow: 0 0 12px #999999;
|
56
|
+
-webkit-box-shadow: 0 0 12px #999999;
|
57
|
+
box-shadow: 0 0 12px #999999;
|
58
|
+
color: #FFFFFF;
|
59
|
+
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
|
60
|
+
filter: alpha(opacity=80);
|
61
|
+
margin: 0 0 6px;
|
62
|
+
opacity: 0.8;
|
63
|
+
padding: 15px 15px 15px 50px;
|
64
|
+
width: 300px;
|
65
|
+
}
|
66
|
+
|
67
|
+
.toast
|
68
|
+
{
|
69
|
+
background-color: #030303;
|
70
|
+
}
|
71
|
+
|
72
|
+
.toast-success
|
73
|
+
{
|
74
|
+
background-color: #51A351;
|
75
|
+
}
|
76
|
+
|
77
|
+
.toast-error
|
78
|
+
{
|
79
|
+
background-color: #BD362F;
|
80
|
+
}
|
81
|
+
|
82
|
+
.toast-info
|
83
|
+
{
|
84
|
+
background-color: #2F96B4;
|
85
|
+
}
|
86
|
+
|
87
|
+
.toast-warning
|
88
|
+
{
|
89
|
+
background-color: #F89406;
|
90
|
+
}
|
91
|
+
|
92
|
+
.toast-top-right
|
93
|
+
{
|
94
|
+
right: 12px;
|
95
|
+
top: 12px;
|
96
|
+
}
|
97
|
+
|
98
|
+
#toast-container > :hover
|
99
|
+
{
|
100
|
+
-moz-box-shadow: 0 0 12px #000000;
|
101
|
+
-webkit-box-shadow: 0 0 12px #000000;
|
102
|
+
box-shadow: 0 0 12px #000000;
|
103
|
+
cursor: pointer;
|
104
|
+
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
|
105
|
+
filter: alpha(opacity=100);
|
106
|
+
opacity: 1;
|
107
|
+
}
|
108
|
+
|
109
|
+
#toast-container > .toast-info
|
110
|
+
{
|
111
|
+
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important;
|
112
|
+
}
|
113
|
+
|
114
|
+
#toast-container > .toast-error
|
115
|
+
{
|
116
|
+
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important;
|
117
|
+
}
|
118
|
+
|
119
|
+
#toast-container > .toast-success
|
120
|
+
{
|
121
|
+
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important;
|
122
|
+
}
|
123
|
+
|
124
|
+
#toast-container > .toast-warning
|
125
|
+
{
|
126
|
+
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important;
|
127
|
+
}
|
128
|
+
|
129
|
+
/*Responsive Design*/
|
130
|
+
|
131
|
+
@media all and (max-width: 240px)
|
132
|
+
{
|
133
|
+
#toast-container > div
|
134
|
+
{
|
135
|
+
padding: 8px 8px 8px 50px;
|
136
|
+
width: 108px;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
@media all and (min-width: 241px) and (max-width: 320px)
|
141
|
+
{
|
142
|
+
#toast-container > div
|
143
|
+
{
|
144
|
+
padding: 8px 8px 8px 50px;
|
145
|
+
width: 128px;
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
@media all and (min-width: 321px) and (max-width: 480px)
|
150
|
+
{
|
151
|
+
#toast-container > div
|
152
|
+
{
|
153
|
+
padding: 8px 8px 8px 50px;
|
154
|
+
width: 192px;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
@media all and (min-width: 481px) and (max-width: 768px)
|
159
|
+
{
|
160
|
+
#toast-container > div
|
161
|
+
{
|
162
|
+
padding: 15px 15px 15px 50px;
|
163
|
+
width: 300px;
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
@media all and (min-width: 769px)
|
168
|
+
{
|
169
|
+
#toast-container > div
|
170
|
+
{
|
171
|
+
padding: 15px 15px 15px 50px;
|
172
|
+
width: 300px;
|
173
|
+
}
|
174
|
+
}
|
@@ -0,0 +1,207 @@
|
|
1
|
+
// By: Hans Fjällemark and John Papa
|
2
|
+
// https://github.com/CodeSeven/toastr
|
3
|
+
//
|
4
|
+
// Modified to support css styling instead of inline styling
|
5
|
+
// Inspired by https://github.com/Srirangan/notifer.js/
|
6
|
+
|
7
|
+
; (function (define) {
|
8
|
+
define(['jquery'], function ($) {
|
9
|
+
var toastr = (function () {
|
10
|
+
var
|
11
|
+
defaults = {
|
12
|
+
tapToDismiss: true,
|
13
|
+
toastClass: 'toast',
|
14
|
+
containerId: 'toast-container',
|
15
|
+
debug: false,
|
16
|
+
fadeIn: 300,
|
17
|
+
fadeOut: 1000,
|
18
|
+
extendedTimeOut: 1000,
|
19
|
+
iconClasses: {
|
20
|
+
error: 'toast-error',
|
21
|
+
info: 'toast-info',
|
22
|
+
success: 'toast-success',
|
23
|
+
warning: 'toast-warning'
|
24
|
+
},
|
25
|
+
iconClass: 'toast-info',
|
26
|
+
positionClass: 'toast-top-right',
|
27
|
+
timeOut: 5000, // Set timeOut to 0 to make it sticky
|
28
|
+
titleClass: 'toast-title',
|
29
|
+
messageClass: 'toast-message'
|
30
|
+
},
|
31
|
+
|
32
|
+
error = function (message, title, optionsOverride) {
|
33
|
+
return notify({
|
34
|
+
iconClass: getOptions().iconClasses.error,
|
35
|
+
message: message,
|
36
|
+
optionsOverride: optionsOverride,
|
37
|
+
title: title
|
38
|
+
});
|
39
|
+
},
|
40
|
+
|
41
|
+
getContainer = function (options) {
|
42
|
+
var $container = $('#' + options.containerId);
|
43
|
+
if ($container.length) {
|
44
|
+
return $container;
|
45
|
+
}
|
46
|
+
$container = $('<div/>')
|
47
|
+
.attr('id', options.containerId)
|
48
|
+
.addClass(options.positionClass);
|
49
|
+
$container.appendTo($('body'));
|
50
|
+
return $container;
|
51
|
+
},
|
52
|
+
|
53
|
+
getOptions = function () {
|
54
|
+
return $.extend({}, defaults, toastr.options);
|
55
|
+
},
|
56
|
+
|
57
|
+
info = function (message, title, optionsOverride) {
|
58
|
+
return notify({
|
59
|
+
iconClass: getOptions().iconClasses.info,
|
60
|
+
message: message,
|
61
|
+
optionsOverride: optionsOverride,
|
62
|
+
title: title
|
63
|
+
});
|
64
|
+
},
|
65
|
+
|
66
|
+
notify = function (map) {
|
67
|
+
var
|
68
|
+
options = getOptions(),
|
69
|
+
iconClass = map.iconClass || options.iconClass;
|
70
|
+
|
71
|
+
if (typeof (map.optionsOverride) !== 'undefined') {
|
72
|
+
options = $.extend(options, map.optionsOverride);
|
73
|
+
iconClass = map.optionsOverride.iconClass || iconClass;
|
74
|
+
}
|
75
|
+
|
76
|
+
var
|
77
|
+
intervalId = null,
|
78
|
+
$container = getContainer(options),
|
79
|
+
$toastElement = $('<div/>'),
|
80
|
+
$titleElement = $('<div/>'),
|
81
|
+
$messageElement = $('<div/>'),
|
82
|
+
response = { options: options, map: map };
|
83
|
+
|
84
|
+
if (map.iconClass) {
|
85
|
+
$toastElement.addClass(options.toastClass).addClass(iconClass);
|
86
|
+
}
|
87
|
+
|
88
|
+
if (map.title) {
|
89
|
+
$titleElement.append(map.title).addClass(options.titleClass);
|
90
|
+
$toastElement.append($titleElement);
|
91
|
+
}
|
92
|
+
|
93
|
+
if (map.message) {
|
94
|
+
$messageElement.append(map.message).addClass(options.messageClass);
|
95
|
+
$toastElement.append($messageElement);
|
96
|
+
}
|
97
|
+
|
98
|
+
var fadeAway = function () {
|
99
|
+
if ($(':focus', $toastElement).length > 0) {
|
100
|
+
return;
|
101
|
+
}
|
102
|
+
var fade = function (callback) {
|
103
|
+
return $toastElement.fadeOut(options.fadeOut, callback);
|
104
|
+
};
|
105
|
+
var removeToast = function () {
|
106
|
+
if ($toastElement.is(':visible')) {
|
107
|
+
return;
|
108
|
+
}
|
109
|
+
$toastElement.remove();
|
110
|
+
if ($container.children().length === 0) {
|
111
|
+
$container.remove();
|
112
|
+
}
|
113
|
+
};
|
114
|
+
fade(removeToast);
|
115
|
+
};
|
116
|
+
var delayedFadeAway = function () {
|
117
|
+
if (options.timeOut > 0 || options.extendedTimeOut > 0) {
|
118
|
+
intervalId = setTimeout(fadeAway, options.extendedTimeOut);
|
119
|
+
}
|
120
|
+
};
|
121
|
+
var stickAround = function () {
|
122
|
+
clearTimeout(intervalId);
|
123
|
+
$toastElement.stop(true, true).fadeIn(options.fadeIn);
|
124
|
+
};
|
125
|
+
$toastElement.hide();
|
126
|
+
$container.prepend($toastElement);
|
127
|
+
$toastElement.fadeIn(options.fadeIn);
|
128
|
+
if (options.timeOut > 0) {
|
129
|
+
intervalId = setTimeout(fadeAway, options.timeOut);
|
130
|
+
}
|
131
|
+
|
132
|
+
$toastElement.hover(stickAround, delayedFadeAway);
|
133
|
+
if (!options.onclick && options.tapToDismiss) {
|
134
|
+
$toastElement.click(fadeAway);
|
135
|
+
}
|
136
|
+
|
137
|
+
if (options.onclick) {
|
138
|
+
$toastElement.click(function () {
|
139
|
+
options.onclick() && fadeAway();
|
140
|
+
});
|
141
|
+
}
|
142
|
+
|
143
|
+
if (options.debug && console) {
|
144
|
+
console.log(response);
|
145
|
+
}
|
146
|
+
return $toastElement;
|
147
|
+
},
|
148
|
+
|
149
|
+
success = function (message, title, optionsOverride) {
|
150
|
+
return notify({
|
151
|
+
iconClass: getOptions().iconClasses.success,
|
152
|
+
message: message,
|
153
|
+
optionsOverride: optionsOverride,
|
154
|
+
title: title
|
155
|
+
});
|
156
|
+
},
|
157
|
+
|
158
|
+
warning = function (message, title, optionsOverride) {
|
159
|
+
return notify({
|
160
|
+
iconClass: getOptions().iconClasses.warning,
|
161
|
+
message: message,
|
162
|
+
optionsOverride: optionsOverride,
|
163
|
+
title: title
|
164
|
+
});
|
165
|
+
},
|
166
|
+
|
167
|
+
clear = function ($toastElement) {
|
168
|
+
var options = getOptions();
|
169
|
+
var $container = $('#' + options.containerId);
|
170
|
+
if ($toastElement && $(':focus', $toastElement).length === 0) {
|
171
|
+
var removeToast = function () {
|
172
|
+
if ($toastElement.is(':visible')) {
|
173
|
+
return;
|
174
|
+
}
|
175
|
+
$toastElement.remove();
|
176
|
+
if ($container.children().length === 0) {
|
177
|
+
$container.remove();
|
178
|
+
}
|
179
|
+
};
|
180
|
+
$toastElement.fadeOut(options.fadeOut, removeToast);
|
181
|
+
return;
|
182
|
+
}
|
183
|
+
if ($container.length) {
|
184
|
+
$container.fadeOut(options.fadeOut, function () {
|
185
|
+
$container.remove();
|
186
|
+
});
|
187
|
+
}
|
188
|
+
};
|
189
|
+
return {
|
190
|
+
clear: clear,
|
191
|
+
error: error,
|
192
|
+
info: info,
|
193
|
+
options: {},
|
194
|
+
success: success,
|
195
|
+
version: '1.1.2',
|
196
|
+
warning: warning
|
197
|
+
};
|
198
|
+
})();
|
199
|
+
return toastr;
|
200
|
+
});
|
201
|
+
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
|
202
|
+
if (typeof module !== 'undefined' && module.exports) { //Node
|
203
|
+
module.exports = factory(require(deps[0]));
|
204
|
+
} else {
|
205
|
+
window['toastr'] = factory(window['jQuery']);
|
206
|
+
}
|
207
|
+
}));
|